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.0.tar.gz (167.5 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.0-py3-none-any.whl (71.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: blocksd-0.3.0.tar.gz
  • Upload date:
  • Size: 167.5 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.0.tar.gz
Algorithm Hash digest
SHA256 18acf1be111a8db9530a5adee7ad222108f21414a252fa7f34901bb3d4c5237b
MD5 b4f5bab5d51a148cd6cb28edf770b7a2
BLAKE2b-256 fec5c918a1dd2e80dbedd146618085d351bf20b03a317cf96a4ed3ae816c01c0

See more details on using hashes here.

Provenance

The following attestation bundles were made for blocksd-0.3.0.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.0-py3-none-any.whl.

File metadata

  • Download URL: blocksd-0.3.0-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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 93b2980045f7da2a4ba4c08347225dda9ac450fb5b6d43b2a20e9b54289ff8ed
MD5 0bdc0e4d336084a432d979ff8ead852c
BLAKE2b-256 804694bd0c84612fba5afd293b22d8354f5f801a270d04f2420a9e459cb755f8

See more details on using hashes here.

Provenance

The following attestation bundles were made for blocksd-0.3.0-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