fix(reader): correct the QR reader's identity — Dingtian DT-008, not "GEE"
An early wrong assumption named the QR/RFID access reader "GEE" / "GEE/Fondvision" / "GEE-QR-ER80" (and summarized a raw GEE PDF as its datasheet). There is no GEE device — it's the Dingtian DT-008 (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. Code: - Driver symbol geeQrReaderDriver → dingtianQrReaderDriver; label → "Dingtian DT-008 QR/RFID reader (HTTP push)"; comments/description rewritten to the real DT-008 facts (Wiegand 26/34, TCP/IP, USB, RS485 — not RS-232; QR/barcode + ID/IC/NFC — not DataMatrix/1D). - Persisted driverId "gee-qr-reader" → "dingtian-qr-reader" (the registry lookup key + the row created on assign in qr-reader.ts). - Migration 0015 rewrites existing devices.driver_id rows so configured readers keep resolving (applied to the dev DB — 2 rows; the booth applies it on boot). Behaviour is unchanged: naming + the persisted id only. Wiki + memory: - Renamed entities/gee-qr-er80.md → dingtian-dt008-reader.md and sources/gee-qr-er80.md → dingtian-dt008.md; rewrote both to the real DT-008 product-page specs while KEEPING all the verified-on-hardware protocol facts (cjihao serial, .jsp path, Connection: close). Fixed every cross-reference + "GEE" mention in 6 other pages. Memory gee-reader-serial-binding → dingtian-reader-serial-binding. The only surviving "GEE" mentions are deliberate naming-correction notes, the raw PDF filename, and the append-only log history. Full workspace build/lint/test green; dev DB readers verified resolving to the registered dingtian-qr-reader driver. Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { execFile } from "node:child_process";
|
||||
|
||||
// Unprivileged ICMP liveness check for PUSH-only devices that expose no TCP port —
|
||||
// e.g. the Dingtian/GEE QR readers, which GET our backend on each scan but listen on
|
||||
// e.g. the Dingtian DT-008 QR readers, which GET our backend on each scan but listen on
|
||||
// nothing. For those a TCP connect probe (what cameras/printers use) has nothing to
|
||||
// connect to; ICMP echo is the only honest "powered + on-network" signal.
|
||||
//
|
||||
|
||||
@@ -7,7 +7,7 @@ import { stubAccessDriver } from "./access-stub.js";
|
||||
import { dahuaDriver, hikvisionDriver } from "./camera.js";
|
||||
import { cashinoDriver } from "./printer-cashino.js";
|
||||
import { rongtaDriver } from "./printer-rongta.js";
|
||||
import { geeQrReaderDriver, tcpipReaderDriver, wiegandReaderDriver } from "./reader.js";
|
||||
import { dingtianQrReaderDriver, tcpipReaderDriver, wiegandReaderDriver } from "./reader.js";
|
||||
|
||||
let registered = false;
|
||||
|
||||
@@ -19,7 +19,7 @@ export function registerBuiltinDrivers(): void {
|
||||
registry.register(stubAccessDriver);
|
||||
registry.register(wiegandReaderDriver);
|
||||
registry.register(tcpipReaderDriver);
|
||||
registry.register(geeQrReaderDriver);
|
||||
registry.register(dingtianQrReaderDriver);
|
||||
registry.register(hikvisionDriver);
|
||||
registry.register(dahuaDriver);
|
||||
registry.register(rongtaDriver);
|
||||
@@ -31,7 +31,7 @@ export {
|
||||
stubAccessDriver,
|
||||
wiegandReaderDriver,
|
||||
tcpipReaderDriver,
|
||||
geeQrReaderDriver,
|
||||
dingtianQrReaderDriver,
|
||||
hikvisionDriver,
|
||||
dahuaDriver,
|
||||
rongtaDriver,
|
||||
|
||||
@@ -8,7 +8,7 @@ import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
const icmpPing = vi.fn<(host: string, timeoutMs?: number) => Promise<boolean>>();
|
||||
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
|
||||
});
|
||||
|
||||
@@ -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.<ext>) 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.<ext>)
|
||||
// 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),
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@ export {
|
||||
stubAccessDriver,
|
||||
wiegandReaderDriver,
|
||||
tcpipReaderDriver,
|
||||
geeQrReaderDriver,
|
||||
dingtianQrReaderDriver,
|
||||
hikvisionDriver,
|
||||
dahuaDriver,
|
||||
rongtaDriver,
|
||||
|
||||
Reference in New Issue
Block a user