Skip to main content

Counting Events

Overview

Counting events are generated when cameras count people or vehicles crossing a line or entering an area. All counting events have category === 'counting'.

Two API versions produce counting events:

  • IPC v1.x -- PASSLINECOUNT (line crossing count) and TRAFFIC (area/intrusion count)
  • NVR v2.0 -- targetCountingByLine (line count) and targetCountingByArea (area count)

Events arrive through ViewtronServer's 'event' emitter like any other category. The parseEvent() factory returns a ViewtronEvent object with the same interface regardless of source.

Event Types

IPC v1.x Event Types

eventTypeeventDescriptionDescription
PASSLINECOUNT'Line Crossing Target Count'Targets crossing a counting line
TRAFFIC'Intrusion Target Count'Targets counted in a zone

NVR v2.0 Event Types

eventTypeeventDescriptionDescription
targetCountingByLine'Target Counting by Line'Targets crossing a counting line
targetCountingByArea'Target Counting by Area'Targets counted in a defined area

NVR v2.0 adds area counting (targetCountingByArea), which IPC v1.x does not support as a distinct event type.

Properties

Every counting event includes the common ViewtronEvent properties (source, category, cameraName, timestamp, etc.) plus the fields below.

eventType

The raw smartType value from the camera XML.

Type: string

event.eventType  // 'PASSLINECOUNT', 'TRAFFIC', 'targetCountingByLine', 'targetCountingByArea'

eventDescription

Human-readable label for the event type.

Type: string

event.eventDescription  // 'Line Crossing Target Count', 'Target Counting by Line', etc.

targetType

What the camera counted. IPC cameras send numeric IDs that the SDK maps to strings. NVR sends strings directly.

Type: string

ValueMeaning
'person'Person counted
'car'Car counted
'motorcycle'Motorcycle or bicycle counted
event.targetType  // 'person', 'car', 'motorcycle'

IPC mapping: 1 = 'person', 2 = 'car', 4 = 'motorcycle'. The SDK handles this conversion automatically.

eventId

NVR only. Identifier for the counting event.

Type: string

event.eventId  // e.g., '1'

IPC counting events do not populate this field. It will be an empty string.

targetId

NVR only. Identifier for the tracked target within the event.

Type: string

event.targetId  // e.g., '5'

IPC counting events do not populate this field. It will be an empty string.

boundary

NVR only. The type of counting boundary.

Type: string

event.boundary  // e.g., 'line', 'area'

IPC counting events do not populate this field. It will be an empty string.

IPC vs NVR Comparison

FeatureIPC v1.xNVR v2.0
Line countingPASSLINECOUNTtargetCountingByLine
Area countingTRAFFIC (zone-based)targetCountingByArea
Target typeNumeric ID in XML, SDK maps to stringString directly from \<targetListInfo>
Event/target IDsNot availableFrom \<eventInfo> block
Boundary typeNot availableFrom \<eventInfo> block
Channel IDNot availablechannelId property
Device IP / MACNot availablecameraIp, cameraMac properties
ImagesYesYes

Code Examples

Basic Count Handling

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

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

server.on('event', (event, clientIP) => {
if (event.category === 'counting') {
console.log(`${event.eventDescription} on ${event.cameraName}`);
console.log(` Target type: ${event.targetType || 'unknown'}`);
}
});

server.start();

Filtering Line vs Area Counting

server.on('event', (event, clientIP) => {
if (event.category !== 'counting') return;

switch (event.eventType) {
case 'PASSLINECOUNT':
case 'targetCountingByLine':
console.log('Line crossing count');
break;
case 'TRAFFIC':
case 'targetCountingByArea':
console.log('Area count');
break;
}
});

Distinguishing IPC vs NVR

server.on('event', (event, clientIP) => {
if (event.category !== 'counting') return;

if (event.source === 'NVR') {
// NVR v2.0 — has channel ID and event info
console.log(`NVR ch${event.channelId}: ${event.eventDescription}`);
console.log(` Event ID: ${event.eventId}, Target ID: ${event.targetId}`);
} else {
// IPC v1.x — target type available, no event IDs
console.log(`IPC: ${event.eventDescription}`);
console.log(` Target type: ${event.targetType}`);
}
});

Saving Images

const fs = require('fs');

server.on('event', (event, clientIP) => {
if (event.category !== 'counting') return;
if (!event.hasImages) return;

const ts = Date.now();

if (event.sourceImageBytes) {
fs.writeFileSync(`count_${ts}.jpg`, event.sourceImageBytes);
}

if (event.targetImageBytes) {
fs.writeFileSync(`count_target_${ts}.jpg`, event.targetImageBytes);
}
});

Combined with Other Event Types

server.on('event', (event, clientIP) => {
switch (event.category) {
case 'lpr':
console.log(`Plate: ${event.plateNumber}`);
break;
case 'intrusion':
console.log(`Intrusion: ${event.eventDescription}`);
break;
case 'counting':
console.log(`Count: ${event.eventDescription} (${event.targetType})`);
break;
}
});