Skip to main content


🔌 blocksd

Linux Daemon for ROLI Blocks Devices
✦ Topology · Keepalive · LED Control · Touch Events ✦

CI PyPI Python License

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 ROLI Blocks host protocol: device discovery, topology management, API mode keepalive, LED control, touch events, and device configuration. Your Blocks stay alive and useful on Linux.

✦ Features

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

📦 Install

Quick Install

curl -fsSL https://github.com/hyperb1iss/blocksd/releases/latest/download/install.sh -o install-blocksd.sh
bash install-blocksd.sh

Installs or upgrades blocksd using uv and managed Python, installs udev rules with sudo, and enables and restarts a systemd user service. Run as your normal user. Use --version 0.5.0 to select a release or --no-udev, --no-service, and --no-enable to skip setup steps. See the installation guide for prerequisites and upgrade details.

From PyPI

uv tool install --python 3.13 blocksd
blocksd install    # sets up systemd service + udev rules

Arch Linux

Packaging recipes live in packaging/aur/. AUR publication is separate from a GitHub or PyPI release; check the package's availability before installing through an AUR helper.

From Source

git clone https://github.com/hyperb1iss/blocksd.git
cd blocksd
just install
just web-build
uv run --locked blocksd install

The 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.

⚡ Usage

The current daemon does not upload its LittleFoot LED renderer (firmware opcode compatibility remains unresolved). LED commands and API frames can update heap data, but an accepted write does not establish visible LED output. See the LittleFoot notes.

Running the Daemon

# Foreground with verbose logging
systemctl --user stop blocksd   # if the service is installed
blocksd run -v

# As a systemd service (after install)
systemctl --user start blocksd
systemctl --user status blocksd
journalctl --user -u blocksd -f

When 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%

Device Status

# Quick scan, shows detected MIDI ports
blocksd status

# Full probe, connects to devices, shows type/serial/battery/version
systemctl --user stop blocksd   # also stop any foreground daemon
blocksd status --probe
systemctl --user start blocksd

LED Control

The LED and config commands open their own MIDI sessions. Stop the service and any foreground daemon before using them. LED commands remain running until Ctrl+C; config commands probe for about eight seconds. Restart the service afterward.

Control the 15×15 LED grid on Lightpad Block and Lightpad Block M:

blocksd led solid '#ff00ff'                          # solid color
blocksd led rainbow                                   # static rainbow
blocksd led gradient ff0000 0000ff                    # horizontal gradient
blocksd led gradient ff0000 0000ff --vertical         # vertical gradient
blocksd led checkerboard ff0000 00ff00                # 1x1 checkerboard
blocksd led checkerboard ff0000 00ff00 --size 3       # 3×3 checkerboard
blocksd led off                                       # lights off

Device Configuration

Read 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 sensitivity

Web Dashboard

If blocksd is already running, open http://localhost:9010 directly. Use blocksd ui only when no daemon is running; the command starts its own daemon.

blocksd ui                             # start a daemon and open its dashboard
blocksd ui --port 8080                 # custom port

Opens a real-time dashboard showing connected devices, topology, battery status, and LED state. Uses WebSocket for live updates.

Service Management

blocksd install                        # install systemd service + udev rules
blocksd install --no-udev              # skip udev rules
blocksd install --no-enable            # write/reload without starting or restarting
blocksd uninstall                      # remove service and udev rules

🔌 External API

blocksd 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 discover first to get the device uid
  • Only stream frames to devices advertising nonzero grid_width and grid_height in discovery
  • Use the fixed-size binary frame protocol for animation and streaming
  • Treat frame_ack.accepted=false or binary ack 0x00 as a rejected write: this usually means the device is not ready yet, the uid is 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.

🏗️ Architecture

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 (100-byte repaint)
├── topology/
│   ├── detector.py           MIDI port scanning
│   ├── device_group.py       connection lifecycle (the big one)
│   └── manager.py            orchestrates DeviceGroups
├── api/
│   ├── commands.py           shared command validation and dispatch
│   ├── 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

Protocol Pipeline

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 ────────  │

Supported Devices

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 Unknown LIC 🔲 Untested
Loop Block Unknown LOC 🔲 Untested
Developer Control Block Unknown DCB 🔲 Untested
Touch Block Unknown TCB 🔲 Untested
Seaboard RISE 25/49 0x0200 / 0x0210 N/A 🔲 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.

🧪 Development

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 check

🗺️ Roadmap

See 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 Assembler: bytecode generation and BitmapLEDProgram definition
  • LittleFoot Upload: firmware-compatible renderer for visible LED output
  • 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

⚖️ License

ISC


Star on GitHub    Ko-fi

If blocksd keeps your Blocks alive, give us a ⭐ or support the project

✦ Built with obsession by Hyperbliss Technologies ✦

Metadata

Release files for blocksd 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for blocksd 0.5.0
File Size Uploaded
blocksd-0.5.0.tar.gz 296.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for blocksd 0.5.0
File Interpreter ABI Platform
blocksd-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 453.6 kB

Release files / blocksd-0.5.0.tar.gz

Download URL blocksd-0.5.0.tar.gz
Size 296.4 kB
Tags Source
SHA-256 checksum
How to use checksums
9438185ca2c2be6e24bfe8f3450c92bbafa6224070bbb8b33ede49d872febc43
BLAKE2b-256 checksum
How to use checksums
e85c7aff30e7f1f72b1af3a666d52d3894973743f9eb90b4fd6719f31ad69ccc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 6, 2026.

Transparency log

Release files / blocksd-0.5.0-py3-none-any.whl

Download URL blocksd-0.5.0-py3-none-any.whl
Size 157.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
61b148adedd0a3d12f14ccc70c57088de5d4db9182a79100158abfe427b5431d
BLAKE2b-256 checksum
How to use checksums
e36184a2c93811bb42e27896d68f5220f6387a15c2cf0fd8ed51b8150a6a66bd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 6, 2026.

Transparency log

Release history Release notifications | RSS feed

0.6.0

2 release files

This release

0.5.0 This release

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page