Node.js/TypeScript driver and test CLI for YC-series lock control boards (Eboxlock), spoken over a USB-to-RS485 adapter.
Implements the vendor "Protocol for integration": framed messages with SOF
57 4B 4C 59, length, board address, command word, data, and an XOR checksum.
Hardware model: each channel is a single output that may drive a lock or a
light. open (0x82) powers the channel for a fixed period — a timed pulse.
set <ch> on|off (0x88/0x89) holds the channel continuously on or off — e.g. an
LED. The board also reports manual status changes (0x85), which monitor
surfaces.
npm installnpm install compiles the TypeScript to dist/ automatically (via the prepare
script), so the eboxlock bin and library entry points work straight away — this
also covers installing it as a git dependency. Native serialport bindings are
built on install. Node 18+.
npm run cli -- --port <path> [options] <command> [args]
# or, once published/linked:
eboxlock --port <path> [options] <command> [args]Options: --port/-p <path>, --board/-b <n> (default 0), --baud <n>
(default 9600), --timeout <ms> (default 500).
Commands:
Each channel is a single output that may drive a lock or a light.
| Command | Protocol | Action |
|---|---|---|
open <ch> |
0x82 | Pulse the channel for a fixed period (opens a lock) |
open-all |
0x86 | Pulse every channel |
open-multi <ch...> |
0x87 | Pulse several channels |
set <ch> on|off |
0x88/0x89 | Hold the channel continuously on/off (e.g. an LED) |
status <ch> |
0x83 | Read one channel's status |
status-all |
0x84 | Read all channels' status |
monitor |
0x85 | Report manual status changes from the board (Ctrl-C to stop) |
raw <cmd> [data...] |
— | Send raw body bytes (hex), print the response |
list-ports |
— | List available serial ports |
eboxlock list-ports
eboxlock -p /dev/tty.usbserial-A50285BI open 1
eboxlock -p /dev/tty.usbserial-A50285BI open 1 --retries 3 # retry until confirmed open
eboxlock -p /dev/tty.usbserial-A50285BI set 3 on
eboxlock -p /dev/tty.usbserial-A50285BI status-all
eboxlock -p /dev/tty.usbserial-A50285BI -b 2 open-multi 1 2 3
eboxlock -p /dev/tty.usbserial-A50285BI monitor
eboxlock -p /dev/tty.usbserial-A50285BI raw 82 01 # open ch1 by raw bytesExit code is 0 on a success status byte, 1 on a failure status, 2 on a
usage error.
Install it as a dependency and import from the package root (ESM, with bundled type declarations):
npm install node-eboxlockimport { SerialPort } from 'serialport';
import { EboxlockClient } from 'node-eboxlock';
const port = new SerialPort({ path: '/dev/tty.usbserial-XXX', baudRate: 9600 });
const client = new EboxlockClient(port, { boardAddr: 0 });
await client.openLock(1); // timed pulse on the channel
await client.setChannel(3, true); // hold channel 3 on continuously
const all = await client.statusAll();// { totalChannels, lockStatuses, ... }
// Open and retry every 500ms until the board confirms the lock is open.
// maxRetries = extra attempts after the first; throws if never confirmed.
await client.openLockConfirmed(1, { maxRetries: 3, intervalMs: 500 });
client.on('statusChange', (e) => console.log(e.channel, e.lockStatus));The pure protocol codec lives in src/protocol.ts (frame build/parse, checksum,
command builders, response decoders) and has no I/O dependency. Everything in
protocol.ts and client.ts is re-exported from the package root; EboxlockClient
accepts any duplex PortLike, so you can supply a transport other than
serialport if needed.
npm run build # emits ESM + .d.ts to dist/ (tsc -p tsconfig.build.json)
npm pack # preview the publishable tarball (dist/ + README only)The package is ESM-only. exports/types point at dist/, and the
eboxlock bin resolves to the compiled dist/cli.js. The build runs
automatically on npm install (prepare) and before publish (prepublishOnly
cleans dist/ first, then prepare rebuilds it).
npm run demoDrives the client against an in-memory spec-compliant board simulator
(test/fakeBoard.ts) and prints the exchange.
npm test # 41 tests: protocol codec, transport, full round-trip
npm run typecheckProtocol tests assert against every worked example in the vendor PDF; integration tests run the real client against the fake board for a complete request→response loop.
src/protocol.ts pure protocol: framing, checksum, builders, decoders
src/client.ts EboxlockClient — request/response over a serial port
src/cli.ts one-shot subcommand CLI
test/fakeBoard.ts spec-compliant board simulator (used by demo + tests)
examples/demo.ts hardware-free demo
docs/superpowers/specs/ design spec