The Dingtian board's inputs are independent of its relays (configurable), so a button on an input can report to the host WITHOUT auto-firing a relay — solving the access-controller-button-flow blocker the UHPPOTE/ZKTeco couldn't. packages/devices: - access-dingtian.ts: `dingtian` access driver implementing AccessControlDevice (relay pulse/latch via UDP string protocol :60001), InputDevice (read inputs + poll-based press/release events, active-LOW), and the new PreconditionDevice. - PreconditionDevice capability on the interface: a device can report config it requires for parking and optionally fix it. Dingtian checks input_link_relay via the HTTP config API and can disable it. - httpPort config field — the web/config API port is separate from UDP control (this unit uses 8080, not the default 80). - Register dingtian; export driver objects from the package. Verified on real hardware (DT-R004 @ 10.0.10.172): status read, relay pulse, input events; disabled input_link_relay via the driver, then confirmed pressing inputs fires NO relay (0000) — host-in-the-loop entry works. Config-write gotcha recorded: config_set.cgi requires "command":"setconfig" injected after "status" (GET omits it) or the POST silently no-ops. apps/server/scripts/dingtian-test.mjs: status / watch / pulse hardware test. wiki: dingtian-relay verified; button-flow marked RESOLVED; index + log.
5.1 KiB
type, tags, sources, updated, status
| type | tags | sources | updated | status | |||||
|---|---|---|---|---|---|---|---|---|---|
| decision |
|
|
2026-06-15 | settled |
Push-Button → Auto-Open: the Ticket-First Entry Blocker (RESOLVED)
✅ RESOLVED (2026-06-15) by the dingtian-relay controller. Its inputs are decoupled from its relays (
input_link_relayconfigurable off — done & verified on hardware), so a button on an input reports to the host without firing a relay. Host-in-the-loop entry (button → host → ticket → host opens relay) now works. The original blocker (below) stands as the record of why the UHPPOTE/ZKTeco units couldn't do it.Original procurement-blocking finding (2026-06-15), from on-hardware testing: the UHPPOTE and ZKTeco controllers on hand could not, as wired/configured, deliver the required entry flow. See entry-exit-readers, trust-boundary.
The required flow
car arrives → driver presses button → TICKET PRINTS → then barrier opens
The ticket must print before the barrier opens, and entry must fail closed: if the ticket can't print (printer offline / out of paper), the barrier must stay shut — no untracked car enters (the anti-fraud core, see threat-model, append-only-event-chain).
The problem (verified on real hardware)
The push-button is wired into the controller's push-button / request-to-exit (REX) input. On that input the controller firmware auto-fires the relay immediately — the door opens on press. The host only observes the event after the relay has already actuated, so there is no point at which it can insert the ticket-print step. The host is structurally too late.
This is the entry-exit-readers principle in the negative: a button on the controller's own input is decided by the controller, not the host. For host-in-the-loop entry, the button must be a host-side input and the controller demoted to a commanded relay.
Verified facts (UHPPOTE 225088491, firmware 09120)
Tested live via the uhppoted lib (see apps/server/scripts/):
- Relays work, host-commanded:
openDoordoors 1 & 2 →{opened:true}, physically actuated, logged as events withreason="remote open door". - Buttons fire events — but only after auto-opening: press logs an event with
reason="push button ok"(door 1 button → door 1, door 2 button → door 2). - Both doors are in
control: "controlled"mode with a 3 s delay. - No UDP command exists to stop the push-button input from auto-opening the relay. The
uhppotedprotocol (and the UHPPOTE firmware, which is not changeable — uhppote-udp-protocol) has no "report-but-don't-open" mode for that input.
Per-device assessment
- UHPPOTE — push-button input is firmware-hardwired to auto-open; not configurable.
Cannot do ticket-first entry while the button is on that input. Fine as a commanded relay
(host
openDoor) and for permit/wiegand lanes; not suitable for the button-driven entry lane without rewiring the button to a host-side input. See uhppote-controller. - ZKTeco (C3 / inBio) — better positioned but unverified by us. Its auxiliary inputs
have programmable linkage (via ZKBioSecurity / the PULL SDK) and need not be tied to
"open door", and its SDK streams real-time events + an explicit open command — so
button → aux input → host event → print → host opensis achievable in principle. BUT: (a) wiring the button to the door's exit-switch input still auto-opens, same as UHPPOTE — it only works on a properly-configured aux input; (b) ZKTeco speaks its own PULL SDK protocol, not the UHPPOTE one — no verified MIT-licensed Node lib exists (mature open implementations are Python:zkaccess-c3-py,pyzkaccess), so it needs a new driver. See zkteco-controller.
Bottom line: neither controller currently on hand delivers ticket-first entry as wired. UHPPOTE can't at all on that input; ZKTeco might with an aux-input reconfig + a new driver, but that is unverified.
Options (unresolved — to settle later)
- Rewire the button off the controller's REX/exit input to a host-readable input (spare
GPIO, a USB/IP digital-input module, or a non-auto-open input) so the host sees the press,
prints, then commands
openDoor. Keeps UHPPOTE as a commanded relay. - ZKTeco aux-input path — wire the button to a programmable aux input, host decides via SDK.
Requires building a
[[zkteco-controller|zkteco]]driver (PULL SDK) and validating the no-auto-open linkage on real hardware. - Custom esp32-custom-controller controller for the entry lane — full control of button logic; the documented (currently deferred) prevention-grade path.
Status
Open / paused. Recorded so the constraint isn't rediscovered. The relay + event-log command path is otherwise proven on hardware (discovery, open, event capture all work) — the gap is specifically the button-before-ticket ordering on the entry lane. Revisit when the entry-lane hardware decision is taken. Related: open-questions (lane topology, failure modes).