Skip to content

hyperb1iss/blocksd

Repository files navigation


🔌 blocksd

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

CI PyPI Python License

FeaturesInstallUsageArchitectureDevicesDevelopmentVision


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.

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

From PyPI

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

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

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

🏗️ 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
├── 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

🧪 Development

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

About

Linux daemon for ROLI Blocks devices — topology, keepalive, LED control

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages