Model the entry button (I1) and a Hikvision radar (I2) as named children of the access controller, and drive the button's 12V lamp on a spare relay. - Radar = the existing relays[].presenceInput one-car-one-ticket gate, now labelled presenceKind: loop|radar. A radar may idle opposite the button, so add a per-input active-level override: relays[].presenceActiveLow -> driver inputActiveLow set, inverting just that terminal (pure helper inputActive()). The Dingtian has one board-wide resting level otherwise. - AuxOutputDevice.setAux(channel,on) capability on the device interface (Dingtian latch) so business logic drives a NON-barrier lamp through the interface. Barriers still only pulseOpen — barrier-not-a-door preserved. - ButtonLightController: subscribes to the radar input edge + the camera lane status and drives a 3-state lamp — radar+car=solid, radar-only=blink (~1Hz), else off. Fails OFF on host loss/error; de-duped. A radar detection never opens a barrier on its own (advisory; threat model). - SetupWizard: presence kind + active-low + a button-light relay picker; sq+en i18n. Tests: button-light.test.ts (truth table + blink + fail-OFF + de-dupe), access-dingtian.test.ts (active-level inversion). Workspace build+lint+test green (158 server tests). Wiki: hikvision-radar, button-light-indicator + updates. Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
3.0 KiB
type, tags, sources, updated, status
| type | tags | sources | updated | status | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| concept |
|
2026-06-24 | settled |
Button-light indicator (radar × camera disagreement lamp)
The entry button has a 12 V light. It is driven by the host on a spare relay of the dingtian-relay controller as a 3-state indicator that combines the [[hikvision-radar| radar]] input with the camera "car in zone" signal:
| Radar input | Camera (lane entry busy) | Button light |
|---|---|---|
| detecting | free — no car confirmed | BLINK (~1 Hz) |
| detecting | busy — camera confirms a car | SOLID on |
| clear | — | OFF |
It is a disagreement indicator: the radar sees something but the camera hasn't confirmed a real vehicle → blink (attention / "pull forward"); both agree → solid; nothing there → off.
Signals
- Radar = the presence input edge on the entry relay (
relays[].presenceInput, the same edge the entry-double-press gate observes — so the lamp and the gate always agree on "a car is here"). - Camera "car in zone" = the existing lpr-camera (
LaneStatusEvententry busy/free, from camera vehicle detection). Already advisory; already drives the booth's barrier lights. No new camera plumbing.
Config
A controller-level config.buttonLight = { relay, blinkOnMs?, blinkOffMs? } (the operator picks a
spare relay — not a barrier relay; the setup UI warns if it overlaps one). Blink defaults to
500 ms / 500 ms.
Implementation
apps/server/src/button-light.ts — ButtonLightController subscribes to deviceEvents.onInput
(radar) + onLaneStatus (camera), computes the target state per controller, and drives the lamp via
a device-agnostic aux-output capability.
- Aux-output capability.
AuxOutputDevice { setAux(channel, on) }on the device interface (the Dingtian driver implements it as a latch). Business logic drives the lamp through this — never the driver's barrier methods. - Barrier-not-a-door is preserved. The lamp is not a barrier, so holding / blinking it on a
timer is fine — the barrier-not-a-door rule forbids timing a barrier closed, and barriers
still only ever
pulseOpen. The lamp uses the separatesetAuxlatch. - Fails OFF. On host loss, shutdown, or a
setAuxerror the lamp defaults OFF — a dead lamp is "no hint", never a misleading solid "go". SOLID is only ever held while busy + present is actively true (never latched on through a crash path). - De-duped. Only writes when the effective output changes, so the 50 ms input poll doesn't spam the controller over UDP.
Status
Built 2026-06-24 for the first booth (button I1, radar I2, lamp on a spare relay). Covered by
apps/server/src/button-light.test.ts (the truth table + blink toggling + fail-OFF + de-dupe).
Related: hikvision-radar, entry-double-press, lpr-camera, dingtian-relay,
barrier-not-a-door.