dmx-mainhall-foo/README.md
Yan Minagawa fbb303a322 docs: add related-projects section to README
Links to c-base/dmxbackend (the backend this tool talks to), the
matelight ecosystem (jaseg/matelight upstream, c-base fork,
matelight-pixel frontend, the c-matelight gitea org with the freshest
code, and mlaudiospectrum for the audio-reactive prior art), other
c-base lighting (roboclub-lighting), and the artefact guide entry for
the Matelight hardware history.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-10 10:31:11 +02:00

13 KiB
Raw Blame History

lightcontrol

Rust tooling for the c-base mainhall lighting rig. One TUI for animated presets driving the whole hall via dmxbackend, plus two focused one-shot binaries for the wall panels and the SonicPulse LED bars.

Talks to:

  • dmxbackend at dmx.cbrp3.c-base.org:8000 (REST + WebSocket) for the 48 DMX-routed fixtures.
  • matelight at matelight.cbrp3.c-base.org:8081 (/monitor WS, subprotocol matemon) for live pixel sync of the hall lights to whatever is playing on the Mate-crate display.
  • ArtNet node at 10.0.0.146:6454 (default) for the Stairville SonicPulse LED bars that aren't on dmxbackend.

The local microphone, optionally, for beat-driven scenes.


Quick start

# prerequisites (Fedora):
sudo dnf install rustup alsa-lib-devel pkgconf-pkg-config
rustup-init -y && source "$HOME/.cargo/env"

# build everything
cargo build --release

# fire up the TUI against the live rig
./target/release/lightcontrol

On Debian/Ubuntu the equivalent of alsa-lib-devel is libasound2-dev. If you don't want microphone support and can't or won't install ALSA dev libs, see No-mic build below.


Build

The default build enables the mic cargo feature, which pulls in cpal and through it the system ALSA library. The TUI's beat-detector and the BeatPulse preset rely on it.

cargo build --release             # default: TUI + panels + bars + mic

No-mic build

cargo build --release --no-default-features

Identical behaviour except the BeatPulse preset shows a slow cyan "waiting for mic" heartbeat instead of reacting to audio. Useful on build hosts that don't have ALSA dev headers, or on machines with no audio input.

Quick checks

cargo test                        # unit tests for presets + detector
cargo clippy --all-targets -- -D warnings

Binaries

lightcontrol — main TUI

Animated presets driving every fixture in the mainhall through dmxbackend's /api/v1/websocket_state/ at 25 fps.

./target/release/lightcontrol                          # interactive TUI
./target/release/lightcontrol --preset rainbows        # launch straight in
./target/release/lightcontrol --check                  # dump fixture list
./target/release/lightcontrol --host dmx.example:8000  # different backend
./target/release/lightcontrol --matelight ws://.../monitor   # custom mate

Environment variables:

  • DMX_HOST — overrides --host
  • MATELIGHT_URL — overrides --matelight

The TUI shows a header (host, fixture count, FPS, matelight + mic status), a live beat detector panel (flash bar + BPM + envelope sparkline), and the preset list with the active preset highlighted.

Keys

Key Preset
1 Rainbows
2 Blue House
3 70th Disco
4 Jungle
5 Lasertec
6 Police
7 Mirror Ball (blue fade)
8 Morning Light (sunrise)
9 Orange/Green Mirror Ball
m Matelight Sync (live)
s Gabba Strobe (white, fast)
r Red Strobe (fast)
L Blue Strobe (fast) — capital L; b is blackout
p Pink Strobe (fast)
k Beat Pulse (mic-driven)
0 / b Blackout
/ + Enter Navigate list
q / Esc / Ctrl-C Quit

--preset CLI aliases

Lower-cased and matched verbatim — useful for shell scripting / OBS integration:

Preset Aliases
Rainbows rainbow, rainbows, 1
Blue House blue, bluehouse, blue-house, 2
70th Disco disco, disco70, 70th, 70th-disco, 3
Jungle jungle, 4
Lasertec lasertec, laser, 5
Police police, polizei, 6
Mirror Ball mirror, mirrorball, mirror-ball, discoball, kugel, 7
Morning Light morning, sunrise, dawn, sonnenaufgang, morgen, 8
Orange/Green Ball orangegreen, orange-green, orange, green, kürbis, 9
Matelight Sync matelight, mate, sync, m
Gabba Strobe gabba, strobe, strobo, stroboscope, s
Red Strobe red, rot, redstrobe, r
Blue Strobe blau, bluestrobe, blue-strobe, l
Pink Strobe pink, magenta, pinkstrobe, p
Beat Pulse beat, beatpulse, kick, mic, audio, k
Blackout off, blackout, 0

Beat detector panel

┌─ beat detector ────────────────┬─ envelope (last ~4 s) ─────────────────┐
│ BEAT  █████████████             │ ▂▃▆▇▆▃▁▂▇▆▃▁▂▇▆▃▁▂▃▆▇▆▃▁▂▇▆▃▁▂▇▆▃▁▂  │
│ level ████████████░░░░░░░░     │                                        │
│  128.4 BPM   beats=47  last 0.08s ago │                                 │
└────────────────────────────────┴────────────────────────────────────────┘

The flash bar fires on every detected beat in the current per-beat hue palette. The level bar is the live short-window envelope. The sparkline plots the last ~4 seconds of envelope at 20 Hz, scaled with a ×2.5 boost so quiet rooms still show shape.

Pre-show diagnostic: put on the playlist, look at the panel. Solid BPM + regular flashes → detector locked. No flashes → mic not picking up, check pavucontrol recording tab. Constant strobing → too much noise, raise MIN_DELTA in src/beat.rs (default 0.020, try 0.035).

panels — Showtec PAR 56 wall panels (one-shot)

Hits the LED Par 56 fixtures via dmxbackend's WebSocket, sends one frame, exits. Useful for setup checks or quick scene calls from a script.

./target/release/panels --color red                 # red wash
./target/release/panels --color "#1a3f8f" --dim 180 # custom hex + dimmer
./target/release/panels --color off                 # blackout
./target/release/panels --dry-run --color magenta   # print, don't send

Colors: red, green, blue, white, yellow, orange, magenta, cyan, off, or any #RRGGBB.

bars — Stairville SonicPulse LED Bar 10 (ArtNet direct)

The bars aren't routed through dmxbackend, so this one talks ArtNet UDP directly to the node at 10.0.0.146:6454 (4 bars × 39 channels = 156 channels in universe 2).

./target/release/bars --color magenta            # paint all 4 bars
./target/release/bars --color "#ff5500" --dim 200
./target/release/bars --poll                     # ArtPoll discovery
./target/release/bars --sweep 0-15               # walk universes 0-15 to find them
./target/release/bars --broadcast --color blue   # broadcast if unicast fails
./target/release/bars --dry-run --color red      # print the packet, don't send

If --color does nothing visible: try --poll first to confirm the node is on the LAN, then --sweep to find which universe the bars actually listen on. The factory default is 0; many nodes are set to different universes per harness.


Architecture

                            ┌──────────────────────────┐
                            │  c-base mainhall lights  │
                            └──────────────────────────┘
                                       ▲    ▲
                              DMX over │    │  ArtNet (UDP/6454)
                                       │    │  → 10.0.0.146 → 4 SonicPulse bars
                                       │    │
                  ┌────────────────────┴──┐ │
                  │  dmxbackend (aiohttp) │ │
                  │  dmx.cbrp3:8000       │ │
                  │  REST /api/v1/...     │ │
                  │  WS   /api/v1/        │ │
                  │       websocket_state │ │
                  └────────┬──────────────┘ │
                           │                │
                  ┌────────┴────────────────┴──┐
                  │   lightcontrol (this repo) │
                  │                            │
                  │   ┌─────────┐ ┌─────────┐  │     ws://matelight:8081
                  │   │ engine  │ │ matelight ─────────────/monitor (matemon)
                  │   │ (presets│ │  feeder │  │     binary RGB frames →
                  │   │  @25fps)│ │         │  │     drive hall via sample
                  │   └────┬────┘ └─────────┘  │
                  │        │                   │     local microphone (cpal)
                  │        │      ┌─────────┐  │ ←───────────────────────
                  │        ├──────┤  beat   │  │     energy-onset detector
                  │        │      │ detector│  │     → BeatPulse preset
                  │        │      └─────────┘  │
                  │        ▼                   │
                  │   binaries:                │
                  │   lightcontrol (TUI)       │
                  │   panels       (one-shot)  │
                  │   bars  (ArtNet, ad-hoc)   │
                  └────────────────────────────┘

Source layout:

  • src/lib.rs — shared types (Fixture/Element/Channel), HTTP client, re-exports.
  • src/presets.rs — the 15 animated presets + render dispatch.
  • src/matelight.rs — matelight /monitor WebSocket feeder + frame sampler.
  • src/beat.rs — cpal capture + energy-onset beat detector (feature mic).
  • src/main.rs — TUI binary, engine loop, key handling.
  • src/bin/panels.rs — wall panels one-shot.
  • src/bin/bars.rs — SonicPulse ArtNet driver.

Tuning notes

  • Mic input device. On laptops with both built-in mic and a desk feed, PulseAudio/PipeWire may pick the wrong one. Fix in pavucontrol → Recording tab while lightcontrol is running.
  • Beat sensitivity. src/beat.rs constants:
    • THRESHOLD (default 1.35) — ratio of short to long envelope. Higher = stricter.
    • MIN_DELTA (default 0.020) — absolute energy rise required. Suppresses warmup-window false triggers and quiet-room noise.
    • MIN_INTERVAL_MS (default 200) — caps detected BPM at 300.
  • Matelight unreachable. TUI header will show matelight: connecting… or the last error. lightcontrol reconnects every 3 s. The Matelight preset falls back to a slow dim-white pulse meanwhile.
  • Photosensitivity. Gabba/Red/Blue/Pink strobes are hard 12.5 Hz square-wave alternations at the engine's Nyquist rate. Don't fire them at a crowd that hasn't been warned.

c-base backend & infrastructure

  • c-base/dmxbackend — the aiohttp service this tool talks to. ArtNet/HTTP-WebSocket/MQTT bridge for the mainhall lights. Hosts the fixture API at dmx.cbrp3.c-base.org:8000 and the live state WebSocket at /api/v1/websocket_state/.
  • c-base/c-base-map — interactive map of c-base areas and interfaces. Useful context for where the fixtures actually sit in space.
  • code.c-base.org/t/dmx-mainhall-foo — this repo's home.

Matelight ecosystem

  • jaseg/matelight — the canonical project. WS2801-in-Mate-bottles, 40×16 display, CRAP protocol (UDP/1337). Foundation everything else builds on.
  • c-base/matelight — c-base fork of the above.
  • c-base/matelight-pixel — Python/FastAPI + React frontend served at matelight.cbrp3.c-base.org:8000.
  • code.c-base.org/c-matelight — the active production org on c-base's Gitea (fresher than the GitHub mirror). Contains matelight, matelight-original, matelight-pixel, c-matelight.
  • c-base/mlaudiospectrum — audio-spectrum analyzer that paints the Matelight from mic input. Conceptually adjacent to our BeatPulse preset; if you want to push audio reactivity into the Matelight itself (instead of the hall), this is the prior art.

Other c-base lighting

Documentation