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) andTRAFFIC(area/intrusion count) - NVR v2.0 --
targetCountingByLine(line count) andtargetCountingByArea(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
| eventType | eventDescription | Description |
|---|---|---|
PASSLINECOUNT | 'Line Crossing Target Count' | Targets crossing a counting line |
TRAFFIC | 'Intrusion Target Count' | Targets counted in a zone |
NVR v2.0 Event Types
| eventType | eventDescription | Description |
|---|---|---|
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
| Value | Meaning |
|---|---|
'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
| Feature | IPC v1.x | NVR v2.0 |
|---|---|---|
| Line counting | PASSLINECOUNT | targetCountingByLine |
| Area counting | TRAFFIC (zone-based) | targetCountingByArea |
| Target type | Numeric ID in XML, SDK maps to string | String directly from \<targetListInfo> |
| Event/target IDs | Not available | From \<eventInfo> block |
| Boundary type | Not available | From \<eventInfo> block |
| Channel ID | Not available | channelId property |
| Device IP / MAC | Not available | cameraIp, cameraMac properties |
| Images | Yes | Yes |
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;
}
});
Related Pages
- ViewtronEvent -- common properties and category routing
- Images -- working with event images (sourceImageBytes, targetImageBytes, hasImages)
- API Reference: Line Counting -- raw XML endpoint documentation, counting zone configuration