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;
}
});