@leumas/surveillance-node
Leumas Surveillance edge node — the data plane. Runs the SAME camera-manager media/detector/recorder pipelines near the cameras, pulls its assigned cameras from a control plane over HTTP, and...
@leumas/surveillance-node — Surveillance edge node (data plane)
Runs the Leumas camera-manager pipelines near the cameras and publishes only detection events to a control plane (the Leumas API) — never raw video. This is the horizontal-scale half of the control/data-plane split: each node handles its local cameras; the control plane holds the registry, rules, metering, and event index.
It is not a fork — it imports the identical @leumas/adapter-surveillance pipeline services (streams/media/detector/recorder, which are connector-free) and orchestrates them against cameras it pulls over HTTP. The API's own in-process sidecars are the "built-in node" for a single-box / EXE install, so small deployments need no separate node at all.
Run
SURVEILLANCE_CONTROL_PLANE_URL=https://studio.example.com \
SURVEILLANCE_NODE_TOKEN=<shared node token> \
SURVEILLANCE_INGEST_TOKEN=<shared ingest token> \
SURVEILLANCE_NODE_TENANT=<tenant slug> \
SURVEILLANCE_NODE_ID=lobby-box-1 \
node bin/leumas-surveillance-node.js
Assign cameras to a node by setting each camera's nodeId to the node's SURVEILLANCE_NODE_ID (cameras with no nodeId stay on the control-plane built-in node). The node:
- registers (
POST /api/surveillance/node/register), - pulls its assigned cameras (
GET /api/surveillance/node/cameras), - runs
ensureStreams+ensureDetections+reconcileRecordinglocally (the local sidecar posts
detections to the control plane's /ingest), and
- heartbeats (
POST /api/surveillance/node/heartbeat) — all on a periodic reconcile loop.
Deploy
Ship it self-contained with pnpm deploy --filter @leumas/surveillance-node <dir> (same discipline as the API EXE). It needs ffmpeg + mediamtx + the Python detection extras on the box to actually run detection; without them it registers, pulls, and heartbeats (wiring stays verifiable), and detection is a clean no-op.
Auth
Phase 4 uses a shared SURVEILLANCE_NODE_TOKEN (loopback-only if unset) — fine for a single-tenant appliance. Phase 5 upgrades node auth to signed, revocable per-fleet licenses (@leumas/licensing) for safe multi-tenant cloud, without changing these routes or this client.