hyperb1iss/blocksd
Folders and files
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Β | Β | |||
Β | Β | |||
Β | Β | |||
Β | Β | |||
Β | Β | |||
Β | Β | |||
Β | Β | |||
Β | Β | |||
Β | Β | |||
Β | Β | |||
Β | Β | |||
Β | Β | |||
Β | Β | |||
Β | Β | |||
Β | Β | |||
Β | Β | |||
Β | Β | |||
Β | Β | |||
Β | Β | |||
Β | Β | |||
Repository files navigation
Linux Daemon for ROLI Blocks Devices
β¦ Topology Β· Keepalive Β· LED Control Β· Touch Events β¦
Features β’ Install β’ Usage β’ External API β’ Architecture β’ Devices β’ Development β’ Docs β’ Vision
ROLI Blocks devices need an active host-side handshake over MIDI SysEx to enter "API mode." Without it, they show a searching animation and eventually power off. There's no official Linux support.
blocksd implements the full ROLI Blocks protocol: device discovery, topology management, API mode keepalive, LED control, touch events, and device configuration. Your Blocks stay alive and useful on Linux.
| Capability | Description |
|---|---|
| π API Mode Keepalive | Periodic pings prevent the 5-second device timeout that kills API mode |
| ποΈ Topology Management | Auto-discovers devices over USB, tracks DNA-connected blocks through master |
| π Full State Machine | Serial β topology β API activation β ping loop, matching the C++ reference |
| π‘ LED Control | Lightpad / Lightpad M RGB565 bitmap grid, CLI patterns (solid, gradient, rainbow, checkerboard) |
| π Touch & Button Events | Normalized touch data (x/y/z/velocity) and button callbacks |
| βοΈ Device Config | Read/write device settings (sensitivity, MIDI channel, scale, etc.) |
| π DAW Friendly | ALSA multi-client, blocksd and your DAW share MIDI without conflict |
| π‘οΈ systemd Integration | Type=notify service, watchdog heartbeat, udev rules for plug-and-play |
curl -fsSL https://raw.githubusercontent.com/hyperb1iss/blocksd/main/install.sh | bashInstalls blocksd, udev rules, and a systemd user service in one shot.
uv tool install blocksd
blocksd install # sets up systemd service + udev rulesyay -S blocksd # stable release
yay -S blocksd-git # latest from maingit clone https://github.com/hyperb1iss/blocksd.git
cd blocksd
uv sync
uv run blocksd installThe install command sets up:
- udev rules: proper permissions for ROLI USB devices (requires sudo)
- systemd user service: auto-starts on login with watchdog monitoring
- Security hardening: sandboxed with
ProtectSystem=strict,NoNewPrivileges, etc.
# Foreground with verbose logging
blocksd run -v
# As a systemd service (after install)
systemctl --user start blocksd
systemctl --user status blocksd
journalctl --user -u blocksd -fWhen running, you'll see devices connect:
INFO blocksd ready, scanning for ROLI devices
INFO Master serial: LKBC9PZSOH978HOE
INFO Topology: 2 devices, 1 connections
INFO β¨ Device connected: lumi_keys_block (LKBC9PZSOH978HOE), battery 31%
INFO β¨ Device connected: lightpad_block_m (LPMJW6SWHSPD8H92), battery 31%
# Quick scan, shows detected MIDI ports
blocksd status
# Full probe, connects to devices, shows type/serial/battery/version
blocksd status --probeControl the 15Γ15 LED grid on Lightpad Block and Lightpad Block M:
blocksd led solid '#ff00ff' # solid color
blocksd led rainbow # animated rainbow
blocksd led gradient ff0000 0000ff # horizontal gradient
blocksd led gradient ff0000 0000ff --vertical # vertical gradient
blocksd led checkerboard ff0000 00ff00 # 2Γ2 checkerboard
blocksd led checkerboard ff0000 00ff00 --size 3 # 3Γ3 checkerboard
blocksd led off # lights offRead and write device settings like velocity sensitivity, MIDI channel, scale mode, and more:
blocksd config list # show all known config IDs
blocksd config get 10 # read velocity sensitivity
blocksd config set 10 50 # write velocity sensitivityblocksd ui # launch web UI on http://localhost:9010
blocksd ui --port 8080 # custom portOpens a real-time dashboard showing connected devices, topology, battery status, and LED state. Uses WebSocket for live updates.
blocksd install # install systemd service + udev rules
blocksd install --no-udev # skip udev rules
blocksd install --no-enable # install but don't auto-start
blocksd uninstall # remove everythingblocksd exposes two APIs for external integration:
Unix Socket: low-latency IPC for local clients (e.g. Hypercolor)
- Socket path:
$XDG_RUNTIME_DIR/blocksd/blocksd.sock - Fallback path:
/tmp/blocksd/blocksd.sock - One socket supports both control messages and high-rate LED frame writes
WebSocket: browser and network clients (used by blocksd ui)
- Default:
ws://localhost:9010/ws - Binary LED frame writes + JSON device events
The quick rules:
- Use
discoverfirst to get the deviceuid - Only stream frames to devices advertising nonzero
grid_widthandgrid_heightin discovery - Use the fixed-size binary frame protocol for animation and streaming
- Treat
frame_ack.accepted=falseor binary ack0x00as a rejected write: this usually means the device is not ready yet, theuidis gone, or the payload was malformed - Once a device is live, frame writes are coalesced daemon-side to the latest target state instead of surfacing host-visible βbusyβ backpressure
- Prefer a separate subscription socket if you also want events; outbound NDJSON events and 1-byte binary frame acks share the same connection
See the API reference for the full protocol reference, examples, and Hypercolor-oriented integration notes.
blocksd
βββ daemon.py asyncio main loop, sd_notify, signal handling
β βββ TopologyManager polls MIDI ports every 1.5s
β βββ DeviceGroup per-USB lifecycle + touch/button/config events
β βββ MidiConnection python-rtmidi wrapper (SysEx I/O)
βββ protocol/ pure protocol logic (no I/O, fully testable)
β βββ constants.py enums, headers, bit sizes
β βββ checksum.py SysEx checksum algorithm
β βββ packing.py 7-bit pack/unpack (LSB-first)
β βββ builder.py host β device packet construction
β βββ decoder.py device β host packet parsing
β βββ serial.py serial number request/parse
β βββ data_change.py SharedDataChange diff encoder
β βββ remote_heap.py ACK-tracked heap manager for live updates
βββ device/
β βββ models.py BlockType, DeviceInfo, TouchEvent, ButtonEvent
β βββ config_ids.py known configuration item IDs
β βββ registry.py serial prefix β device type mapping
β βββ connection.py rtmidi β asyncio bridge
βββ led/
β βββ bitmap.py RGB565 LED grid (15Γ15 Lightpad)
β βββ patterns.py solid, gradient, rainbow, checkerboard
βββ littlefoot/
β βββ opcodes.py LittleFoot VM opcode definitions
β βββ assembler.py bytecode assembler with label support
β βββ programs.py BitmapLEDProgram (94-byte repaint)
βββ topology/
β βββ detector.py MIDI port scanning
β βββ device_group.py connection lifecycle (the big one)
β βββ manager.py orchestrates DeviceGroups
βββ api/
β βββ server.py Unix socket + WebSocket servers
β βββ protocol.py NDJSON + binary frame wire protocol
β βββ events.py event broadcaster (device/touch/button/config)
β βββ websocket.py RFC 6455 frame codec
β βββ http.py HTTP parser + static file serving
βββ web/ web dashboard (Vite build output)
βββ config/
β βββ schema.py DaemonConfig (Pydantic)
β βββ loader.py TOML config file parsing
βββ sdnotify.py lightweight systemd notification (no deps)
βββ cli/
βββ app.py Typer commands (run, status --probe)
βββ led.py LED pattern commands (solid, rainbow, etc.)
βββ config.py device config get/set/list
βββ install.py systemd/udev setup
Host Device
β β
β ββ Serial Dump Request βββββββββββββββββββΊ β
β ββββββββββββββββββββ Serial Response ββββ β
β ββ Request Topology ββββββββββββββββββββββΊ β
β ββββββββββββββββββββββ Topology βββββββββ β
β ββ endAPIMode + beginAPIMode βββββββββββββΊ β
β βββββββββββββββββββββ Packet ACK ββββββββ β
β β
β ββ Ping (400ms master / 1666ms DNA) ββββββΊ β β keepalive loop
β βββββββββββββββββββββ Packet ACK ββββββββ β
β β
β ββ SharedDataChange (LED data) βββββββββββΊ β β heap writes
β βββββββββββββββββββββ Packet ACK ββββββββ β
| Device | USB PID | Serial Prefix | Status |
|---|---|---|---|
| Lightpad Block / M | 0x0900 |
LPB / LPM |
β Tested |
| LUMI Keys Block | 0x0E00 |
LKB |
β Tested |
| Seaboard Block | 0x0700 |
SBB |
π² Untested |
| Live Block | β | LIC |
π² Untested |
| Loop Block | β | LOC |
π² Untested |
| Developer Control Block | β | DCB |
π² Untested |
| Touch Block | β | TCB |
π² Untested |
| Seaboard RISE 25/49 | 0x0200 / 0x0210 |
β | π² Untested |
Bitmap LED streaming is currently exposed for Lightpad Block / Lightpad Block M only. Other devices are still discoverable and supported by the topology/API state machine, but they do not advertise a bitmap frame surface.
See CONTRIBUTING.md for the full development guide.
uv sync # install all dependencies
uv run pytest # run tests
uv run ruff check . # lint
uv run ruff format --check . # format check
uv run ty check # type checkSee VISION.md for the full vision, use cases, and ideas beyond music.
- Protocol Core: 7-bit packing, checksum, SysEx builder/decoder
- Device Discovery: MIDI port scanning, serial number parsing
- Topology Management: multi-device tracking, DNA connections
- API Mode Keepalive: full state machine with correct ping timing
- Remote Heap Manager: ACK tracking, retransmission, heap state sync
- LittleFoot Programs: bytecode assembler, BitmapLEDProgram upload
- CLI LED Commands:
blocksd led solid #ff00ff,blocksd led rainbow - Touch/Button Events: normalized callbacks with full velocity data
- Config Commands: read/write device settings via CLI
- sd_notify Integration: Type=notify service with watchdog heartbeat
- CI/CD: GitHub Actions, PyPI publishing, automated releases
- D-Bus Interface: IPC for external applications
- Hypercolor Integration: ROLI Blocks as an RGB device backend
If blocksd keeps your Blocks alive, give us a β or support the project
β¦ Built with obsession by Hyperbliss Technologies β¦