diff --git a/wiki/concepts/site-device-installation.md b/wiki/concepts/site-device-installation.md new file mode 100644 index 0000000..8df8829 --- /dev/null +++ b/wiki/concepts/site-device-installation.md @@ -0,0 +1,209 @@ +--- +type: reference +tags: [parking, runbook, installation, devices, network, field] +sources: [] +updated: 2026-09-09 +--- + +# Site device installation — know it BEFORE you are standing in the booth + +A field runbook: for every device we deploy, its **factory address and credentials**, the **tool** +you need, **what the app configures by itself** at assign time versus **what must be done by hand on +the device**, and the **traps already paid for** on park-buzi and the lab. The [[appliance-provisioning]] +runbook covers the booth PC (OS, disk, Docker, Periphery); this page covers everything plugged into +it. Written 2026-09-09 after an evening lost to a printer whose factory address nobody had written +down ([[k200l-printer]]). + +Rule of thumb that explains most of this page: **every field device ships on its own private +subnet with DHCP off, and none of them announce themselves.** You bring a laptop that can take a +second static address, you put it on the device's factory subnet, you move the device to the site +plan, and only then does anything else see it. + +## Before leaving the office + +**Bring** + +- A laptop with an Ethernet port and the right to add a **second static IPv4 address** to it + (Windows: adapter → IPv4 → Advanced → add). Under WSL, remember the source-address bug + ([[wsl-dev-networking]]): after adding a temporary address, `ping` may work while HTTP times out. +- The Dingtian reader tool **`QRCode_v1_6_5.exe`** (Windows) — the only way to set a DT-008's IP, + server target, prefixes and symbologies. A browser is enough for everything else. +- Patch cables, a USB A–B cable (printers), the site's **address plan** (below) filled in, the + app **admin** password, and a fresh Komodo **onboarding key** if the booth PC is new + ([[appliance-provisioning]] §7a). +- The **serials** if already known: DT-008 `cjihao` (on the reader's label / in the tool), camera + MAC/serial, printer model (label on the bottom — the K200L's own web UI calls it "POS-80"). + +**Address plan** — the device VLAN ([[network-isolation]]) is `10.0.10.0/24` on both sites so far, +**every device static, DHCP off everywhere**. The convention from park-buzi / park-lab: + +| Address | Device | Factory address it came from | +| --- | --- | --- | +| 10.0.10.1 | VLAN gateway (switch/router) | — | +| 10.0.10.5 | [[dingtian-relay]] board (barriers + inputs) | `192.168.1.100` | +| 10.0.10.7 / .8 | [[dingtian-dt008-reader]] entry / exit (**unique IP each**) | `192.168.1.99` | +| 10.0.10.9 | entry-dispenser printer (park-buzi: Cashino KP-300H) | *not recorded — fill in* | +| 10.0.10.10 | booth-receipt printer (park-buzi: [[rongta-printer]]) | *not recorded — fill in* | +| 10.0.10.11 / .7 (lab) | [[k200l-printer]] | `192.168.123.100` | +| 10.0.10.12 / .13 | [[lpr-camera]] entry / exit (Hikvision DS-2CD1047G3H-LIU) | `192.168.1.64` (Hikvision default; needs activation) | +| 10.0.10.203 | the booth PC on the device VLAN (**the `backendIp` every device pushes to**) | — | + +Fill the real numbers into the site record before you drive; the wizard asks for the booth's push +address once and writes it into the Dingtian and the cameras. + +## 1. Dingtian relay board (DT-R004 family) — barriers, button, radar + +**Factory:** IP `192.168.1.100`, web UI on port 80, login `admin` / `admin`, UDP `60000` (binary) / +`60001` (string), multicast discovery `224.0.2.11:60000`. See [[dingtian-relay]]. + +**By hand, on the device (browser at its factory address):** set the site IP / mask / gateway in +the Network page and reboot. That is the only thing you *must* do by hand. Optional but recommended: +in the web UI **disable the UDP2 "string" protocol** (a password-less relay-fire path); the app's +harden step tries to disable it and **warns if the device refused** — then do it here. + +**Wiring:** button on **I1** (NO contact to GND, idles HIGH, pulls LOW on press); radar dry contact +on **I2**; barrier operator's open input on **relay 1** (entry) and **relay 2** (exit); a spare relay +for the entry button lamp ([[button-light-indicator]]). One board can carry both barriers; two +distant barriers = two boards ([[entry-exit-points]]). + +**What the wizard does on assign** ([[first-run-setup]], [[device-input-flow]]): finds the board by +multicast ("Scan for controllers" — laptop/booth must share the L2 segment), checks and clears +`input_link_relay` (factory default auto-fires a relay from its input — the app must decide, not the +board), sets a random **relay password** (UDP binary), disables every other control channel, rotates +the web login, and writes the **input push** URL + per-device Digest credentials so button/radar +edges reach the booth PC. You enter the relay map (which relay is entry/exit/both) and the inputs +(button → its relay; radar → `presence`, `activeLow` if it idles opposite the button — +[[hikvision-radar]]). + +**Traps** + +- The HTTP CGI API is **unauthenticated** on this firmware; `admin/admin` gates only the web page. + Never enable `session_en` — it bricks the config API and only a **factory reset** recovers. The + VLAN is the boundary, not the login ([[dingtian-relay]] §Hardening). +- A relay password mismatch shows as **"offline despite ping"**: the status query is answered only + with the right password. Re-assign / re-enter the relay password in the device form. +- "Relay test" in Setup pulses real hardware and signs a ledger event — use it to prove wiring, + once per relay. + +## 2. Dingtian DT-008 QR + RFID readers + +**Factory:** IP `192.168.1.99`; no web UI — everything is set with **`QRCode_v1_6_5.exe`** over the +network. See [[dingtian-dt008-reader]]. + +**By hand, in the tool, per reader:** + +1. **Unique device IP** (`.7` entry, `.8` exit). Two readers on one IP was the 2026-06-18 + "wrong barrier" incident — scans land on the wrong device row. +2. **Server IP** = the booth PC (`10.0.10.203`), **server port** = the booth's HTTP port (80 behind + the prod proxy); "server language" can stay whatever it is (php/jsp/asp/aspx/cgi are all + served — the reader GETs `/qa/mcardsea.`). +3. **Output prefixes:** `QRCode Output Prefix` = `Q:`, `Card Output Prefix` = `K:` (channel + tagging — a printed clone of a card cannot pass as the card). +4. **Card Input format = `6H`** (defines the UID shape enrolled; changing it later orphans every + card). +5. **Symbologies: QR + Code128 only**, minimum decode length ≥ 10, checksums on — otherwise low + sun through the striped arm produces phantom 6-digit reads (park-buzi, July). +6. Note the **serial (`cjihao`)** — the wizard binds the reader by serial, not by IP. + +**In the wizard:** add the reader with its serial, bind it to the controller relay it sits at +(direction is inherited from the relay). **Verify:** scan a card — the server log shows +`READ serial=… → device=… verdict=… dir=…`; the reader beeps **twice** on accept, once on refuse, +and only after the server's reply (no reply = no beep, the scan still happened). + +**Trap:** a factory reset or a swapped unit silently loses items 3–5. Re-apply all of them. + +## 3. Hikvision camera (DS-2CD1047G3H-LIU, AcuSense) — ANPR + snapshots + +**Factory:** `192.168.1.64`, **inactive** until a password is set on first boot (browser at that +address or the SADP tool); after activation the login is `admin` / the password you chose. Site +convention so far: `admin` / `admin123` on the first units (change per site and record it). See +[[lpr-camera]]. + +**By hand, on the camera:** + +1. Activate, set the site IP, disable DHCP. Time: NTP off-site is unavailable — the app re-syncs + the camera clock from the booth at every offline→ready edge ([[clock-integrity]]). +2. **Streams:** the snapshot the app pulls MUST come from the **sub stream** (`102`) — the main + stream's ISAPI snapshot returns **503 instantly, always, on this model**. Set the sub stream to + the highest resolution the camera allows. +3. **Event push:** Event → Motion Detection with the AcuSense **Detection Target = Vehicle** filter + ON, "Notify Surveillance Center" on, then Alarm Settings → **Alarm Server** → + `http://10.0.10.203/api/devices/hikvision//event`. The `deviceId` exists only after + the wizard assign, so: **assign first, then come back to the camera**. Digest user/password if + the firmware allows it (the wizard shows them). +4. "Enable Hikvision-CGI" is a different legacy surface — **not** needed for ISAPI. +5. **Close the web UI / live view when done.** The camera has few connection slots; a browser left + open makes every snapshot pull 503 "Device Busy" ([[lpr-camera]] §503). + +**In the wizard:** driver `hikvision`, host, `admin` password, channel 1, **stream = Sub**, ANPR on, +bind to the relay at that barrier, `alarmPushEnabled` on. + +**Verify, do not assume:** drive a car through and look at `GET /api/events` (or the log) for an +alarm with `targetType=vehicle`. A camera configured for push that has sent **zero** alarms is +broken on its side: pull its *Diagnose Information*; `Main Db is broken` means a corrupt config +database → **factory reset**, then redo 1–3 (the Vehicle target filter defaults OFF after a reset). +Point the Alarm Server at a dumb HTTP sink on the laptop if you need to see the verbatim body +([[lpr-camera]] §"auto-enter but not auto-exit"). + +## 4. Radar (vehicle presence at the entry barrier) + +A dry-contact sensor into a Dingtian input, nothing on the network. Check with the board's input +status (`00` query → `relays:inputs`) whether it **idles HIGH or LOW**; if it idles opposite the +button, set `activeLow` on that input in the wizard, or the gate inverts (tickets only when the +lane is empty). It is advisory: it gates the button, it never opens anything ([[hikvision-radar]], +[[entry-double-press]]). + +## 5. Printers — three models, one byte stream, different status + +All print the same ESC/POS bytes over **raw TCP 9100** or **USB (`/dev/usb/lpN`)**; what differs +is whether the app can see paper/cover state ([[printer-status-monitoring]], +[[printer-usb-transport]]). Roles: **entry-dispenser** outside at the lane, **booth-receipt** +inside (receipts, subscription cards, Z-reports, and the backup for entry tickets), **wash-desk** +if the site has a Car Wash ([[printer-roles-failover]]). Higher `failoverRank` = tried first. + +| Model | Factory network | Config UI | App driver | Live status | +| --- | --- | --- | --- | --- | +| [[k200l-printer]] (Xprinter/ICS K200L, "POS-80" board; **the park-buzi unit**) | `192.168.123.100/24`, DHCP off | browser, port 80, no login: Configuration → fixed IP → Save → Restart | **`k200l`** | over LAN: cover / paper / cutter / off-line from `/prt_status.htm`; over USB: reachability only | +| [[rongta-printer]] (RP-series) | *not recorded — fill in* | status page `/prn_stat.htm` on port 80 | `rongta` | over LAN: full; USB: reachability | +| Cashino KP-300H | *not recorded — fill in* | *not recorded* | `escpos` (generic) | reachability only, by design — no trustworthy status source | + +**Prefer LAN over USB** wherever a cable can reach: the booth sees a real amber "cover open, paper +out" while a roll is changed, and the `usblp` path (udev rule, node renumbering, the park-buzi +"offline after reload" mystery) drops out of the picture. USB needs the appliance's `usblp` + +udev rule ([[printer-usb-transport]] §Provisioning) and the printer shows up as `/dev/usb/lpN`, +numbered by plug order. + +**Verify:** the wizard's "Test" only *probes* (opens the port / the device node) — it prints +nothing. Print something real: a subscription with a QR credential auto-prints its card and has a +**Reprint card** button; a payment prints a receipt; a wash till prints slips. Check the Cashino's +barcode with a real ticket (the KP-300H garbled overflowing barcodes until the geometry fix). + +## 6. Order of work on site + +1. Address plan on paper; VLAN ports patched; booth PC up with its device-VLAN address. +2. Dingtian: factory address → site address (browser) → wire button, radar, barriers. +3. Wizard: **controllers first** (the relay map + inputs); "Relay test" each barrier. +4. Readers: tool (IP, server, prefixes, format, symbologies) → wizard (serial, bind) → scan test. +5. Cameras: activate → IP → sub stream → wizard assign → Alarm Server + Vehicle target → drive-through + test → close the browser. +6. Printers: site address → wizard (role, rank) → print a card. +7. Walk-through: button + radar → ticket; QR entry then exit; RFID; a subscriber's plate at the + camera; pay at the booth → receipt → exit; paper reload on each printer while watching the + footer. +8. Record in the site record: every IP, serial, camera password, printer model, which relay is + which, photos of the labels. Remove the temporary laptop addresses. Log out of every device UI. + +## Gaps to fill next time you hold the hardware + +- Factory address and configuration tool of the **Cashino KP-300H** and the **Rongta RP** units + (both still unknown here). +- The exact screens in `QRCode_v1_6_5.exe` for the reader's IP and server target (a screenshot). +- Whether the camera activation was done with SADP or the browser at park-buzi, and the per-site + camera password location. +- Where the **site record** lives (a page per site under `wiki/entities/`? — park-buzi and park-2 + have none yet; the Komodo stack env is the closest thing). + +Related: [[appliance-provisioning]] · [[first-run-setup]] · [[device-registry]] · +[[network-isolation]] · [[entry-exit-points]] · [[dingtian-relay]] · [[dingtian-dt008-reader]] · +[[lpr-camera]] · [[hikvision-radar]] · [[k200l-printer]] · [[rongta-printer]] · +[[printer-usb-transport]] · [[wsl-dev-networking]] diff --git a/wiki/decisions/appliance-provisioning.md b/wiki/decisions/appliance-provisioning.md index 218225a..8fee786 100644 --- a/wiki/decisions/appliance-provisioning.md +++ b/wiki/decisions/appliance-provisioning.md @@ -14,6 +14,8 @@ parking appliance. Written from the **first real provisioning, 2026-06-23** (har actual hardware, including the firmware-specific workaround. Companion to [[disk-os-hardening]] (the *why*), [[tpm]] (TPM analysis), [[container-deployment]] (the images), and [[fleet-deployment-komodo]] (the deploy control plane this runbook's §7 uses). +**The devices plugged into the booth** (relay board, readers, cameras, radar, printers — factory +addresses, tools, hand steps, traps) have their own field runbook: [[site-device-installation]]. > ⚠ This box is the [[threat-model|outsider-with-the-box]] defence. The load-bearing anti-fraud > control is still [[reconciliation]] over the [[append-only-event-chain|signed chain]] — disk diff --git a/wiki/log.md b/wiki/log.md index c9cb843..3d9b430 100644 --- a/wiki/log.md +++ b/wiki/log.md @@ -3249,3 +3249,51 @@ from park-2 then corrected (the copy carried park-2's review outbox + booth-2 to bench must never feed the collector under a booth id); pinned to the booth's stage-. Pages: [[printer-usb-transport]] (identity, bench result, WSL caveat), [[fleet-deployment-komodo]] (park-lab row). + +## [2026-09-09] ingest | Printer cover-open bug — lab did NOT reproduce; park-buzi closed, evidence pending +Same printer unit on `park-lab` (real Linux host, booth image stage-2d9bb15, prod compose, dev DB +snapshot with the USB printer as booth-receipt, cards via subscription reprint): paper out → cover +→ reload → reprint — no error. Printer, USB transport and compose wiring cleared in isolation; +what remains is park-buzi's environment (kernel/USB path/power) or the container's history. +park-buzi is shut down (staff shortage). Recorded on [[printer-usb-transport]]: the three +commands to run FIRST when the box next powers on (container log transitions, kernel journal, +`lsusb -t`), how to read each answer, and two proposed no-booth follow-ups (close the +`withTimeout` handle leak; make the monitor self-document consecutive USB offline polls). +Dev-DB snapshot procedure for a lab (online backup → reset-db --financial --diagnostics → clear +backup fields → VACUUM → copy into the volume with chown) used today; not yet on a wiki page. + +## [2026-09-09] build | K200L printer identified + `k200l` driver with live status; network setup recorded +The bottom label says **Model K200L** (Xprinter/ICS XP-K200L family, USB+LAN, ESC/POS); the LAN +board ("J-Speed Ethernet WebConfig 1.02") calls it "POS-80", as does the USB descriptor. User +configured it from factory 192.168.123.100 (DHCP off, web UI on :80, no auth) to 10.0.10.7 on the +lab; added as booth printer on `park-lab` on the generic driver → badge stayed green with the cover +open, because the generic driver is reachability-only by design. Found the board's status page: +**`/prt_status.htm`**, the Rongta's five rows exactly, but the reply has NO status line/headers +(node:http: "Parse Error: Expected HTTP/"; curl: 000/empty) — so a Rongta-path option would not +have worked. Per the user ("this is not rongta", "create a new printer"): the Rongta driver is +untouched; new **`printer-k200l.ts`** (`k200l`) delegates printing to the generic ESC/POS device +and reads the page over a raw socket, tolerant of both reply shapes; mapping mirrors the Rongta +(unreachable → offline, page not understood → degraded never ready, faults → degraded named, USB → +floor). Tests replay the captured headerless page (10 new, devices suite 76 green); live probe +against 10.0.10.7 → ready; bench with cover open showed "cover open, paper out, printer off-line". +Consequence for park-buzi: over USB the app never saw cover/paper state at all — the reported +"offline" is a probe failure (errno still to be pulled). Pages: new [[k200l-printer]] (names, +network setup runbook, board quirks, status page, park-buzi implication), [[rongta-printer]], +[[printer-status-monitoring]], [[printer-usb-transport]], [[wsl-dev-networking]] (parking-net +pinned to eth1 while the LAN NIC is eth0 — the source-address bug bit again), index. + +## [2026-09-09] query | Field runbook: installing the devices at a site (what to know before the booth) +User: "we need a section about installing these devices in the park sites … I didn't know this +printer has initial IP 192.168.123.100 and a web interface … also dingtian relays and readers, +cashino printers — know beforehand, not struggle on site." New reference page +[[site-device-installation]], synthesised from the entity pages + memory notes: the bring list, +the site address plan (10.0.10.x convention, every device static), then per device — Dingtian +relay (factory 192.168.1.100, admin/admin, what harden() does vs the by-hand IP + UDP2 disable, +wiring I1/I2, unauthenticated CGI, session_en brick), DT-008 readers (192.168.1.99, the +QRCode_v1_6_5.exe tool: unique IP, server target, Q:/K: prefixes, 6H card format, QR+Code128 +only, serial binding, re-apply after a reset), Hikvision G3H (192.168.1.64 + activation, SUB +stream mandatory, Alarm Server after assign, Vehicle target filter, close the web UI, corrupt-DB +factory reset), radar (idle level → activeLow), printers (K200L / Rongta / Cashino table; LAN over +USB; "Test" probes, print a card to verify), the on-site order of work, and the gaps still +unrecorded (Cashino/Rongta factory addresses, the reader tool screens, camera activation, where +the site record lives). Linked from [[appliance-provisioning]] and [[k200l-printer]]; indexed.