wiki: ER80 protocol = HTTP GET poll + JSON verdict (from QRCode SDK)
The QRCode SDK v1.6.5 settles the reader protocol (supersedes the earlier
serial guess). On each scan the reader HTTP-GETs the host
(/qa/mcardsea.php?cardid&mjihao&cjihao&status&time); the host replies JSON
{data:[{...,status,output}],code:0}. Reply status 1=valid(beep 2x)/0=invalid
(beep 1x); output 0=Access/1=WG26/2=WG34; time syncs the clock. The GET's status
low digit is the direction (1=in/0=out).
Key: the beep/accept is decided by the SERVER REPLY, not locally -- the 'no
beep' during bring-up was a plain-text reply, not a scan failure. Host-in-the-
loop and synchronous. 'Server language' only selects the URL path; transport is
plain HTTP.
New source page qrcode-sdk; updated gee-qr-er80 (protocol resolved), index.
This commit is contained in:
@@ -23,37 +23,42 @@ scanner** the design called for — read at the pay station and exit lane — an
|
||||
- **Multi-interface** (Wiegand 26/34, RS-232, RS-485, USB, TCP/IP); the `-W` variant exposes
|
||||
**Wiegand + RS-232/RS-485**.
|
||||
|
||||
## How it fits our architecture — host-side reader
|
||||
## How it integrates — HTTP-GET push, server replies the verdict (confirmed via SDK)
|
||||
|
||||
It's a **host-side identity source** ([[entry-exit-readers]]): the host sees the scan, decides, and
|
||||
commands the relay — exactly the model the read-driven flows already use. A scan becomes a
|
||||
`DeviceReadEvent` on the internal `read` bus (`kind: "qr"`/`"ticket"`, value = the scanned string),
|
||||
consumed by the **exit flow** and the **QR-permit** path ([[parking-session]], [[permit]]) — both
|
||||
**already built**. So integration is a new **`ReaderDevice` adapter**, no business-logic change
|
||||
([[device-adapter-pattern]]).
|
||||
The protocol is settled by the **[[qrcode-sdk|QRCode SDK v1.6.5]]** (not serial as first guessed).
|
||||
The reader is configured (Windows tool `QRCode_v1_6_5.exe`) with a **server IP/port** and a "server
|
||||
language" (only picks the URL path, e.g. `/qa/mcardsea.php`). **On each scan it HTTP-GETs the host:**
|
||||
|
||||
- **Interface choice:** prefer **RS-232/RS-485 (serial)** for the QR variant — Wiegand can't carry a
|
||||
variable-length QR string well (it's built for fixed-width card IDs). The host reads scans over a
|
||||
serial port (USB-serial on TX/RX, or the USB variant); no Wiegand-decode hardware needed. This
|
||||
suits [[offline-first]] (local serial, no network) and sidesteps the [[dingtian-relay|Dingtian]]'s
|
||||
lack of an onboard card list (we never wanted autonomy here anyway).
|
||||
- **LED/BEEP control lines** mean the host can drive scan feedback (accepted/rejected) — nice for an
|
||||
unmanned lane.
|
||||
- **Linux-supported**, 4–15 VDC — fits the [[disk-os-hardening|appliance]].
|
||||
```
|
||||
GET /qa/mcardsea.php?cardid=<QR>&mjihao=<devId>&cjihao=<devSN>&status=<2 chars>&time=<utc>
|
||||
```
|
||||
`cardid` = scanned data; `status` low digit = **direction (1=in / 0=out)**. The host replies JSON
|
||||
`{data:[{cardid,cjihao,mjihao,status,time,output}],code:0}` where reply **`status` 1=valid (beep
|
||||
2×) / 0=invalid (beep 1×)**, **`output` 0=Access/1=WG26/2=WG34**, `time` syncs the clock.
|
||||
|
||||
## Open questions (block the adapter)
|
||||
This is **host-in-the-loop and SYNCHRONOUS**: the GET *is* the access query and **our reply is the
|
||||
decision** — it drives the reader's beep + output. So unlike a fire-and-forget reader, the endpoint
|
||||
must decide (valid/invalid, direction from `status`) and reply, then also emit a `DeviceReadEvent`
|
||||
on the `read` bus for the entry/exit/permit flows ([[parking-session]], [[permit]]) to open the
|
||||
barrier. ([[device-input-flow]] is the analogous push pattern; this one also returns a verdict.)
|
||||
|
||||
1. **RS-232/RS-485 protocol:** baud rate + frame format, and confirm a QR scan emits as an **ASCII
|
||||
string** (expected) terminated by CR/LF vs. a framed/checksummed protocol. This is the one fact
|
||||
the adapter needs and the datasheet omits. Resolve via vendor docs or by observing the port on a
|
||||
scan.
|
||||
2. **Serial vs. USB-CDC vs. TCP/IP** for *this* unit: `-W` is Wiegand/RS-232/485. Decide the host
|
||||
wiring (a USB-RS232/485 adapter on TX/RX, most likely).
|
||||
3. **Does Wiegand mode even carry QR?** Likely Wiegand is for the optional *card* modes only; confirm
|
||||
so we don't design a Wiegand path for QR.
|
||||
> **This explains the "no beep":** feedback comes from the server's JSON reply, not locally. A
|
||||
> non-JSON / missing reply ⇒ no beep even though the scan worked. So "no beep" ≠ "didn't scan."
|
||||
|
||||
- Pushes over plain **HTTP** to our `10.0.10.x` host (on the device subnet); no serial wiring, no
|
||||
Wiegand-decode hardware. Suits the host-in-the-loop model; autonomy is moot anyway
|
||||
([[dingtian-relay]] has no onboard ACL).
|
||||
- **Linux-supported**, 4–15 VDC, default IP `192.168.1.99` — fits the [[disk-os-hardening|appliance]].
|
||||
|
||||
## Resolved (2026-06-16)
|
||||
|
||||
- Protocol = HTTP GET poll + JSON verdict (above). The earlier "serial/Wiegand, find the baud"
|
||||
open questions are **moot** — it's HTTP. Wiegand is the reader's *output line* on a valid read
|
||||
(the reply `output` field), not the host transport.
|
||||
|
||||
## Next
|
||||
|
||||
A `ReaderDevice` driver in `packages/devices` (serial transport) emitting `read` events. Add it to
|
||||
the [[device-registry]] under the `reader` category so the [[first-run-setup]] wizard can assign it
|
||||
per lane. Pending open-question #1 (the serial frame) before coding.
|
||||
A backend route (like `routes/devices.ts` for the Dingtian push) that parses the GET, **decides**
|
||||
(reuse the permit/exit lookup), replies the JSON verdict, and emits on the `read` bus. The
|
||||
[[device-registry]] `reader` entry can model it for [[first-run-setup]] (server IP/port are set in
|
||||
the vendor tool; the app side is the endpoint). Build-ready — protocol fully known.
|
||||
|
||||
Reference in New Issue
Block a user