W1 lane B proof: inhibit masters, tempo clock, highlight
Branch w1-server-core, worktree ~/trc-lighting/wt-server-core, cut from two-screen 4dbe8af.
Mac dry run: dotnet bin/w1/LightDesk.dll --dry-run --ui-standalone --port 7081 --camera-from audit-2026-10-10/.camera-scratch.
Baseline for the ms check: git archive 4dbe8af built and run the same way on port 7089.
Never called: /api/dmx/nodes, POST /api/dmx/output. Both servers stopped after the run.
Build: dotnet build -c Release succeeded; the only warnings left are CA1416 in CamFrame.cs (not touched). The one
pre-existing warning in Program.cs (CS8632, string? Mode) was removed.
1. Inhibit: ANTHEM with KEY capped at 5
Leko 1 = universe 1 address 33, dimmer channel 40. Leko 2 = address 41, dimmer channel 48. ANTHEM (703) asks
Group 21 At 10 in data/scenes.json (not 15 as PLAN.md says).
| Camera-safe | KEY inhibit | Engine target | Frame leko 1 / leko 2 (of 255) |
|---|---|---|---|
| off | 100 (none) | 10 % | 25 / 25 |
| off | 5 | 10 % | 12 / 12 |
| on | 100 (none) | 25 % (the camera-safe floor) | 64 / 64 |
| on | 5 | 25 % | 12 / 12 |
| off | 5, then KEY fader to Full | 100 % | 12 / 12 |
Pass: at or below 13/255 in every case; the cap wins over the camera-safe floor and over a fader at Full.
/api/status.inhibits and /api/rig/state.inhibits both read KEY 21 max 5 fixtures 1-6, FOH 22 max 10 fixtures 201, 202.
SSE: inhibit arrived at once on a POST, and the next rig event carried inhibits with the new FOH value.
2. Tempo: a beats:1 hit at 120 BPM
Test hit (temporary, not committed): two steps on the truss pars, Group 3 At Full then Group 3 At 0, each beats: 1.
Sampled /api/dmx/frame on channel 112 (truss par 3101 dimmer); the 40 fps loop reached 31 ms per sample
(each request renders a frame), 256 samples over 8 s.
| Measure | n | Mean | Median | Min | Max |
|---|---|---|---|---|---|
| Step period, 120 BPM (target 500) | 14 | 501.1 ms | 499.1 | 478.4 | 527.0 |
| Two-step cycle, 120 BPM (target 1000) | 7 | 1002.2 ms | 999.0 | 987.4 | 1023.8 |
| Step period, 90 BPM (target 666.7) | 8 | 666.3 ms | 667.0 | 652.1 | 681.6 |
Pass: 500 ms ±10 on the mean. Single intervals spread about ±25 ms because the samples are 31 ms apart.
A first run before the final rebuild read 499.1 ms mean (n=15).
Tap: six taps 500 ms apart gave 120 BPM with taps: 4; one tap after a 2.2 s gap kept 120 and restarted the count at 1.
3. ms-only hits unchanged
HEARTBEAT (ms 220 / 220, no beats), the dimmer of 1101 sampled through /api/dmx/state, the same way on both builds:
| Build | Run 1 mean | Run 2 mean |
|---|---|---|
| this branch (7081) | 221.9 ms | 221.2 ms |
| baseline 4dbe8af (7089) | 222.0 ms | 221.4 ms |
Pass: same period within 1 ms. The final binary read 220.8 ms through /api/dmx/frame.
4. Highlight
Picked 1201 and 1202 (/api/ui/selection), ANTHEM live, POST /api/highlight {fixtures:[1201,1202], on:true}, 3 s of frames:
| Fixture | Channel | Min | Max | Distinct values |
|---|---|---|---|---|
| 1201 picked | 238 | 51 | 255 | 77 |
| 1202 picked | 282 | 51 | 255 | 77 |
| 1203 not picked | 304 | 230 | 230 | 1 |
| leko 1 not picked | 40 | 12 | 12 | 1 |
Breath period on 1201: 986 ms and 998 ms. 51/255 = 20 %.
Undo ring before and after highlight on, 1.5 s, off: identical (depth 10, same top entry and times).
Released by on:false (1201 back to 230), by a new pick ([1203]), and by /api/blackout; a re-post of the same pick keeps it.
Highlight on leko 1 with KEY capped at 5 reached 255 in this first run; superseded by the re-run below.
Errors answer 400: inhibit on group 99, tempo without bpm, highlight without fixtures.
5. Re-run: highlight now respects the inhibit cap (team lead ruling, Greg: "Don't use the key light almost at all")
Engine.cs Render: the cap now applies after the highlight; the highlight still overrides the grand master.
ANTHEM live, KEY 5, FOH 10, POST /api/highlight {fixtures:[1201,1202,1], on:true}, 3 s of frames, 98 samples:
| Fixture | Channel | Min | Max | Distinct values |
|---|---|---|---|---|
| 1201 highlighted | 238 | 51 | 255 | 70 |
| 1202 highlighted | 282 | 51 | 255 | 70 |
| 1203 not highlighted | 304 | 230 | 230 | 1 |
| leko 1 highlighted, KEY capped at 5 | 40 | 12 | 12 | 1 |
Breath period on 1201: 1007 ms and 1014 ms. Pass: leko 1 never exceeded 13/255 while highlighted.