Node.js SDK Overview
The Viewtron Node.js SDK provides one main component:
- ViewtronServer -- an HTTP server that receives AI detection events from Viewtron cameras and NVRs, built on the Node.js EventEmitter pattern
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 Node.js SDK is receive-only. For outbound camera control (device info, plate database CRUD), use the Python SDK.
Installation
npm install viewtron-sdk
Requires Node.js 18.0.0 or later. Installs one dependency: fast-xml-parser (XML parsing).
Quick Start -- Receiving Events
Set up a server that listens for camera HTTP POST 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}`);
}
});
server.start().then(({ port, ip }) => {
console.log(`Listening on ${ip}:${port}`);
});
Configure your camera or NVR to send HTTP POST events to http://\<your-ip>:5050. The server handles persistent connections, keepalive responses, and XML parsing automatically.
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();
Architecture
The SDK has one data flow -- inbound events from cameras to your application.
Camera/NVR --> HTTP POST (XML) --> ViewtronServer --> ViewtronEvent --> your event handler
- You create a
ViewtronServeron a port of your choice. - You configure the camera/NVR to POST events to your server's IP and port.
- The camera maintains a persistent HTTP/1.1 connection and sends keepalives every 30 seconds.
- When an AI detection fires, the camera sends an XML payload containing the event type, metadata, and optionally base64-encoded images.
ViewtronEvent()parses the XML, detects IPC v1.x vs NVR v2.0 format, and returns aViewtronEventobject.- The server emits an
'event'with the parsed event and the camera's IP address.
Keepalives, alarm status messages, traject data, and unrecognized XML are filtered out -- your 'event' handler only receives real detection events.
EventEmitter pattern
ViewtronServer extends Node.js EventEmitter. The server emits five event types:
| Event | Arguments | When |
|---|---|---|
'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 |
No outbound camera control
Unlike the Python SDK (which includes ViewtronCamera for sending commands to cameras), the Node.js SDK is receive-only. It does not control cameras or manage plate databases. If you need outbound control from a Node.js application, use the camera's HTTP API directly or call the Python SDK from a subprocess.
Event Categories
Every event object has a .category string that tells you what type of detection triggered it:
| Category | Description | Example Alarm Types |
|---|---|---|
lpr | License plate recognition | VEHICE (IPC), vehicle (NVR) |
face | Face detection | VFD (IPC), videoFaceDetect (NVR) |
intrusion | Perimeter/zone detection -- line crossing, region intrusion, zone entry/exit, loitering | PEA, AOIENTRY, AOILEAVE, LOITER (IPC), regionIntrusion, lineCrossing (NVR) |
counting | People/vehicle counting by line or area | PASSLINECOUNT, TRAFFIC (IPC), targetCountingByLine, targetCountingByArea (NVR) |
metadata | Video metadata events | VSD (IPC), videoMetadata (NVR) |
traject | Smart tracking -- continuous target position data sent multiple times per second | Traject list data (IPC and NVR) |
Route events using event.category:
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}`);
console.log(`Target: ${event.targetType}, ID: ${event.targetId}`);
break;
case 'face':
// NVR v2.0 provides demographics
if (event.face) {
console.log(`Face: age=${event.face.age}, sex=${event.face.sex}`);
}
break;
case 'counting':
console.log(`Count event: ${event.eventDescription}`);
console.log(`Target type: ${event.targetType}`);
break;
}
});
Note: traject events are filtered out by ViewtronServer by default. They are high-volume (multiple per second) and handled separately. If you need raw traject data, use the ViewtronEvent() factory function directly with the 'raw' event.
IPC vs NVR
Viewtron devices use two different XML API versions:
- IPC (IP Camera) -- v1.x format. Events come directly from the camera. Alarm types are uppercase codes like
VEHICE,VFD,PEA. - NVR (Network Video Recorder) -- v2.0 format. Events are forwarded from cameras connected to the NVR. Alarm types are camelCase strings like
vehicle,videoFaceDetect,regionIntrusion.
You do not need to handle this difference. ViewtronEvent() detects the API version automatically and populates the same properties on the event object. The .category value is the same for both -- "lpr" whether it came from an IPC or NVR. The .source field tells you which format was detected ("IPC" or "NVR").
Where the formats do differ in available data:
| Feature | IPC (v1.x) | NVR (v2.0) |
|---|---|---|
| Plate group | Fixed: whiteList, blackList, temporaryList | User-defined group names (e.g., "Residents") |
| Vehicle attributes | Not available | Brand, color, type, model (via event.vehicle) |
| Plate owner | Not available | event.carOwner from NVR database |
| Face demographics | Not available | Age, sex, glasses, mask (via event.face) |
| Channel ID | N/A (direct connection) | NVR channel number (event.channelId) |
| Target type | Numeric ID mapped to name | String value directly |
Exports
The package exports six items:
const {
ViewtronServer, // HTTP server class (extends EventEmitter)
ViewtronEvent, // Factory function — parseEvent(xml) → ViewtronEvent | null
ViewtronEventClass, // The ViewtronEvent class itself — for instanceof checks
IPC_CATEGORIES, // Map of IPC v1.x smartType codes → category strings
NVR_CATEGORIES, // Map of NVR v2.0 smartType codes → category strings
ALARM_DESCRIPTIONS, // Map of all smartType codes → human-readable descriptions
TARGET_TYPES, // Map of IPC numeric target type IDs → name strings
} = require('viewtron-sdk');
Most applications only need ViewtronServer. The other exports are useful for advanced use cases like building custom parsers or filtering by raw alarm type.
Node.js Requirements
- Node.js 18.0.0 or later
- Dependencies (installed automatically):
fast-xml-parser
What's Next
Detailed reference pages for each component:
- ViewtronServer -- constructor options, EventEmitter events, start/stop, connected camera tracking
- ViewtronEvent -- the factory function, event properties, category routing, what returns null
- LPR Events -- plateNumber, plateGroup, vehicle attributes, IPC vs NVR differences
- Intrusion Events -- perimeter, line crossing, zone entry/exit, loitering, target types
- Face Detection Events -- face demographics (NVR v2.0 only), face crop images
- Counting Events -- people and vehicle counting by line or area
- Images -- extracting overview and target crop images, sourceImageBytes/targetImageBytes Buffers