feat(devices): radar presence input + button-light output on the controller
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
This commit is contained in:
@@ -26,10 +26,12 @@ press → print → press again issued a second ticket immediately. That is not
|
||||
The guard lives on the entry relay's spec (`config.relays[]` — see [[entry-exit-points]]), because
|
||||
whether real one-car-one-ticket is *possible* depends on the hardware at that lane. Two modes:
|
||||
|
||||
### PRESENCE mode (preferred — when a vehicle loop is wired)
|
||||
`relays[].presenceInput` = the 1-based input terminal of an **induction loop / barrier presence
|
||||
signal** on the same [[dingtian-relay|controller]] (the Dingtian's inputs are decoupled from its
|
||||
relays, and loops are already in the [[bom]]). The rule makes one-car-one-ticket **physical**:
|
||||
### PRESENCE mode (preferred — when a vehicle-presence sensor is wired)
|
||||
`relays[].presenceInput` = the 1-based input terminal of a **vehicle-presence sensor** on the same
|
||||
[[dingtian-relay|controller]] (the Dingtian's inputs are decoupled from its relays). The sensor may
|
||||
be an **induction loop** OR a **[[hikvision-radar|radar]]** (`relays[].presenceKind: "loop"|"radar"`
|
||||
— a label; the gate behaviour is identical). A radar wired to idle opposite the button needs
|
||||
`presenceActiveLow: true` so its edge reads correctly. The rule makes one-car-one-ticket **physical**:
|
||||
|
||||
- A press prints **only while a car is present** on the loop.
|
||||
- After a ticket prints, the relay is **disarmed** — no second ticket — **until the loop CLEARS**
|
||||
|
||||
Reference in New Issue
Block a user