/** * 继电器命令行调试工具 —— 参数化触发按键/配对/原始命令,方便接线调试。 * * 多板:--board N 指定 MODBUS 板号(默认 1)。pair/press 不传时按 config 的 board 字段自动路由。 * * 用法(端口/波特率走 .env 的 SERIAL_PORT/SERIAL_BAUD): * npx ts-node scripts/relay.ts probe --board 1 # 在线探测指定板(读线圈) * npx ts-node scripts/relay.ts status --board 2 # 读 64 路线圈状态 * npx ts-node scripts/relay.ts pair remote # 进配对(板号按 config) * npx ts-node scripts/relay.ts pair meter --hold 2500 # 进配对,覆盖时长 * npx ts-node scripts/relay.ts press remote convex --hold 800 # 点按命名键 * npx ts-node scripts/relay.ts pulse 34,35 --hold 3000 --board 1 # 同时脉冲指定通道 * npx ts-node scripts/relay.ts on 34 --board 2 / off 34 # 单路通/断 * npx ts-node scripts/relay.ts raw 010500050000 # 发原始 16 进制帧(自带 CRC 时勿重复) */ import * as dotenv from 'dotenv'; import * as path from 'path'; dotenv.config({ path: path.resolve(__dirname, '../.env') }); import { SerialController } from '../utils/common/serial_controller'; import { triggerRelayAction, pressButton } from '../utils/common/relay.helper'; function flag(name: string): string | undefined { const i = process.argv.indexOf(`--${name}`); return i >= 0 ? process.argv[i + 1] : undefined; } /** 取位置参数(剔除 --flag 及其紧随的值)。 */ function positionals(): string[] { const argv = process.argv.slice(2); const out: string[] = []; for (let i = 0; i < argv.length; i++) { if (argv[i].startsWith('--')) { i++; // 跳过该 flag 的值 continue; } out.push(argv[i]); } return out; } async function main() { const [cmd, a, b] = positionals(); const hold = flag('hold') ? parseInt(flag('hold') as string, 10) : undefined; const board = flag('board') ? parseInt(flag('board') as string, 10) : undefined; switch (cmd) { case 'probe': { const c = new SerialController(board ? { deviceId: board } : {}); await c.open(); console.log(await c.ping(board)); await c.close(); break; } case 'status': { const c = new SerialController(board ? { deviceId: board } : {}); await c.open(); console.log('status:', (await c.readStatus(board)).toString('hex').toUpperCase()); await c.close(); break; } case 'pair': { if (!a) throw new Error('用法: pair [--hold ms] [--board N]'); await triggerRelayAction(a, 'pairing', { ...(hold ? { holdMs: hold } : {}), ...(board ? { deviceId: board } : {}) }); break; } case 'press': { if (!a || !b) throw new Error('用法: press