Skip to main content

Viewtron Node.js SDK

The Viewtron Node.js SDK (npm install viewtron-sdk) is the recommended way to receive AI detection events from Viewtron cameras and NVRs in a Node.js application. It provides one main component:

  • ViewtronServer — an HTTP server, built on the Node.js EventEmitter pattern, that receives camera webhook events, handles persistent connections and keepalives, and parses each payload into a typed event object.

Both IPC (IP camera, v1.x API) and NVR (network video recorder, v2.0 API) formats are handled transparently — your code receives the same event.category values regardless of which device sent the event. The SDK handles all XML parsing, API version differences, HTTP connection management, and keepalive responses automatically.

The Node.js SDK is receive-only. For outbound camera control (device info, plate database CRUD), use the Python SDK.

Install

npm install viewtron-sdk

Requires Node.js 18.0.0+. Installs one dependency: fast-xml-parser.

Source code: github.com/mikehaldas/viewtron-nodejs-sdk | Full API reference: Node.js SDK Reference

Receiving Events — ViewtronServer

ViewtronServer is a complete HTTP server that receives webhook events from Viewtron cameras. It handles HTTP/1.1 persistent connections, keepalive messages, and XML responses — you just listen for the 'event' events.

const { ViewtronServer } = require('viewtron-sdk');

const server = new ViewtronServer({ port: 5050 });

server.on('event', (event, clientIP) => {
console.log(`[${event.category}] from ${clientIP}`);

if (event.category === 'lpr') {
console.log(` Plate: ${event.plateNumber}`);
console.log(` Group: ${event.plateGroup}`);
}

// Save the full-scene image
if (event.sourceImage) {
require('fs').writeFileSync('overview.jpg', event.sourceImageBytes);
}
});

server.start().then(({ port, ip }) => {
console.log(`Listening on ${ip}:${port}`);
});

Point your camera's HTTP POST at http://<your-server-ip>:5050 and events start flowing. No XML parsing, no base64 decoding, no keepalive handling — the SDK does it all.

ES Module syntax

import { ViewtronServer } from 'viewtron-sdk';

const server = new ViewtronServer({ port: 5050 });

server.on('event', (event, clientIP) => {
console.log(`${event.category} from ${clientIP}`);
});

const { port, ip } = await server.start();
console.log(`Listening on ${ip}:${port}`);

Callback-style options

If you prefer passing callbacks in the constructor instead of using .on():

const server = new ViewtronServer({
port: 5050,
onEvent: (event, clientIP) => {
console.log(event.category, event.plateNumber);
},
onConnect: (clientIP) => {
console.log(`Camera connected: ${clientIP}`);
},
});

server.start();

EventEmitter events

ViewtronServer extends Node.js EventEmitter and emits five event types. Only 'event' fires for real detections — keepalives, alarm status, and traject data are filtered out.

EventArgumentsWhen
'event'(event, clientIP)Parsed ViewtronEvent from a real detection
'connect'(clientIP)First message from a new camera IP
'raw'(xml, clientIP)Raw XML string before parsing (excludes traject)
'listening'({ port, ip })Server started successfully
'error'(err)Server or parsing error

ViewtronEvent — Parse Any Event

If you're building your own HTTP server or processing saved XML, use ViewtronEvent directly. It parses the raw XML, detects IPC v1.x vs NVR v2.0 automatically, and returns a ViewtronEvent object — or null for keepalives, alarm status messages, and unrecognized payloads.

const { ViewtronEvent } = require('viewtron-sdk');

const event = ViewtronEvent(xmlString);
if (event === null) {
return; // keepalive, alarm status, or unrecognized
}

console.log(event.source); // "IPC" or "NVR"
console.log(event.category); // "lpr", "intrusion", "face", "counting", "metadata"
console.log(event.plateNumber); // "ABC1234"
console.log(event.plateGroup); // "whiteList" (IPC) or NVR group name

// Images as decoded JPEG Buffers — ready for saving, MQTT, notifications
const overview = event.sourceImageBytes; // Buffer or null (full scene)
const plateCrop = event.targetImageBytes; // Buffer or null (target closeup)

Routing by category

Every event has a .category string. Route on it:

server.on('event', (event, clientIP) => {
switch (event.category) {
case 'lpr':
console.log(`Plate: ${event.plateNumber} (group: ${event.plateGroup})`);
break;
case 'intrusion':
console.log(`Intrusion: ${event.eventDescription}, target: ${event.targetType}`);
break;
case 'face':
console.log(`Face: ${event.face ? event.face.sex : 'no attributes'}`);
break;
}
});
CategoryDescriptionApplication Guide
lprLicense plate recognition with plate group / vehicle attributesLPR
faceFace detection (with age/sex/glasses/mask on NVR)Face Detection
intrusionLine crossing, region intrusion, zone entry/exit, loiteringHuman Detection · Perimeter Security
countingPeople/vehicle counting by line or areaPeople Counting
metadataContinuous object detectionReal-Time Tracking

Event Properties

Unlike the Python SDK (which returns a different class per event type), the Node.js SDK always returns a single ViewtronEvent object with the relevant fields populated.

Common Fields

PropertyTypeDescription
sourcestring"IPC" for cameras, "NVR" for NVRs
categorystring"lpr", "face", "intrusion", "counting", "metadata", "traject"
eventTypestringRaw smartType code (IPC uppercase e.g. VEHICE, NVR camelCase e.g. vehicle)
eventDescriptionstringHuman-readable description (e.g. "License Plate Detection")
cameraNamestringDevice or camera name
cameraIpstringCamera IP address (NVR events only; empty for IPC)
channelIdstringNVR channel number (NVR only; empty for IPC)
timestampstringEvent timestamp from the XML

LPR Fields (category === "lpr")

PropertyTypeDescription
plateNumberstringDetected plate text
plateGroupstringIPC: "whiteList", "blackList", "temporaryList". NVR: user-defined group name. Empty if not in the database.
plateColorstringPlate color (NVR only)
carOwnerstringOwner name from an NVR plate-database match (NVR only)
vehicleobject | null{ type, color, brand, model } when available (NVR only), else null

Face Fields (category === "face")

PropertyTypeDescription
faceobject | null{ age, sex, glasses, mask } when available (NVR only), else null

Detection Fields (intrusion / counting)

PropertyTypeDescription
eventIdstringEvent identifier from the detection zone
targetIdstringTarget identifier for tracking across frames
targetTypestring"person", "car", "motorcycle"
statusstringIPC detection status (SMART_START, SMART_PROCEDURE, SMART_STOP); empty for NVR

See each application guide for complete working examples.

Images

Most events include JPEG snapshots embedded as base64. The SDK exposes both the raw base64 strings and lazy-decoded Buffer objects.

PropertyTypeDescription
sourceImagestringBase64 full scene, or '' if absent
targetImagestringBase64 target crop, or '' if absent
sourceImageBytesBuffer | nullDecoded full scene (lazy, cached), or null
targetImageBytesBuffer | nullDecoded target crop (lazy, cached), or null
hasImagesbooleantrue if either image is present
const fs = require('fs');

server.on('event', (event) => {
if (event.hasImages) {
if (event.sourceImage) fs.writeFileSync(`${event.timestamp}_source.jpg`, event.sourceImageBytes);
if (event.targetImage) fs.writeFileSync(`${event.timestamp}_target.jpg`, event.targetImageBytes);
}
});

Use the base64 strings (sourceImage / targetImage) directly for a JSON API or an HTML <img> tag; use the Bytes Buffers for writing to disk or sending over a socket. Buffers are decoded once on first access, then cached.

No Outbound Camera Control

The Node.js SDK is receive-only. Unlike the Python SDK's ViewtronCamera class, it does not send commands to cameras or manage plate databases. For outbound control from Node.js, call the camera's HTTP API directly (see the API Reference) or use the Python SDK.

Projects Built with This SDK

ProjectDescription
Node-RED Integrationnode-red-contrib-viewtron — receive camera AI events as Node-RED flow messages using this SDK

Supported Cameras

The SDK works with any Viewtron AI security camera or NVR that supports HTTP POST webhooks. For license plate recognition, use the Viewtron LPR cameras. All Viewtron products are NDAA compliant.

Questions & Development Inquiries

Mike Haldas is available for questions, consultation, and custom software development for Viewtron API related projects. Email details about your project to mike@viewtron.com.