Skip to main content

Linux daemon for ROLI Blocks devices โ€” keeps them alive, controls LEDs, manages topology

Project description


๐Ÿ”Œ 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 โ€ข 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.

โœฆ 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://raw.githubusercontent.com/hyperb1iss/blocksd/main/install.sh | bash

Installs blocksd, udev rules, and a systemd user service in one shot.

From PyPI

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

Arch Linux (AUR)

yay -S blocksd       # stable release
yay -S blocksd-git   # latest from main

From Source

git clone https://github.com/hyperb1iss/blocksd.git
cd blocksd
uv sync
uv run 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

Running the Daemon

# 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 -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
blocksd status --probe

LED Control

Control 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 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

blocksd ui                             # launch web UI on http://localhost:9010
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            # install but don't auto-start
blocksd uninstall                      # remove everything

๐Ÿ”Œ 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 docs/API.md 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 (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

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 โ€” 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.

๐Ÿงช 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 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

โš–๏ธ 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 โœฆ

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

blocksd-0.3.1.tar.gz (167.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

blocksd-0.3.1-py3-none-any.whl (71.9 kB view details)

Uploaded Python 3

File details

Details for the file blocksd-0.3.1.tar.gz.

File metadata

  • Download URL: blocksd-0.3.1.tar.gz
  • Upload date:
  • Size: 167.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for blocksd-0.3.1.tar.gz
Algorithm Hash digest
SHA256 dd40b1337ecad3759787aa448de7c5040820f3999b79e02c069d0e87fd9d0b22
MD5 3ae3fd0063279475f86e2acc92e716bf
BLAKE2b-256 f9e549a205403c4bf96c512c58e56b6b1bcdb34ce267ec4cdc0220d53a6b6584

See more details on using hashes here.

Provenance

The following attestation bundles were made for blocksd-0.3.1.tar.gz:

Publisher: publish.yml on hyperb1iss/blocksd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file blocksd-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: blocksd-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 71.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for blocksd-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 323e430f301f47e3059ab941f2d83454ca2d23351a7f3c44b416b2b9af3ed944
MD5 d79e2b5f51f90650a049db82f2f9e0f7
BLAKE2b-256 049be2d85e014adacb12195ddd8dec4701b1882d02f9cf0b5edb782e8d887371

See more details on using hashes here.

Provenance

The following attestation bundles were made for blocksd-0.3.1-py3-none-any.whl:

Publisher: publish.yml on hyperb1iss/blocksd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page