ViewtronEvent
Overview
ViewtronEvent is a factory function that parses the raw XML from a camera HTTP POST and returns a typed event object. It automatically detects whether the source is an IPC (v1.x) or NVR (v2.0) and returns the appropriate class.
Usage
from viewtron import ViewtronEvent
event = ViewtronEvent(xml_string)
if event is None:
# Keepalive, alarm status, or unrecognized — skip
return
print(event.category) # "lpr", "intrusion", "face", etc.
print(event.get_alarm_type()) # Raw smartType code
print(event.get_alarm_description()) # Human-readable name
Usually you don't call ViewtronEvent directly — ViewtronServer calls it internally and passes the result to your on_event callback. But you can use it standalone if you're building your own HTTP server.
Return Values
| Camera sends... | Returns | Category |
|---|---|---|
| License plate detection (IPC) | LPR | "lpr" |
| License plate detection (NVR) | VehicleLPR | "lpr" |
| Face detection (IPC) | FaceDetection | "face" |
| Face detection (NVR) | FaceDetectionV2 | "face" |
| Perimeter intrusion (IPC) | IntrusionDetection | "intrusion" |
| Zone entry (IPC) | IntrusionEntry | "intrusion" |
| Zone exit (IPC) | IntrusionExit | "intrusion" |
| Loitering (IPC) | LoiteringDetection | "intrusion" |
| Illegal parking (IPC) | IllegalParking | "intrusion" |
| Region intrusion (NVR) | RegionIntrusion | "intrusion" |
| Line crossing (NVR) | LineCrossing | "intrusion" |
| Pass line count (IPC) | IntrusionDetection | "counting" |
| Intrusion target count (IPC) | IntrusionDetection | "counting" |
| Counting by line (NVR) | TargetCountingByLine | "counting" |
| Counting by area (NVR) | TargetCountingByArea | "counting" |
| Video metadata (IPC) | VideoMetadata | "metadata" |
| Video metadata (NVR) | VideoMetadataV2 | "metadata" |
| Smart tracking | Traject | "traject" |
| Keepalive heartbeat | None | — |
| Alarm status | None | — |
| Unrecognized | None | — |
Common Properties
All event objects (except Traject) share these properties and methods.
Properties
| Property | Type | Description |
|---|---|---|
category | str | Event category: "lpr", "face", "intrusion", "counting", "metadata", "traject" |
alarm_type | str | Raw smartType code (e.g., "VEHICE", "vehicle", "PEA", "regionIntrusion") |
alarm_description | str | Human-readable description (e.g., "License Plate Recognition") |
ip_cam | str | Camera/device name |
Methods
| Method | Returns | Description |
|---|---|---|
get_alarm_type() | str | Raw smartType code |
get_alarm_description() | str | Human-readable event description |
get_ip_cam() | str | Camera device name |
get_time_stamp() | str | Unix timestamp as string |
get_time_stamp_formatted() | str | Formatted timestamp (e.g., "2026-04-09 15:30:45") |
get_plate_number() | str | Plate text, or "\<NO PLATE EXISTS>" for non-LPR events |
get_ip_address() | str | Camera IP address (if set) |
set_ip_address(ip) | int | Set the camera IP (called by server automatically) |
source_image_exists() | bool | Whether a source (overview) image is attached |
target_image_exists() | bool | Whether a target (cropped) image is attached |
images_exist() | bool | Whether any images are attached |
get_source_image() | str or None | Base64-encoded source image |
get_target_image() | str or None | Base64-encoded target image |
get_source_image_bytes() | bytes or None | Decoded JPEG bytes for source image |
get_target_image_bytes() | bytes or None | Decoded JPEG bytes for target image |
dump_xml() | None | Print raw XML to stdout (debugging) |
dump_json() | None | Print parsed data as JSON to stdout (debugging) |
NVR-only Methods
| Method | Returns | Description |
|---|---|---|
get_channel_id() | str | NVR channel number |
Category Routing
The recommended pattern for handling events by type:
def handle_event(event, client_ip):
if event.category == "lpr":
plate = event.get_plate_number()
group = event.get_plate_group()
print(f"Plate {plate} ({group})")
elif event.category == "intrusion":
print(f"Intrusion: {event.get_alarm_description()}")
elif event.category == "face":
# NVR v2.0 only — check class
if hasattr(event, 'get_face_age'):
print(f"Face: age {event.get_face_age()}, sex {event.get_face_sex()}")
elif event.category == "counting":
print(f"Count event: {event.get_alarm_type()}")
IPC vs NVR Detection
ViewtronEvent automatically detects the source format by checking the XML API version:
- Version starts with
"1"(or no version) -- IPC v1.x classes (LPR,FaceDetection,IntrusionDetection, etc.) - Version starts with
"2"-- NVR v2.0 classes (VehicleLPR,FaceDetectionV2,RegionIntrusion, etc.)
Your code doesn't need to worry about this -- use event.category for routing and the appropriate getter methods.
Related Pages
- LPR Events --
get_plate_number(),get_plate_group(), vehicle attributes, IPC vs NVR differences - Intrusion Events -- perimeter, line crossing, zone entry/exit, loitering
- Face Detection Events -- age, sex, glasses, mask (NVR v2.0 only)
- Counting Events -- line counting, area counting
- Images -- working with event images
- ViewtronServer -- the server that produces these events