devices: stub-access driver (bench-test flows without a relay)
A live QR scan reached the app but rejected: 'reader not on an access-equipped lane' — the dispatcher requires an access device on the reader's lane. Add a no-op stub-access driver (access category, no config) whose pulseOpen only logs and does no device I/O, so the QR->permit->accept flow (incl. the beep) can be tested without the Dingtian relay connected. Not for production; registered in the catalog.
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
import type { AccessControlDevice, DeviceHealth } from "../interfaces.js";
|
||||
import type { AccessDriver, DeviceConfig } from "../registry.js";
|
||||
import { stubLog } from "./common.js";
|
||||
|
||||
// Stub access controller — a no-op barrier for BENCH TESTING the entry/exit/permit
|
||||
// flows without real relay hardware. `pulseOpen` just logs "intent to open"; it
|
||||
// performs no device I/O, so it can stand in on a lane while the real
|
||||
// [[dingtian-relay]] isn't connected. NOT for production. See first-run-setup.md.
|
||||
|
||||
class StubAccess implements AccessControlDevice {
|
||||
readonly driverId = "stub-access";
|
||||
constructor(_config: DeviceConfig) {}
|
||||
async connect(): Promise<void> {}
|
||||
async disconnect(): Promise<void> {}
|
||||
async healthCheck(): Promise<DeviceHealth> {
|
||||
return { status: "ready", detail: "stub (no real barrier)" };
|
||||
}
|
||||
async pulseOpen(doorId: number): Promise<void> {
|
||||
stubLog(this.driverId, `pulseOpen door ${doorId} (stub — no relay fired)`);
|
||||
}
|
||||
async getDoorStatus(): Promise<"open" | "closed"> {
|
||||
return "closed";
|
||||
}
|
||||
}
|
||||
|
||||
export const stubAccessDriver: AccessDriver = {
|
||||
id: "stub-access",
|
||||
category: "access",
|
||||
label: "Stub barrier (bench testing — no relay)",
|
||||
description:
|
||||
"A no-op access controller for testing the flows without hardware. pulseOpen only logs; no relay is fired. Not for production.",
|
||||
transports: ["tcp-ip"],
|
||||
configFields: [],
|
||||
create: (c) => new StubAccess(c),
|
||||
};
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
import { registry } from "../registry.js";
|
||||
import { dingtianDriver } from "./access-dingtian.js";
|
||||
import { stubAccessDriver } from "./access-stub.js";
|
||||
import { dahuaDriver, hikvisionDriver } from "./camera.js";
|
||||
import { rongtaDriver } from "./printer-rongta.js";
|
||||
import { geeQrReaderDriver, tcpipReaderDriver, wiegandReaderDriver } from "./reader.js";
|
||||
@@ -14,6 +15,7 @@ export function registerBuiltinDrivers(): void {
|
||||
if (registered) return;
|
||||
registered = true;
|
||||
registry.register(dingtianDriver);
|
||||
registry.register(stubAccessDriver);
|
||||
registry.register(wiegandReaderDriver);
|
||||
registry.register(tcpipReaderDriver);
|
||||
registry.register(geeQrReaderDriver);
|
||||
@@ -24,6 +26,7 @@ export function registerBuiltinDrivers(): void {
|
||||
|
||||
export {
|
||||
dingtianDriver,
|
||||
stubAccessDriver,
|
||||
wiegandReaderDriver,
|
||||
tcpipReaderDriver,
|
||||
geeQrReaderDriver,
|
||||
|
||||
@@ -11,6 +11,7 @@ export { setDeviceLogSink, type DeviceLogSink } from "./drivers/common.js";
|
||||
export {
|
||||
registerBuiltinDrivers,
|
||||
dingtianDriver,
|
||||
stubAccessDriver,
|
||||
wiegandReaderDriver,
|
||||
tcpipReaderDriver,
|
||||
geeQrReaderDriver,
|
||||
|
||||
+10
@@ -681,3 +681,13 @@ guarantee. Recorded in [[dingtian-relay]] (new Hardening section).
|
||||
matching permit → status:1 + open; re-scan → exit; unknown card → status:0; unassigned serial →
|
||||
status:0. Full build 5/5.
|
||||
- Updated [[gee-qr-er80]] (assignment as-built).
|
||||
|
||||
## [2026-06-16] feature | stub-access driver (bench-test the flows without a relay)
|
||||
- Live QR scan reached the real app (.jsp, serial resolved) but rejected: "reader not on an
|
||||
access-equipped lane" — lane 1 had the reader but no access device. The dispatcher requires an
|
||||
access device on the same lane.
|
||||
- Added a no-op **`stub-access`** driver (access category, no config): `pulseOpen` just logs, no
|
||||
device I/O — stands in on a lane to test QR→permit→accept (incl. the beep) without the
|
||||
[[dingtian-relay]] connected. NOT for production. Registered in the catalog.
|
||||
- To get a live accept: assign Stub barrier to the reader's lane + a permit whose QR = the scanned
|
||||
code → status:1 (2-beep) + logged pulseOpen.
|
||||
|
||||
Reference in New Issue
Block a user