Linux Daemon for ROLI Blocks Devices
✦ Topology · Keepalive · LED Control · Touch Events ✦
Features • Install • Usage • Architecture • Devices • Development • 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 — so 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 | 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 |
uv tool install blocksd
blocksd install # sets up systemd service + udev rulesgit 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 blocks:
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 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
├── 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
├── 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 |
See CONTRIBUTING.md for the full development guide.
uv sync # install all dependencies
uv run pytest # run tests (275 currently)
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 ✦