diff --git a/apps/server/src/device-events.ts b/apps/server/src/device-events.ts index ee2440d..cfbacf8 100644 --- a/apps/server/src/device-events.ts +++ b/apps/server/src/device-events.ts @@ -30,7 +30,7 @@ export interface DeviceReadEvent { /** * The decision a read produced. Returned by the read flows so a SYNCHRONOUS reader * (e.g. the QR reader, whose HTTP reply drives its beep + output) can answer the - * device. A fire-and-forget reader simply ignores it. See wiki/entities/gee-qr-er80.md. + * device. A fire-and-forget reader simply ignores it. See wiki/entities/dingtian-dt008-reader.md. */ export interface ReadOutcome { /** Was the vehicle admitted/exited (barrier opened)? Drives the reader's beep. */ diff --git a/apps/server/src/routes/qr-reader.ts b/apps/server/src/routes/qr-reader.ts index 1077837..8962a0d 100644 --- a/apps/server/src/routes/qr-reader.ts +++ b/apps/server/src/routes/qr-reader.ts @@ -4,10 +4,10 @@ import type { DeviceReadEvent } from "../device-events.js"; import type { ReadDispatcher } from "../read-dispatch.js"; import type { CredentialCapture } from "../credential-capture.js"; -// GEE/Dingtian QR reader endpoint. The reader is configured (vendor tool) with our -// host as its "server"; on each scan it sends an HTTP GET and BEEPS/acts based on +// Dingtian DT-008 QR/RFID reader endpoint. The reader is configured (vendor tool) with +// our host as its "server"; on each scan it sends an HTTP GET and BEEPS/acts based on // our JSON reply — host-in-the-loop and synchronous. Protocol from the QRCode SDK -// v1.6.5; see wiki/sources/qrcode-sdk.md and wiki/entities/gee-qr-er80.md. +// v1.6.5; see wiki/sources/qrcode-sdk.md and wiki/entities/dingtian-dt008-reader.md. // // reader → GET /qa/mcardsea.php?cardid=&mjihao=&cjihao=&status=<2ch>&time= // server → {"data":[{cardid,cjihao,mjihao,status,time,output}],"code":0,"message":""} @@ -35,7 +35,7 @@ export async function qrReaderRoutes( ): Promise { // Resolve the lane_devices row whose config.serial matches the reader's reported // serial (cjihao). The row id is a normal UUID; the serial is config the admin - // enters when assigning the gee-qr-reader. Returns the row id, or null if no + // enters when assigning the dingtian-qr-reader. Returns the row id, or null if no // reader is assigned for that serial. (Small device set → scan in JS.) const readerRowIdForSerial = (serial: string): string | null => { if (!serial) return null; @@ -52,7 +52,7 @@ export async function qrReaderRoutes( // drive output) once the socket CLOSES — every vendor demo replies // `Connection: close` and shuts the socket. Without it the reader waits out a // ~10 s keep-alive timeout before beeping. So force-close the connection. - // See wiki/sources/qrcode-sdk.md, entities/gee-qr-er80.md. + // See wiki/sources/qrcode-sdk.md, entities/dingtian-dt008-reader.md. reply.header("connection", "close"); const cardid = (q.cardid ?? "").trim(); const mjihao = q.mjihao != null ? Number(q.mjihao) : 0; @@ -75,7 +75,7 @@ export async function qrReaderRoutes( accepted = true; // beep "ok" so the operator knows the card was read } else { const read: DeviceReadEvent = { - driverId: "gee-qr-reader", + driverId: "dingtian-qr-reader", deviceId, value: cardid, kind: "qr", diff --git a/apps/server/src/server.ts b/apps/server/src/server.ts index 2407a3d..f725ed8 100644 --- a/apps/server/src/server.ts +++ b/apps/server/src/server.ts @@ -234,10 +234,10 @@ export async function buildServer(opts: BuildOptions = {}): Promise Promise>(); vi.mock("./icmp.js", () => ({ icmpPing: (...a: [string, number?]) => icmpPing(...a) })); -const { geeQrReaderDriver } = await import("./reader.js"); +const { dingtianQrReaderDriver } = await import("./reader.js"); afterEach(() => { icmpPing.mockReset(); @@ -17,26 +17,26 @@ afterEach(() => { describe("QR reader healthCheck (ICMP liveness)", () => { it("with an IP that replies → ready", async () => { icmpPing.mockResolvedValue(true); - const r = geeQrReaderDriver.create({ serial: "H05M2AFA", host: "10.0.10.7" }); + const r = dingtianQrReaderDriver.create({ serial: "H05M2AFA", host: "10.0.10.7" }); expect(await r.healthCheck()).toEqual({ status: "ready", detail: "ping 10.0.10.7" }); expect(icmpPing).toHaveBeenCalledWith("10.0.10.7"); }); it("with an IP that does NOT reply → offline (this is the bug fix)", async () => { icmpPing.mockResolvedValue(false); - const r = geeQrReaderDriver.create({ serial: "H05M2AFA", host: "10.0.10.7" }); + const r = dingtianQrReaderDriver.create({ serial: "H05M2AFA", host: "10.0.10.7" }); expect(await r.healthCheck()).toEqual({ status: "offline", detail: "no ping reply from 10.0.10.7" }); }); it("with NO IP → degraded (never a false 'ready')", async () => { - const r = geeQrReaderDriver.create({ serial: "H05M2AFA" }); + const r = dingtianQrReaderDriver.create({ serial: "H05M2AFA" }); const h = await r.healthCheck(); expect(h.status).toBe("degraded"); expect(icmpPing).not.toHaveBeenCalled(); // nothing to ping }); it("exposes an optional host field for monitoring", () => { - const hostField = geeQrReaderDriver.configFields.find((f) => f.key === "host"); + const hostField = dingtianQrReaderDriver.configFields.find((f) => f.key === "host"); expect(hostField).toBeDefined(); expect(hostField!.required).toBe(false); // operation is push-by-serial; IP is monitor-only }); diff --git a/packages/devices/src/drivers/reader.ts b/packages/devices/src/drivers/reader.ts index a410430..fcafe78 100644 --- a/packages/devices/src/drivers/reader.ts +++ b/packages/devices/src/drivers/reader.ts @@ -75,18 +75,19 @@ export const tcpipReaderDriver: ReaderDriver = { create: (c) => new StubReader("tcpip-reader", c), }; -// GEE/Fondvision QR access reader (e.g. GEE-QR-ER80). A PUSH device: on each scan -// it HTTP-GETs our backend (/qa/mcardsea.) carrying its serial (cjihao); the -// backend resolves the lane by matching that serial to this device's `serial` -// config, decides, and replies the verdict (drives the beep). No host-side -// connection — the adapter is a stub; the real integration is the HTTP endpoint -// (apps/server routes/qr-reader.ts). See wiki/entities/gee-qr-er80.md. -export const geeQrReaderDriver: ReaderDriver = { - id: "gee-qr-reader", +// Dingtian DT-008 QR/RFID access reader (same vendor as the relay board). Scans QR/barcode +// + ID/IC/NFC cards. A PUSH device: on each scan it HTTP-GETs our backend (/qa/mcardsea.) +// carrying its serial (cjihao); the backend resolves the lane by matching that serial to this +// device's `serial` config, decides, and replies the verdict (drives the beep). No host-side +// connection — the adapter is a stub; the real integration is the HTTP endpoint (apps/server +// routes/qr-reader.ts). Interfaces: Wiegand 26/34, TCP/IP, USB, RS485. See +// wiki/entities/dingtian-dt008-reader.md. +export const dingtianQrReaderDriver: ReaderDriver = { + id: "dingtian-qr-reader", category: "reader", - label: "GEE/Fondvision QR reader (HTTP push)", + label: "Dingtian DT-008 QR/RFID reader (HTTP push)", description: - "QR/barcode access reader that HTTP-pushes each scan to the backend. Set its server IP/port to this host in the vendor tool; enter its serial here so scans resolve to this lane.", + "Dingtian DT-008 QR/barcode/RFID access reader that HTTP-pushes each scan to the backend. Set its server IP/port to this host in the vendor tool; enter its serial here so scans resolve to this lane.", transports: ["tcp-ip"], configFields: [ { @@ -105,5 +106,5 @@ export const geeQrReaderDriver: ReaderDriver = { help: "Optional: the reader's IP, used ONLY to monitor it (ping). Scans still resolve by serial. Leave blank to skip liveness monitoring.", }, ], - create: (c) => new StubReader("gee-qr-reader", c), + create: (c) => new StubReader("dingtian-qr-reader", c), }; diff --git a/packages/devices/src/index.ts b/packages/devices/src/index.ts index 56001dd..4d30f14 100644 --- a/packages/devices/src/index.ts +++ b/packages/devices/src/index.ts @@ -14,7 +14,7 @@ export { stubAccessDriver, wiegandReaderDriver, tcpipReaderDriver, - geeQrReaderDriver, + dingtianQrReaderDriver, hikvisionDriver, dahuaDriver, rongtaDriver, diff --git a/wiki/concepts/device-status-monitoring.md b/wiki/concepts/device-status-monitoring.md index 27f6d1d..8eb20f5 100644 --- a/wiki/concepts/device-status-monitoring.md +++ b/wiki/concepts/device-status-monitoring.md @@ -33,7 +33,7 @@ talks only to the adapter interfaces ([[device-adapter-pattern]]), never a drive > an **unprivileged ICMP ping** (`drivers/icmp.ts`, shells `/bin/ping` in SOCK_DGRAM mode — no > CAP_NET_RAW, no native dep; the booth compose sets `net.ipv4.ping_group_range`). Reply → `ready`, > no reply → `offline`; **no IP set → `degraded` ("set IP to monitor")**, never a false green. - > Verified on hardware: pinged the real readers on the device VLAN. See [[gee-qr-er80]]. + > Verified on hardware: pinged the real readers on the device VLAN. See [[dingtian-dt008-reader]]. Both collapse to one **traffic-light**: `ready | degraded | offline`, plus a `detail` string. Fail **toward "there's a problem"**, never false-healthy: a probe that throws or times out reads diff --git a/wiki/concepts/entry-exit-readers.md b/wiki/concepts/entry-exit-readers.md index cdf6c86..5505a96 100644 --- a/wiki/concepts/entry-exit-readers.md +++ b/wiki/concepts/entry-exit-readers.md @@ -22,9 +22,9 @@ There are **two populations** of users, and they map to **two integration paths* | [[wiegand]] reader → UHPPOTE port | The controller | Controller (onboard card list) | **Yes** — works if host down | | Pure TCP/IP reader | Host only | Host, then UDP `open` to relay | No — host on critical path | | [[lpr-camera|LPR]] / QR scanner | Host only | Host | No | -| **[[gee-qr-er80]] QR reader (serial)** | Host only | Host (reads serial → `read` bus) | No | +| **[[dingtian-dt008-reader|Dingtian DT-008]] QR reader** | Host only | Host (reads serial → `read` bus) | No | -> Concrete host-side reader on hand: the **[[gee-qr-er80]]** (QR over RS-232/RS-485). Note autonomy +> Concrete host-side reader on hand: the **[[dingtian-dt008-reader|Dingtian DT-008]]** (QR/RFID over HTTP push). Note autonomy > is moot here anyway — the current relay ([[dingtian-relay]]) has **no onboard card list**, so even > a Wiegand reader would be host-decided. So we take the serial/QR path straight to the host's > `read` bus. diff --git a/wiki/concepts/ticket-encoding.md b/wiki/concepts/ticket-encoding.md index 9466d9a..5d12fdb 100644 --- a/wiki/concepts/ticket-encoding.md +++ b/wiki/concepts/ticket-encoding.md @@ -80,9 +80,9 @@ must have: - The **scanner is a device behind an adapter** ([[device-adapter-pattern]]): a new `ReaderDevice` kind (QR/barcode imager) — likely the same `IdentitySource = "ticket"` / `"qr"` path. Keeps the app device-agnostic; hardware model is procurement ([[bom]], [[open-questions]]). - - **On hand:** the **[[gee-qr-er80]]** QR access reader (`-Q-W`: QR scanner, Wiegand/RS-232/RS-485, + - **On hand:** the **[[dingtian-dt008-reader|Dingtian DT-008]]** QR/RFID reader (Wiegand/TCP-IP/USB/RS485, Linux-supported) — the concrete scanner for this path. A serial `ReaderDevice` adapter feeds the - `read` bus; pending the reader's RS-232 frame/baud (see [[gee-qr-er80]] open questions). + `read` bus; via HTTP-GET push (see [[dingtian-dt008-reader]]). ## Ticketless alternative (plate as the ticket) diff --git a/wiki/entities/gee-qr-er80.md b/wiki/entities/dingtian-dt008-reader.md similarity index 75% rename from wiki/entities/gee-qr-er80.md rename to wiki/entities/dingtian-dt008-reader.md index 955a257..5a318bc 100644 --- a/wiki/entities/gee-qr-er80.md +++ b/wiki/entities/dingtian-dt008-reader.md @@ -1,27 +1,34 @@ --- type: entity -tags: [parking, hardware, readers, qr] -sources: [gee-qr-er80] -updated: 2026-06-16 +tags: [parking, hardware, readers, qr, dingtian] +sources: [dingtian-dt008] +updated: 2026-06-28 status: open --- -# GEE-QR-ER80 (QR access reader) +# Dingtian DT-008 (QR/RFID access reader) -The project's **QR-code reader** (GEE NFC LIMITED). A static optical scanner for **QR / -DataMatrix / 1D barcode**, optional ID/IC card. This is the **[[ticket-encoding|QR ticket]] -scanner** the design called for — read at the pay station and exit lane — and a path for **QR -[[subscription]]** credentials. On hand: variant **`-Q-W`** (QR scanner; Wiegand/RS-232/RS-485). -(See [[gee-qr-er80|datasheet summary]] / `raw/`.) +The project's **QR / barcode / RFID reader** — Dingtian **DT-008**, the **same vendor as the +[[dingtian-relay|relay board]]** (which is why it integrates the same HTTP-push way). A static +optical + card scanner for **QR / barcode (simple)** and **ID/IC/NFC cards**. This is the +**[[ticket-encoding|QR ticket]]** scanner (read at the pay station / exit lane) and a path for **QR +or RFID [[subscription]]** credentials. Product page: dingtian-tech.com/en_us/qr_code_reader.html. +(See [[dingtian-dt008|spec summary]] / `raw/`.) -## What it is (and isn't) +> **Naming correction (2026-06-28).** Through most of this project this reader was wrongly called +> **"GEE" / "GEE/Fondvision" / "GEE-QR-ER80"** — a bad early assumption. There is no GEE device; it +> is the **Dingtian DT-008**. The driver id was renamed `gee-qr-reader` → `dingtian-qr-reader` +> (migration 0015 rewrites existing rows). All *protocol/behaviour* facts below were observed on the +> real hardware and remain correct — only the device identity was wrong. -- **Optical, not RFID-prox.** Earlier we *assumed* "ER80-EM" = a 125 kHz EM4100 card reader — the - datasheet corrects that: it's a **QR/barcode scanner**. The `-EM` in the original label was a - mis-id; the real model is **GEE-QR-ER80**. Optional `D`/`C` variants add ID/IC card, but the unit - on hand is **QR-only** (`-Q`). -- **Multi-interface** (Wiegand 26/34, RS-232, RS-485, USB, TCP/IP); the `-W` variant exposes - **Wiegand + RS-232/RS-485**. +## What it is + +- **QR/barcode + card.** Reads **QR / simple barcode** AND **ID/IC/NFC cards** (~0.2 s, 0–10 cm). + (An earlier note guessed "ER80-EM = 125 kHz EM4100 prox" — that was part of the same mis-id.) +- **Interfaces: Wiegand 26/34, TCP/IP, USB, RS485.** (NOT RS-232 — that was a fictional-datasheet + claim.) For our integration it talks **HTTP over TCP/IP**; Wiegand is the reader's *output line* + on a valid read, not the host transport. +- **Power** 9–16 V DC, 800 mA; **86×86×42 mm**; −30…70 °C. Fits the [[disk-os-hardening|appliance]]. ## How it integrates — HTTP-GET push, server replies the verdict (confirmed via SDK) @@ -48,7 +55,7 @@ barrier. ([[device-input-flow]] is the analogous push pattern; this one also ret - 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]]. +- Default IP `192.168.1.99` (set its server IP/port to this host in the vendor tool). ## Resolved (2026-06-16) @@ -93,18 +100,18 @@ from 10.0.10.7 (referer: http://www.fondvision.com — the OEM is Fondvision) ## Assignment (as-built 2026-06-16) -A dedicated **`gee-qr-reader`** driver ([[device-registry]], reader category) models the push reader: +A dedicated **`dingtian-qr-reader`** driver ([[device-registry]], reader category) models the push reader: its one config field is **`serial`** (the `cjihao` the device reports). The admin assigns it in the [[first-run-setup|setup wizard]] like any device (normal UUID row id), enters the serial, and binds it to a controller relay. The QR endpoint resolves the reader by **matching `config.serial` to the scan's `cjihao`** — not by row id — so no DB hand-editing. Set the reader's server IP/port to this host in the **vendor tool**; assign + enter its serial + bind it here. -- Verified via inject: assign `gee-qr-reader` {serial:"H05M2AFA"} bound to an access relay → +- Verified via inject: assign `dingtian-qr-reader` {serial:"H05M2AFA"} bound to an access relay → a `.jsp` scan with that serial + a matching permit QR → `status:1` (2-beep accept) + open; re-scan → permit exit; unknown card → `status:0`; unassigned serial → `status:0` (no relay, graceful). - Note `tcpip-reader` is the WRONG model for this device (host-connects-out, a stub) — use - `gee-qr-reader`. + `dingtian-qr-reader`. ## Open / next diff --git a/wiki/entities/subscription.md b/wiki/entities/subscription.md index 24c2c26..212cc3a 100644 --- a/wiki/entities/subscription.md +++ b/wiki/entities/subscription.md @@ -237,7 +237,7 @@ LPR/ANPR plate identity** (the plate binding below): (a chosen value could be guessable or collide). The UI sends a blank QR credential; the server mints the value and returns it (so the UI can print it). **An RF credential, by contrast, carries the physical card id, so it is operator-entered.** - - **Reader output = TCP/IP full string** (decided 2026-06-18, the [[gee-qr-er80|host-in-the-loop + - **Reader output = TCP/IP full string** (decided 2026-06-18, the [[dingtian-dt008-reader|host-in-the-loop QR reader]] path): the reader delivers the whole decoded string, so the code length is free (unguessable token). *If a site ever wires the reader as **Wiegand 26/34** instead, a scanned QR truncates to a 24-/32-bit number — the generated code would then have to be a numeric id in @@ -255,7 +255,7 @@ LPR/ANPR plate identity** (the plate binding below): - **RF tag / chip / card — selectable later, NOT live yet.** An RFID/proximity credential, read **host-side** (reader → host → `pulseOpen`). **LIVE since 2026-06-18** — the operator selects RFID and **reads the card off a physical reader** (see "Enrolling a card" below) rather than typing the - number. The GEE readers are combo QR + RFID (ID/IC/NFC), so the same device captures both. A + number. The Dingtian DT-008 readers are combo QR + RFID (ID/IC/NFC), so the same device captures both. A Wiegand-out reader keeps a future autonomous path open ([[entry-exit-readers]]); the [[dingtian-relay]] has no onboard card list. - **Plate (LPR/ANPR) — matching is BUILT, the live SOURCE is the one missing wire.** When plate-bound @@ -296,7 +296,7 @@ traffic, so capture must **borrow one reader briefly without blocking the other* A subscription is a one-to-many aggregate: it may hold **several credentials at once** — e.g. a QR **and** an RFID card (and later NFC). Each is its own `subscription_credentials` row; any of them resolves the same subscription at the barrier. (NFC works today as an `rf` credential on the combo -GEE reader; a distinct `nfc` `kind` is a small future labelling-only addition.) +Dingtian DT-008 reader; a distinct `nfc` `kind` is a small future labelling-only addition.) Crucially, **entry and exit are NOT bound to the same credential.** Originally the session was keyed by the exact credential value read, so you had to leave with whatever you arrived with — an diff --git a/wiki/index.md b/wiki/index.md index 1fe77ab..8e80299 100644 --- a/wiki/index.md +++ b/wiki/index.md @@ -16,7 +16,7 @@ Counts: 4 sources · 19 entities · 45 concepts · 7 decision records. ## Sources - [[parking-system-architecture]] — design notes: stack, threat model, devices, UHPPOTE, ESP32, readers, BOM, open decisions. -- [[gee-qr-er80]] — datasheet: GEE QR access reader (QR/DM/1D; Wiegand/RS-232/485/USB/TCP; Linux). +- [[dingtian-dt008]] — Dingtian DT-008 product page: QR/RFID access reader (QR/barcode + ID/IC/NFC; Wiegand/TCP-IP/USB/RS485; HTTP-GET push). - [[qrcode-sdk]] — QRCode SDK v1.6.5: the reader's HTTP-GET-poll protocol + JSON verdict (beep/output). - [[parksql2017-legacy-schema]] — predecessor SQL Server schema (Albanian market): legacy tariff/discount/membership/shift/fiscal model; confirms blocks, adds time-windows + categories, lacks postpaid sponsors. @@ -40,7 +40,7 @@ Counts: 4 sources · 19 entities · 45 concepts · 7 decision records. - [[atecc608]] — secure element; non-extractable signing key (host events + controller auth). - [[wiegand]] — reader standard feeding the controller directly (autonomous permit-holder path). - [[lpr-camera]] — edge-AI plate recognition; host-side casual-identity source. -- [[gee-qr-er80]] — QR access reader on hand; host-side serial → `read` bus (the QR-ticket scanner). +- [[dingtian-dt008-reader]] — Dingtian DT-008 QR/RFID reader on hand; host-side serial → `read` bus (the QR-ticket scanner). - [[zkteco-controller]] — ❌ rejected/historical; aux-input path was a contender, not pursued. - [[dingtian-relay]] — ✅ CHOSEN access controller; decoupled inputs solve the button blocker (driver verified on hardware); spare relays drive aux outputs (`setAux`). - [[hikvision-radar]] — vehicle-presence radar on a Dingtian input; the entry presence gate (per-input active-level caveat). diff --git a/wiki/log.md b/wiki/log.md index 0b9ed3c..88e895b 100644 --- a/wiki/log.md +++ b/wiki/log.md @@ -1884,3 +1884,20 @@ snapshots from it before I caught it. The signed ledger was untouched (snapshots advisory; `PRAGMA integrity_check: ok`, ledger_events/sessions/subscriptions intact) and it was dev not prod — but it violated the never-touch-the-live-DB rule. Lesson: pass the scratch path explicitly + guard-refuse any non-scratch path BEFORE any destructive op (the corrected harness does). + +## [2026-06-28] fix | The QR reader is a Dingtian DT-008, NOT "GEE" (correct an early mis-id) +A wrong early assumption named the QR/RFID access reader "GEE" / "GEE/Fondvision" / "GEE-QR-ER80" +(and summarized a `raw/GEE-QR-ER80….pdf` as its datasheet). There is no GEE device — it's the +**Dingtian DT-008** (https://www.dingtian-tech.com/en_us/qr_code_reader.html), the SAME vendor as +the relay board, which is why it integrates the identical HTTP-GET-push way. Corrected across the +codebase + wiki: driver symbol `geeQrReaderDriver`→`dingtianQrReaderDriver`, **persisted driverId +`gee-qr-reader`→`dingtian-qr-reader`** (migration **0015** rewrites the existing `devices.driver_id` +rows so readers keep resolving — applied to the dev DB, 2 rows; the booth applies it on boot), label +"Dingtian DT-008 QR/RFID reader (HTTP push)", and all server/test/comment refs. Wiki: renamed +`entities/gee-qr-er80.md`→`entities/dingtian-dt008-reader.md` and `sources/gee-qr-er80.md`→ +`sources/dingtian-dt008.md`, rewrote both to the REAL DT-008 specs (Wiegand26/34 + TCP/IP + USB + +RS485 — NOT RS-232; QR/barcode + ID/IC/NFC — NOT DataMatrix/1D; 9–16 V/800 mA) while keeping all the +verified-on-hardware protocol facts (cjihao serial, `.jsp` path, `Connection: close`). Memory +`gee-reader-serial-binding`→`dingtian-reader-serial-binding`. The only surviving "GEE" mentions are +deliberate naming-correction notes + the raw PDF filename. Behaviour unchanged — naming + the +persisted id only. build/lint/test green. diff --git a/wiki/sources/dingtian-dt008.md b/wiki/sources/dingtian-dt008.md new file mode 100644 index 0000000..ba8abf4 --- /dev/null +++ b/wiki/sources/dingtian-dt008.md @@ -0,0 +1,37 @@ +--- +type: source +tags: [parking, hardware, readers, qr, dingtian, datasheet] +sources: [dingtian-dt008] +updated: 2026-06-28 +--- + +# Source: Dingtian DT-008 QR Code Reader (product page) + +Vendor product page for the **Dingtian DT-008** QR/barcode/RFID access reader — +https://www.dingtian-tech.com/en_us/qr_code_reader.html. This is the reader the project +actually has on hand for the [[ticket-encoding|QR ticket]] / RFID-[[subscription]] paths. +Entity: [[dingtian-dt008-reader]]. Same vendor as the [[dingtian-relay|Dingtian relay board]]. + +> **Supersedes a mis-identified source.** The project originally summarized +> `raw/GEE-QR-ER80 QR Code Access Control Reader.pdf` as if the reader were a "GEE-QR-ER80" +> (GEE NFC LIMITED). That was a wrong early assumption — the device is the Dingtian DT-008. +> Several facts in that PDF (RS-232, DataMatrix/1D, a Linux SDK) do **not** match the real +> hardware and were dropped. The HTTP-push protocol facts, however, were later **verified on the +> actual device** (see [[dingtian-dt008-reader]] "Verified on hardware"). + +## Key takeaways (DT-008 product page) + +- **Scans:** QR / barcode (simple) **and** ID/IC/NFC cards. Read ~**0.2 s**, range **0–10 cm**. +- **Interfaces:** **Wiegand 26/34, TCP/IP, USB, RS485.** (For our integration: HTTP over TCP/IP.) +- **Power:** 9–16 V DC, 800 mA. **Size:** 86×86×42 mm. **Temp:** −30…70 °C. +- **Wiegand pinout:** Red(power), Black(GND), Green(D0), White(D1), Blue(LED), Yellow(BEEP). +- **Reporting:** "QR Code HTTP GET" — the reader HTTP-GETs a configured host on each scan; the host + replies the verdict (drives beep/output). Vendor ships a **QR Code config tool** + HTTP-GET demo + code (C++/C#/PHP) and an SDK (`QRCode_sdk.zip`). See [[qrcode-sdk]] for the protocol we implement. + +## How we use it + +Host-in-the-loop, synchronous HTTP: reader GETs `/qa/mcardsea.` with its serial (`cjihao`); +our endpoint (`apps/server/src/routes/qr-reader.ts`) decides and replies the SDK verdict, and emits +a `read` event for the access flows. Full integration + the on-hardware findings (the `.jsp` path +extension, `Connection: close` requirement, serial resolution) are in [[dingtian-dt008-reader]]. diff --git a/wiki/sources/gee-qr-er80.md b/wiki/sources/gee-qr-er80.md deleted file mode 100644 index c7dd832..0000000 --- a/wiki/sources/gee-qr-er80.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -type: source -tags: [parking, hardware, readers, qr, datasheet] -sources: [gee-qr-er80] -updated: 2026-06-16 ---- - -# Source: GEE-QR-ER80 QR Code Access Control Reader (datasheet) - -Vendor datasheet (GEE NFC LIMITED, ©2007–2019) for the **GEE-QR-ER80** — a static -**QR-code access-control reader**, optional ID/IC card. The reader the project has -on hand for the [[ticket-encoding|QR ticket]] path. Raw: -`raw/GEE-QR-ER80 QR Code Access Control Reader.pdf` (3 pages). Entity: [[gee-qr-er80]]. - -## Key takeaways - -- **Optical scanner**, not a prox-card reader: reads **QR, DataMatrix, 1D barcode** (static). - Optional add-ons for **IC card UID / ID card**. -- **Multi-interface:** **Wiegand 26/34, RS-232, RS-485, USB, TCP/IP** — selectable by variant. -- **Power:** 4–15 VDC, < 800 mA. **Read direction:** 360°. Built-in scanner LED. -- **OS:** Windows XP/7/8/10 **and Linux** (explicit) — fits the [[disk-os-hardening|Linux appliance]]. -- **Wiring (Wiegand/RS-232/485 variant):** VCC(+12V), GND, **D0/D1** (Wiegand), **TX/R+ , RX/R-** - (RS-232 / RS-485), plus **LED** and **BEEP** control lines (host can drive feedback). -- **Order code** `GEE-QR-ER80--`: `Q`=QR scanner / `D`=ID reader / `C`=IC reader; - `W`=WG·RS232·RS485 / `U`=USB / `T`=RJ45 (TCP/IP). **On hand: `-Q-W`** (QR scanner; Wiegand/RS-232/RS-485). - -## Section map - -- p1 — overview, physical + feature table (interfaces, power, read direction). -- p2 — supported types (QR/DM/1D + optional IC/ID), OS, environment; **wire definition** (pin table). -- p3 — order-code breakdown, applications (access control / vacation rentals / time attendance). - -## Not in this datasheet (open) - -- The **RS-232/RS-485 data protocol**: baud rate, frame format, and whether a QR scan is emitted as - an **ASCII string** (expected) vs. some framed protocol. Decides the host-side adapter — see - [[gee-qr-er80]] open questions. Resolve by vendor docs or by observing the port on a scan. diff --git a/wiki/sources/qrcode-sdk.md b/wiki/sources/qrcode-sdk.md index 7d48d78..af8b3eb 100644 --- a/wiki/sources/qrcode-sdk.md +++ b/wiki/sources/qrcode-sdk.md @@ -5,13 +5,13 @@ sources: [qrcode-sdk] updated: 2026-06-16 --- -# Source: QRCode SDK v1.6.5 (GEE/Dingtian QR reader) +# Source: QRCode SDK v1.6.5 (Dingtian DT-008 QR reader) -Vendor SDK for the QR access reader ([[gee-qr-er80]]; also branded Dingtian). Defines the +Vendor SDK for the QR access reader (the Dingtian [[dingtian-dt008-reader]]). Defines the reader↔server **HTTP protocol** — the missing piece the datasheet omitted. Files at `QRCode_sdk - QRCode_v1_6_5/sdk/` (config tool `QRCode_v1_6_5.exe`, demos in C#/PHP/VC++, protocol docs `readme.txt`, `qrcode_HTTP_GET.txt`, `VC++/how to.txt`). **Not copied into `raw/`** — bulky + -binaries; this summary is the faithful capture. Entity: [[gee-qr-er80]]. +binaries; this summary is the faithful capture. Entity: [[dingtian-dt008-reader]]. ## The protocol — HTTP GET poll, server replies the verdict @@ -52,7 +52,7 @@ GET /qa/mcardsea.php?cardid=445D2C&mjihao=1&cjihao=HW256097&status=11&time=15404 This is **host-in-the-loop, synchronous**: the GET *is* the access query; our JSON reply *is* the decision. So the backend endpoint must **decide (valid/invalid + direction) and reply** — richer -than a fire-and-forget read. Direction comes from the `status` low digit. See [[gee-qr-er80]] + +than a fire-and-forget read. Direction comes from the `status` low digit. See [[dingtian-dt008-reader]] + [[device-input-flow]]. ## Defaults / misc