1b55e2034d
The Dingtian board's inputs are independent of its relays (configurable), so a button on an input can report to the host WITHOUT auto-firing a relay — solving the access-controller-button-flow blocker the UHPPOTE/ZKTeco couldn't. packages/devices: - access-dingtian.ts: `dingtian` access driver implementing AccessControlDevice (relay pulse/latch via UDP string protocol :60001), InputDevice (read inputs + poll-based press/release events, active-LOW), and the new PreconditionDevice. - PreconditionDevice capability on the interface: a device can report config it requires for parking and optionally fix it. Dingtian checks input_link_relay via the HTTP config API and can disable it. - httpPort config field — the web/config API port is separate from UDP control (this unit uses 8080, not the default 80). - Register dingtian; export driver objects from the package. Verified on real hardware (DT-R004 @ 10.0.10.172): status read, relay pulse, input events; disabled input_link_relay via the driver, then confirmed pressing inputs fires NO relay (0000) — host-in-the-loop entry works. Config-write gotcha recorded: config_set.cgi requires "command":"setconfig" injected after "status" (GET omits it) or the POST silently no-ops. apps/server/scripts/dingtian-test.mjs: status / watch / pulse hardware test. wiki: dingtian-relay verified; button-flow marked RESOLVED; index + log.
74 lines
2.5 KiB
JavaScript
74 lines
2.5 KiB
JavaScript
// Dingtian relay+input hardware test.
|
|
//
|
|
// node apps/server/scripts/dingtian-test.mjs # status only (safe)
|
|
// node apps/server/scripts/dingtian-test.mjs watch # live input/button monitor
|
|
// node apps/server/scripts/dingtian-test.mjs pulse 1 # pulse relay 1 (prompts)
|
|
//
|
|
// Env: DINGTIAN_HOST (default 10.0.10.172), DINGTIAN_PORT (60001).
|
|
//
|
|
// SAFETY: `pulse` fires a relay → the barrier may move. It prompts first unless
|
|
// YES=1. pulseOpen is momentary (the device self-releases).
|
|
|
|
import { createInterface } from "node:readline/promises";
|
|
import { stdin, stdout } from "node:process";
|
|
import { createRequire } from "node:module";
|
|
|
|
const require = createRequire(import.meta.url);
|
|
const { dingtianDriver } = require("@parking/devices");
|
|
|
|
const host = process.env.DINGTIAN_HOST ?? "10.0.10.172";
|
|
const port = process.env.DINGTIAN_PORT ? Number(process.env.DINGTIAN_PORT) : 60001;
|
|
const dev = dingtianDriver.create({ host, port, channels: 4 });
|
|
|
|
const mode = process.argv[2] ?? "status";
|
|
console.log(`dingtian @ ${host}:${port}\n`);
|
|
|
|
async function showStatus() {
|
|
const health = await dev.healthCheck();
|
|
console.log("health:", JSON.stringify(health));
|
|
const inputs = await dev.readInputs();
|
|
console.log("inputs (active=pressed):", inputs.map((v, i) => `in${i + 1}=${v ? "ON" : "off"}`).join(" "));
|
|
for (let ch = 1; ch <= 4; ch++) {
|
|
console.log(`relay ${ch}:`, await dev.getDoorStatus(ch));
|
|
}
|
|
}
|
|
|
|
if (mode === "status") {
|
|
await showStatus();
|
|
process.exit(0);
|
|
}
|
|
|
|
if (mode === "watch") {
|
|
console.log("── press the buttons on the inputs — Ctrl-C to stop ──\n");
|
|
const unsub = dev.onInput((e) => {
|
|
console.log(`[${e.at}] input ${e.input} ${e.edge.toUpperCase()}`);
|
|
});
|
|
process.on("SIGINT", () => {
|
|
unsub();
|
|
console.log("\nstopped.");
|
|
process.exit(0);
|
|
});
|
|
// keep alive
|
|
await new Promise(() => {});
|
|
}
|
|
|
|
if (mode === "pulse") {
|
|
const ch = Number(process.argv[3] ?? 1);
|
|
if (process.env.YES !== "1") {
|
|
const rl = createInterface({ input: stdin, output: stdout });
|
|
const ans = (await rl.question(`Pulse relay ${ch}? (barrier may move) [y/N] `)).trim();
|
|
rl.close();
|
|
if (ans.toLowerCase() !== "y") {
|
|
console.log("aborted.");
|
|
process.exit(0);
|
|
}
|
|
}
|
|
await dev.pulseOpen(ch);
|
|
console.log(`pulsed relay ${ch}.`);
|
|
// show the relay state right after (likely back off — pulse is momentary)
|
|
setTimeout(async () => {
|
|
console.log(`relay ${ch} now:`, await dev.getDoorStatus(ch));
|
|
process.exit(0);
|
|
}, 300);
|
|
}
|