ViewtronEvent
Overview
ViewtronEvent (exported as the parseEvent function) parses the raw XML from a camera HTTP POST and returns a ViewtronEvent object. It automatically detects whether the source is an IPC (v1.x) or NVR (v2.0) and populates the appropriate fields.
Returns null for keepalive heartbeats, alarm status messages, and unrecognized payloads.
Usage
const { ViewtronEvent } = require('viewtron-sdk');
const event = ViewtronEvent(xmlString);
if (event === null) {
// Keepalive, alarm status, or unrecognized — skip
return;
}
console.log(event.source); // "IPC" or "NVR"
console.log(event.category); // "lpr", "intrusion", "face", etc.
console.log(event.eventType); // Raw smartType code
console.log(event.eventDescription); // Human-readable name
Usually you don't call ViewtronEvent directly -- ViewtronServer calls it internally and passes the result to your 'event' listener. But you can use it standalone if you're building your own HTTP server.
Return Values
Unlike the Python SDK (which returns different classes per event type), the Node.js SDK always returns a single ViewtronEvent object. The category field tells you what type of event it is, and the relevant fields are populated.
| Camera sends... | Returns | source | category |
|---|---|---|---|
| License plate detection (IPC) | ViewtronEvent | "IPC" | "lpr" |
| License plate detection (NVR) | ViewtronEvent | "NVR" | "lpr" |
| Face detection (IPC) | ViewtronEvent | "IPC" | "face" |
| Face detection (NVR) | ViewtronEvent | "NVR" | "face" |
| Perimeter intrusion (IPC) | ViewtronEvent | "IPC" | "intrusion" |
| Zone entry (IPC) | ViewtronEvent | "IPC" | "intrusion" |
| Zone exit (IPC) | ViewtronEvent | "IPC" | "intrusion" |
| Loitering (IPC) | ViewtronEvent | "IPC" | "intrusion" |
| Illegal parking (IPC) | ViewtronEvent | "IPC" | "intrusion" |
| Region intrusion (NVR) | ViewtronEvent | "NVR" | "intrusion" |
| Line crossing (NVR) | ViewtronEvent | "NVR" | "intrusion" |
| Pass line count (IPC) | ViewtronEvent | "IPC" | "counting" |
| Intrusion target count (IPC) | ViewtronEvent | "IPC" | "counting" |
| Counting by line (NVR) | ViewtronEvent | "NVR" | "counting" |
| Counting by area (NVR) | ViewtronEvent | "NVR" | "counting" |
| Video metadata (IPC) | ViewtronEvent | "IPC" | "metadata" |
| Video metadata (NVR) | ViewtronEvent | "NVR" | "metadata" |
| Smart tracking (IPC) | ViewtronEvent | "IPC" | "traject" |
| Smart tracking (NVR) | ViewtronEvent | "NVR" or "NVR-ch3" | "traject" |
| Keepalive heartbeat | null | -- | -- |
| Alarm status message | null | -- | -- |
| Unrecognized payload | null | -- | -- |
Properties
Source and Classification
| Property | Type | Source | Description |
|---|---|---|---|
source | string | Both | "IPC" for cameras, "NVR" for NVRs. Traject events from NVRs include the channel: "NVR-ch3". |
category | string | Both | Event category: "lpr", "face", "intrusion", "counting", "metadata", or "traject" |
eventType | string | Both | Raw smartType code from the XML. IPC uses uppercase ("VEHICE", "PEA", "VFD"), NVR uses camelCase ("vehicle", "regionIntrusion", "videoFaceDetect"). Traject events always use "traject". |
eventDescription | string | Both | Human-readable description (e.g., "License Plate Detection", "Line Crossing", "Smart Tracking") |
IPC eventType values: VEHICE, VEHICLE, VFD, VFD_MATCH, PEA, AOIENTRY, AOILEAVE, LOITER, PVD, VSD, PASSLINECOUNT, TRAFFIC
NVR eventType values: vehicle, videoFaceDetect, regionIntrusion, lineCrossing, targetCountingByLine, targetCountingByArea, videoMetadata
Device Info
| Property | Type | Source | Description |
|---|---|---|---|
cameraName | string | Both | Device or camera name. IPC reads from deviceNo., NVR reads from deviceInfo.deviceName. |
cameraIp | string | NVR | Camera IP address. Only populated by NVR events (from deviceInfo.ip). Empty string for IPC. |
cameraMac | string | NVR | Camera MAC address. Only populated by NVR events (from deviceInfo.mac). Empty string for IPC. |
channelId | string | NVR | NVR channel number (e.g., "1", "3"). Empty string for IPC. |
timestamp | string | Both | Event timestamp from currentTime in the XML. |
LPR Fields
Populated when category === "lpr".
| Property | Type | Source | Description |
|---|---|---|---|
plateNumber | string | Both | Detected license plate text (e.g., "ABC1234"). |
plateColor | string | NVR | Plate color (e.g., "blue", "yellow"). Empty string for IPC. |
plateGroup | string | Both | IPC: fixed values "whiteList", "blackList", or "temporaryList". NVR: user-defined group name from the plate database. |
carOwner | string | NVR | Owner name from the NVR plate database match info. Empty string for IPC or if no match. |
vehicle | object or null | NVR | Vehicle attributes when available, otherwise null. Always null for IPC. |
vehicle object shape:
{
type: "car", // Vehicle type
color: "white", // Vehicle color
brand: "Toyota", // Vehicle brand
model: "Camry" // Vehicle model
}
Face Fields
Populated when category === "face".
| Property | Type | Source | Description |
|---|---|---|---|
face | object or null | NVR | Face attributes when available. Always null for IPC (IPC v1.x sends face events but no attributes). |
face object shape:
{
age: "32", // Estimated age
sex: "male", // "male" or "female"
glasses: "no", // "yes" or "no"
mask: "no" // "yes" or "no"
}
Detection Fields
Populated when category === "intrusion" or category === "counting".
| Property | Type | Source | Description |
|---|---|---|---|
eventId | string | Both | Event identifier from the detection zone. |
targetId | string | Both | Target identifier for tracking across frames. |
targetType | string | Both | IPC: resolved from numeric codes -- "person", "car", "motorcycle". NVR: string directly from XML (e.g., "person", "car"). |
status | string | IPC | Detection status (e.g., "SMART_START", "SMART_PROCEDURE", "SMART_STOP"). Empty string for NVR. |
boundary | string | NVR | Boundary coordinates for intrusion/counting zones. Empty string for IPC. |
Traject Fields
Populated when category === "traject".
| Property | Type | Source | Description |
|---|---|---|---|
targets | array or null | Both | Array of tracked targets currently in frame. null for non-traject events. |
Each target in the array:
{
targetId: "1", // Target identifier
targetType: "person", // "person", "car", "motorcycle"
velocity: "3", // Movement speed
direction: "45", // Movement direction in degrees
rect: {
x1: "100", // Bounding box coordinates
y1: "200",
x2: "300",
y2: "400"
}
}
Image Fields
| Property | Type | Source | Description |
|---|---|---|---|
sourceImage | string | Both | Base64-encoded JPEG of the full camera frame (overview image). Empty string if not included. |
targetImage | string | Both | Base64-encoded JPEG of the cropped detection target (plate, face, person). Empty string if not included. |
sourceImageBytes | Buffer or null | Both | Lazy getter -- decodes sourceImage to a Buffer on first access. Returns null if no source image. |
targetImageBytes | Buffer or null | Both | Lazy getter -- decodes targetImage to a Buffer on first access. Returns null if no target image. |
hasImages | boolean | Both | true if either sourceImage or targetImage contains data. |
sourceImageBytes and targetImageBytes are computed properties (getters). The base64-to-Buffer decoding happens once on first access and is cached.
// Save a plate crop to disk
if (event.targetImageBytes) {
fs.writeFileSync('plate.jpg', event.targetImageBytes);
}
Raw Data
| Property | Type | Source | Description |
|---|---|---|---|
xml | string | Both | The complete raw XML string from the camera. Useful for debugging or when you need fields the SDK doesn't parse. |
Category Routing
The recommended pattern for handling events by type:
server.on('event', (event, clientIP) => {
switch (event.category) {
case 'lpr':
console.log(`Plate: ${event.plateNumber} (${event.plateGroup})`);
if (event.vehicle) {
console.log(`Vehicle: ${event.vehicle.brand} ${event.vehicle.model}`);
}
break;
case 'intrusion':
console.log(`Intrusion: ${event.eventDescription}`);
console.log(`Target: ${event.targetType}, ID: ${event.targetId}`);
break;
case 'face':
if (event.face) {
console.log(`Face: age ${event.face.age}, ${event.face.sex}`);
}
break;
case 'counting':
console.log(`Count: ${event.eventDescription}`);
break;
case 'traject':
console.log(`Tracking ${event.targets.length} targets`);
for (const t of event.targets) {
console.log(` ${t.targetType} #${t.targetId}`);
}
break;
}
});
IPC vs NVR Detection
ViewtronEvent automatically detects the source format by checking the XML API version attribute:
- Version starts with
"1"(or no version attribute) -- IPC v1.x format. Setssourceto"IPC". - Version starts with
"2"-- NVR v2.0 format. Setssourceto"NVR".
NVR v2.0 additional filtering: NVR payloads include a messageType field. Only "alarmData" messages are parsed as events. "keepalive" messages return null.
Traject detection: Traject (smart tracking) data is detected early by checking for \<traject type="list" in the raw XML before full parsing. This is a performance optimization since traject data is high-volume. Traject events from NVRs set source to "NVR-ch\{channelId\}" when a channel ID is present.
Your code doesn't need to worry about source detection -- use event.category for routing and the SDK handles the format differences.
Exported Constants
The SDK also exports the lookup tables used for event classification:
const {
IPC_CATEGORIES, // Maps IPC smartType codes to categories
NVR_CATEGORIES, // Maps NVR smartType codes to categories
ALARM_DESCRIPTIONS, // Maps smartType codes to human-readable descriptions
TARGET_TYPES, // Maps IPC numeric target type IDs to strings
} = require('viewtron-sdk');
These are useful if you need to extend the SDK or check which event types are supported.
Related Pages
- LPR Events -- plateNumber, plateGroup, plateColor, vehicle attributes, IPC vs NVR differences
- Intrusion Events -- eventType, targetType, eventId, status, boundary
- Face Detection Events -- face.age, face.sex, face.glasses, face.mask (NVR v2.0 only)
- Counting Events -- line counting, area counting, targetType
- Images -- working with sourceImageBytes and targetImageBytes
- ViewtronServer -- the server that produces these events