Skip to content

feat(blocks): add LUMI key lighting to the blocksd bridge - #263

Merged
hyperb1iss merged 2 commits into
mainfrom
nova/lumi-bridge
Sep 8, 2026
Merged

feat(blocks): add LUMI key lighting to the blocksd bridge#263
hyperb1iss merged 2 commits into
mainfrom
nova/lumi-bridge

Conversation

@hyperb1iss

@hyperb1iss hyperb1iss commented Sep 7, 2026

Copy link
Copy Markdown
Owner

What this changes

LUMI Keys now appears as a 24-color strip in Hypercolor's blocksd bridge. Lightpad and Lightpad M retain their 225-pixel matrices and binary transport. Discovery rejects unsupported models and inconsistent dimensions instead of publishing unusable surfaces.

Keyboard frames use blocksd's JSON key_frame API with exactly 72 RGB888 bytes. Replies must match the message type and full 64-bit device UID and carry a boolean acceptance result. A rejected frame remains retryable; malformed replies trigger the existing disconnect path. Older Lightpad discovery responses remain compatible when key_count is absent.

Why

The bridge previously treated every ROLI device as a grid and sent Lightpad binary frames. LUMI advertises zero grid dimensions, so Hypercolor exposed zero LEDs and had no keyboard transport. The Python daemon already owns MIDI and the device renderer; this change gives Hypercolor the corresponding discovery and output path.

LUMI requires the daemon capability introduced in blocksd #7. The hardware guide documents setup and the historical backend spec now distinguishes current support from earlier architecture sketches.

Verification

  • Added or updated tests
  • Added or updated docs (README, AGENTS.md, relevant spec, or guide)
  • just verify passes locally (Rust fmt + lint + test)
  • just deny passes (required for dependency or license changes)
  • just ui-test and just ui-build pass (required for crates/hypercolor-ui/)
  • just sdk-lint, just sdk-check, and just sdk-build pass (required for sdk/)
  • just python-verify passes (required for python/)
  • just compat-check passes (required for data/drivers/vendors/*.toml)
  • just docs-build passes (required for docs or README changes)
  • cd docs && zola check passes (required for docs link/content changes)
  • Packaging scripts were syntax-checked (required for scripts/ or packaging/)
  • just e2e-build passes with the normal Servo stack (required for daemon/UI/effect integration changes)
  • just e2e-build-cpu passes when validating the CPU smoke fallback
  • just e2e passes against the Servo stack (required for end-to-end behavior changes; starts daemon/browser)
  • Tested on real hardware, simulator, or e2e harness (describe below)

The six bridge integration tests pass, covering mixed JSON/binary writes, full-width UIDs, invalid geometry, rejected frames, malformed acknowledgements, and reconnects. Independent review also executed the native Rainbow example against an isolated Unix daemon and verified changing 24-key and 225-pixel frames.

Local validation passes workspace just check, Clippy, formatting, 6,479 workspace tests (27 ignored), allocation contracts, documentation build, and documentation link checks. The aggregate just verify encountered an intermittent unchanged build-wrapper fixture failure; its isolated diagnostic rerun passed, and the remaining component gates were run separately. Workspace checks reused the existing frontend distribution from identical UI source because the fresh worktree lacked generated frontend assets.

Linux and Windows checks, UI, and both normal Servo and CPU smoke e2e paths pass in CI. Apple Silicon checks also pass. Intel macOS exceeded its two-hour job limit during deployment-fixture compilation after workspace checks, Clippy, interop/capture/input/ownership fixtures, and status API fixtures passed; the remaining deployment checks did not run. Unchecked local recipe boxes for those e2e paths are covered by the CI equivalents; gates for unchanged surfaces are not applicable.

The live native example accepted 376 frames per device over 15 seconds. Lightpad acknowledged 113 complete repaints, about 7.53 repaints/sec between its first and last acknowledgement. Hardware testing exposed daemon-side snapshot starvation, single-buffer tearing, and a 200 ms receive-loop delay; their fixes are included in blocksd #7. The hardware owner confirmed whole-pad animation after the snapshot fix. The hardware owner subsequently confirmed the full compositor animation looks correct.

Notes for reviewers

The LUMI strip follows key index, without modeling black and white key heights. API acceptance confirms queuing; device presentation acknowledgements establish logical repaint completion, not physical LED scan timing or musical MIDI/MPE behavior.

A second hardware run exercised the real CPU SparkleFlinger compositor through the public daemon library in an isolated ROLI-only harness. A custom scene zone retained both surfaces and mapped them onto one canvas. Device output delivered about 25 frames/sec to blocksd without errors; the Lightpad returned 114 complete repaint acknowledgements in 15 seconds (7.59 logical repaints/sec). The existing live daemon and its case scene were unchanged. The hardware owner confirmed the full compositor animation looks correct. GPU composition and HTML effects were not exercised on the ROLI outputs.

LUMI advertises key colors rather than a Lightpad grid. Select the
lighting surface from advertised capabilities and send exact key frames
with validated acknowledgements while preserving legacy grid transport.

Cover mixed transports, malformed replies, retry and reconnect behavior.
Include a native rainbow example for isolated bridge acceptance checks.
Describe the daemon capability required for LUMI and the existing
Lightpad binary path. Replace false shared-grid claims and distinguish
historical design sketches from the supported implementation contract.

Document the native effect probe and keep physical compositor and
musical input acceptance separate from queued frame acknowledgements.
@coderabbitai

coderabbitai Bot commented Sep 7, 2026

Copy link
Copy Markdown

Warning

Review limit reached

  • Run on-demand review

On-demand reviews are free for the next 13 days. After that, they cost $0.25 per reviewed file.

Or wait 12 minutes for your next included review.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: cce4f284-bfef-42f2-88fb-54bb3ec44ec1

📥 Commits

Reviewing files that changed from the base of the PR and between 42eab63 and 6dd96c8.

📒 Files selected for processing (12)
  • ROADMAP.md
  • crates/hypercolor-core/examples/blocks_rainbow.rs
  • crates/hypercolor-core/src/device/blocks/backend.rs
  • crates/hypercolor-core/src/device/blocks/connection.rs
  • crates/hypercolor-core/src/device/blocks/mod.rs
  • crates/hypercolor-core/src/device/blocks/scanner.rs
  • crates/hypercolor-core/src/device/blocks/types.rs
  • crates/hypercolor-core/tests/blocks_backend_tests.rs
  • docs/content/guide/scope.md
  • docs/content/hardware/_index.md
  • docs/content/hardware/roli-blocks.md
  • docs/specs/30-roli-blocks-backend.md

Comment @coderabbitai help to get the list of available commands.

@hyperb1iss
hyperb1iss marked this pull request as ready for review September 7, 2026 21:07
@hyperb1iss
hyperb1iss merged commit ed50c81 into main Sep 8, 2026
33 of 34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant