--- type: entity tags: [parking, hardware, access-control, rejected, historical] sources: [parking-system-architecture] updated: 2026-06-15 --- # UHPPOTE Controller (rejected — historical) > **❌ NOT USED. Replaced by the [[dingtian-relay]] controller** (and its driver/test code > removed). Kept as the record of *why* — its firmware-fixed push-button blocker > ([[access-controller-button-flow]]) is what drove the switch to a board with decoupled inputs. > The transferable lessons below (network isolation, append-only log ingestion, "a barrier is not > a door") still apply to any access device. The original starting hardware: a **UHPPOTE Wiegand 26/34 network controller (4-door)** — a cheap reader-plus-relay frontend. (See [[parking-system-architecture]] §6.) > **⚠️ The fatal limit (verified on hardware):** the push-button input **auto-opens the relay in > firmware** — no command makes it report-without-opening — so it **cannot** do ticket-first entry > (`button → print → open`). This is *the* reason it was dropped: full detail and the resolution in > [[access-controller-button-flow]]. > > **What was verified on the real unit** (serial 225088491, fw 09120) before retiring it: > host-commanded `openDoor` on doors 1 & 2 (physically actuated, `reason="remote open door"`); > button presses captured live (`reason="push button ok"`); UDP-broadcast [[device-discovery]]. > The driver, `uhppoted` dependency, and test scripts have since been removed from the codebase. > **Past implementation (removed):** was integrated via the official **`uhppoted`** npm package > (MIT — `github.com/uhppoted/uhppoted-lib-nodejs`) as the `uhppote` access driver. It exposed > exactly the protocol commands the design needs: `openDoor`, `getStatus`, and the event-log set > (`getEvent`, `getEventIndex`, `setEventIndex`, `recordSpecialEvents`) plus `setListener`/`listen` > for auto-push — see [[event-log-ingestion]]. Transport defaulted to **UDP** (broadcast `…:60000`), > with optional per-call TCP on newer firmware. The driver also implemented **[[device-discovery]]** > (`getDevices` broadcast) so the setup wizard can scan for controllers. Note: the lib pulls one > trivial extra dep (the npm `os` shim) and uses UDP broadcast, which needs socket broadcast > permission on the host. ## What it is - Combines reader input ([[wiegand]]) and door relays, with an onboard card list enabling **autonomous offline decisions** for Wiegand lanes. - Stores an **indexed event log** (see [[event-log-ingestion]]): `get-events` returns the stored range + current index; each record has event ID, timestamp, card number, door, access-granted flag, reason code. **At the record level it's effectively append-only** — no command edits/deletes an individual event. ## The catch It speaks the [[uhppote-udp-protocol]]: **UDP port 60000, no auth, no encryption**. Anyone on the LAN can open any door — and several unauthenticated commands can blind/reset/skew the log. So the device is **tamper-evident, not tamper-proof**, and only trustworthy behind [[network-isolation]] (mandatory). **Firmware cannot be customized** — the open-source `uhppoted` ecosystem is protocol reverse-engineering only; the controller accepts only the manufacturer's official firmware images. Make the log trustworthy via [[event-log-ingestion]] (host-side index tracking) landing into the [[append-only-event-chain]]. For prevention-grade authentication, see the [[esp32-custom-controller]]. The choice between them is the [[trust-boundary]] decision.