RouterBridge on MCU ignores NOTIFICATION (type 2) messages.
Must use REQUEST (type 0) for draw_frame, then drain the
response to prevent router buffer buildup.
Viz was sending REQUEST (type 0) but never reading responses.
Router response buffer filled up, blocking all subsequent RPCs.
NOTIFICATION (type 2) expects no response — no buffer buildup.
Without Bridge.run() in loop(), the MCU never reads incoming
draw_frame requests from the router. First frame goes through
during setup handshake, but subsequent frames fill the router's
send buffer and the viz stalls.
- just deploy: stash local board changes before git pull
- install.sh: configure git alias 'pull-clean' for manual use
- Board-side changes from test edits are discarded on deploy
- Permanent rename: led-matrix-bridge.ino → sketch.ino (Arduino CLI convention)
- Add just flash-sketch recipe for compiling/flashing MCU via board's arduino-cli
- Run via post-merge hooks for auto-deploy
Rewrite led-matrix-viz.py to eliminate latency:
- Render and pack frame immediately on each MIDI event
- Send on next poll cycle (no POLLOUT dependency, no frame loop)
- Notes on/off purely from MIDI data — zero decay
- Background 5 FPS refresh for router drop recovery
- Clean stats: FPS, active_notes, midi_events, bytes_received, raw_packets
- DECAY_FRAMES default 8→3 (100ms visual trail)
- MAX_NOTE_AGE safety cap: force-expire notes after 15 frames
- Track note age separately from decay to prevent stale notes
- Add FPS and active_notes to viz stats for diagnostics
- Fix router reconnect: unregister old fd, not new one
- .githooks/pre-push: validate Pd patches via python3 pd-validator
- .githooks/post-merge: auto-restart services when systemd/scripts change
- install.sh: configure core.hooksPath at install time
- justfile deploy: set hooksPath after git pull
- Create skills: rego-pd-validator, usb-gadget-configfs, led-matrix-msgpack-rpc
- Update pd-audio-synthesis skill with Uno Q specifics
- Add Pd version check (min 0.54.0) to start-synth.sh
- Add DO NOT EDIT headers to generated pd patches
- Add Gitea Actions CI workflow for patch validation
- Add ConditionPathExists guards to legacy systemd services
- Add 'just ci' recipe for CI
Root cause: synth-diagnostic uses systemctl start to start pipeline
services, but those services had After=synth-diagnostic — causing
deadlock (they waited for synth-diagnostic to exit, which was waiting
for them).
Fix: pipeline services no longer list synth-diagnostic in After=.
synth-diagnostic has Before= them for boot ordering, and starts them
directly via systemctl start in run-tests.sh.
Also fixed prometheus-exporter: had After=synth-diagnostic backwards
— should start before synth-diagnostic (synth-diagnostic has
After=prometheus-exporter).
- dashboard.html: standalone HTML, fetches :9090/metrics, auto-refresh
- Exporter serves dashboard at /dashboard and /dashboard.html
- Cards: Pipeline, Audio, Mixer, MIDI Bridge, LED Viz
- Live gauges, counters, service status dots, last-activity timestamps
midi-bridge: removed HTTP server on :9091, now writes /tmp/midi-stats.json
prometheus-exporter: reads /tmp/midi-stats.json, exposes all metrics on :9090/metrics
Single scrape endpoint for all pipeline components
Added notein→pack→noteout and ctlin→ctlout chains that forward all
incoming MIDI from the MPK Mini to the board's MIDI port. This means
physical keys/knobs now work alongside the GUI click buttons.
The O_NONBLOCK flag set by setblocking(False) was not cleared by
settimeout(n) on this CPython/kernel combo, causing recvfrom to never
return data. Switched to explicit select.poll() with frame-interval
based timeout — simpler, more portable, and avoids the O_NONBLOCK trap.
Also fixes midi-bridge: add time.sleep(0.01) in no-data paths to
prevent 100% CPU spin from spurious POLLIN on f_midi rawmidi.
midi-bridge.py:
- Auto-detect rawmidi device (gadget f_midi > env override > fallback)
- Reconnect on ENODEV (device hotplug)
- No longer needs MIDI_BRIDGE_DEV env var in common cases
start-synth.sh:
- Remove all -alsamidi/-midiadddev flags (kernel lacks CONFIG_SND_SEQUENCER)
- MIDI handled entirely by midi-bridge.service → UDP → netreceive
- Host mode: same approach, no ALSA sequencer needed
mpk-mini-sim.pd:
- New MPK Mini Mk II simulator (25 keys, 8 pads, 8 CC knobs)
- Proper Pd #X obj format for all objects (bng, hsl, t, del, netsend, loadbang)
- UDP output to board:8081, matching midi-bridge format
system: enable usb-gadget-audio.service at boot, load dwc3 module at boot