Table of Contents
viewtron.client
Viewtron Camera Client — send commands to cameras and manage plate databases.
Uses Basic HTTP authentication to communicate with Viewtron IP cameras. Supports license plate CRUD operations and device info queries.
Example:
from viewtron import ViewtronCamera
Viewtron cameras ship set to DHCP. Use the address your router assigned.
camera = ViewtronCamera("192.168.0.20", "admin", "password")
Plate management
camera.add_plate("IB36NL", group="whiteList") plates = camera.get_plates(group="whiteList") camera.modify_plate("IB36NL", owner="Mike", telephone="555-1234", group="whiteList") camera.delete_plate("IB36NL", group="whiteList")
Device info
info = camera.get_device_info()
ViewtronAPIError Objects
class ViewtronAPIError(RuntimeError)
The camera rejected a command or returned an HTTP error.
Subclasses RuntimeError so existing except RuntimeError handlers
still catch API failures.
Attributes:
code- DeviceerrorCodeas a string, when the camera sent one.desc- Short description. For an empty HTTP 400 body this is"Invalid Request (HTTP 400, empty body)".http_status- HTTP status code, or None when the body was HTTP 200 and the failure is an application errorCode.
UnsupportedFeature Objects
class UnsupportedFeature(RuntimeError)
The connected firmware does not provide this command.
Raised when the LicensePlates commands are not available. The older
GetVehiclePlate / AddVehiclePlate command family (listType,
plateItemType, pageIndex, pageSize) is not implemented:
its request and response shape is not confirmed, so this SDK does not
call those commands.
CameraCapabilities Objects
class CameraCapabilities()
What a camera reports about its API.
Attributes:
api_versionstr or None -apiVersionfrom GetDeviceInfo. When that field is missing, GetDeviceDetail is used.http_post_versionstr or None -httpPostVersionfrom GetDeviceInfo, with the same GetDeviceDetail fallback.config_versionstr or None -versionattribute on the device's response\<config>element. Outgoing requests still use config version 2.1.0.supported_apisfrozenset or None - Command names from GetSupportedAPIs. None when that command is not available (Invalid Request or HTTP 400).
ViewtronCamera Objects
class ViewtronCamera()
Client for Viewtron IP camera API with Basic HTTP authentication.
Sends commands to the camera over HTTP. Currently supports license plate database management (CRUD), device info, and capability discovery.
Plate group ids are device-specific. On current firmware (observed on a
camera running 5.3.1, API 2.1.0) group 1 is temporaryList and the
allow list is whiteList, typically group 2. Pass group= with
whiteList (allow), blackList (block), or
temporaryList (temporary). The numeric
group_id argument is still accepted. Omitting both uses "1" and
warns once per process. A future major release will default to
whiteList.
Arguments:
hoststr - Camera IP address (e.g., "192.168.0.20").usernamestr - Camera admin username.passwordstr - Camera admin password.portint - HTTP port (default 80).
Example:
from viewtron import ViewtronCamera
Viewtron cameras ship set to DHCP. Use the address your router assigned.
camera = ViewtronCamera("192.168.0.20", "admin", "password") plates = camera.get_plates(group="whiteList") for plate in plates: print(plate["plate_number"], plate["owner"])
get_device_info
def get_device_info()
Get camera device information.
Returns:
dict with keys like 'deviceName', 'model', 'firmwareVersion', 'apiVersion', and 'httpPostVersion' when the device sends them.
get_supported_apis
def get_supported_apis()
Return the command names advertised by GetSupportedAPIs.
Names are read from applicationInterfaces/item and de-duplicated.
The count attribute is not trusted: devices have been observed
(a camera running 5.3.1 firmware, API 2.1.0) reporting a count that
does not match the number of items, with some names repeated.
Returns:
frozenset of command names, or None when the device answers Invalid Request (errorCode 1) or HTTP 400. None means the command list is unknown (typical of 1.x firmware), not that the device has an empty API.
The result is cached on this instance.
capabilities
@property
def capabilities()
Cached snapshot of api version, HTTP POST version, and commands.
api_version and http_post_version come from GetDeviceInfo.
If either is missing, GetDeviceDetail (detail/property) fills
the gap. config_version is the response \<config version>.
supported_apis is the set from get_supported_apis().
Returns:
CameraCapabilities
get_plate_groups
def get_plate_groups()
Return plate groups as \{id: name\} from GetLicensePlateGroups.
Ids are ints when they are numeric. On current firmware (observed
on a camera running 5.3.1, API 2.1.0) the groups are
1 temporaryList, 2 whiteList, and 3 blackList. Do not
hard-code those ids; call this method.
Returns:
dict mapping group id to group name.
Raises:
UnsupportedFeature- The device has no plate-group command.ViewtronAPIError- The camera returned another error.
add_plate
def add_plate(plate_number,
group_id="1",
group=None,
owner=None,
telephone=None,
card_number=None,
begin_time=None,
end_time=None)
Add a plate to the camera database.
Positional arguments stay plate_number, group_id, group.
Owner, phone, card number, and validity are keyword arguments and
are optional.
AddLicensePlates documents only index, licensePlateNumber,
and groupId. The camera assigns begin and end times. When
owner, telephone, card_number, begin_time, or
end_time is set, this method calls ModifyLicensePlate after
a successful add. Leaving the times unset is the default and lets
the camera assign the validity window. This SDK does not invent a
far-future end date.
beginTime and endTime are not in the ModifyLicensePlate
parameter table. The command description says it updates validity
dates, and the add notes say to use ModifyLicensePlate for
those times, so they are sent with type="string" when provided.
cardNumber is a GetLicensePlates response field and is not
listed on ModifyLicensePlate; it is sent the same way when
provided. licensePlateType is response-only and is not sent.
Arguments:
plate_number- The license plate (e.g., "IB36NL")group_id- Numeric group id. Defaults to"1". On current firmware (observed on a camera running 5.3.1, API 2.1.0) group 1 is the temporary list. The allow list iswhiteList, typically group 2. Relying on this default warns once.group-"whiteList"("allow"),"blackList"("block"), or"temporaryList"("temporary"). Matching ignores case. The id is resolved withget_plate_groups(). When set, this overridesgroup_id.owner- Owner name (carOwner). Omitted when None.telephone- Phone number. Omitted when None.card_number- Card number (cardNumber). Omitted when None.begin_time- Validity start as adatetimeor a string. Adatetimeis formatted asYYYY-MM-DD HH:MM:SS. Omitted when None.end_time- Validity end, same forms asbegin_time.
Returns:
True if successful
Raises:
ViewtronAPIError- The camera rejected the command. The top-level errorCode is checked before the per-item code.UnsupportedFeature- This firmware has no LicensePlates API.
add_plates
def add_plates(plate_numbers, group_id="1", group=None)
Add multiple plates to the camera database.
Arguments:
plate_numbers- List of plate stringsgroup_id- Numeric group id. Defaults to"1"(the temporary list on current firmware; seeadd_plate). Relying on this default warns once.group-"whiteList"("allow"),"blackList"("block"), or"temporaryList"("temporary"). Overridesgroup_idwhen set.
Returns:
True if all successful
Raises:
ViewtronAPIError- The camera rejected the command.UnsupportedFeature- This firmware has no LicensePlates API.
get_plates
def get_plates(max_results=50, offset=1, group_id="1", group=None)
Query one page of the plate database.
Arguments:
max_results- Maximum plates to returnoffset- Starting position (1-based — first plate is offset 1)group_id- Numeric group id. Defaults to"1". On current firmware (observed on a camera running 5.3.1, API 2.1.0) group 1 is the temporary list, so this default does not return allow-list plates. The allow list iswhiteList, typically group 2. Relying on this default warns once.group-"whiteList"("allow"),"blackList"("block"), or"temporaryList"("temporary"). Overridesgroup_idwhen set.
Returns:
List of plate dicts with keys: plate_number, group_id,
begin_time, end_time, owner, telephone, card_number. An empty
database (errorCode 20, Resources Not Exist) returns [].
Raises:
ViewtronAPIError- Any errorCode other than 0 or 20, including Invalid Request (1) and Range Error (16).UnsupportedFeature- This firmware has no LicensePlates API.
get_all_plates
def get_all_plates(group=None, group_id=None, page_size=50)
Return every plate, following resultOffset, maxResult, and total.
Arguments:
group-"whiteList"("allow"),"blackList"("block"), or"temporaryList"("temporary"). When omitted together withgroup_id, every group fromget_plate_groups()is read. That path does not use the"1"default and does not warn.group_id- Numeric group id for a single group. Ignored whengroupis set.page_size- Page size sent asmaxResult.
Returns:
List of plate dicts, in group order then page order.
Raises:
ViewtronAPIError- A page returned an error other than 0 or 20.UnsupportedFeature- This firmware has no LicensePlates API.
get_expiring_plates
def get_expiring_plates(days=7)
Return plates whose validity ends within the next days days.
Built on get_all_plates(), so every group is included. A plate
is included when now \<= end_time \<= now + days. Missing and
unparseable end times are skipped, and plates that have already
expired are not included. Times use YYYY-MM-DD HH:MM:SS or
YYYY-MM-DD.
Arguments:
days- Window length. The default is 7.
Returns:
List of plate dicts from get_all_plates().
modify_plate
def modify_plate(plate_number,
group_id="1",
owner=None,
telephone=None,
group=None,
card_number=None,
begin_time=None,
end_time=None)
Update an existing plate's details.
ModifyLicensePlate documents carOwner and telephone.
beginTime, endTime, and cardNumber are also sent with
type="string" when provided. See add_plate for which of
those fields the parameter table confirms.
Arguments:
plate_number- Plate to modify (must already exist)group_id- Numeric group id. Defaults to"1"(the temporary list on current firmware; seeadd_plate). Relying on this default warns once.owner- New owner name (optional)telephone- New phone number (optional)group-"whiteList"("allow"),"blackList"("block"), or"temporaryList"("temporary"). Overridesgroup_idwhen set.card_number- Card number (optional). Appended so existing positional calls stay valid.begin_time- New validity start,datetimeor string.end_time- New validity end,datetimeor string.
Returns:
True if successful
Raises:
ViewtronAPIError- The camera rejected the command.UnsupportedFeature- This firmware has no LicensePlates API.
delete_plate
def delete_plate(plate_number, group_id="1", group=None)
Delete a plate from the database.
Arguments:
plate_number- Plate to deletegroup_id- Numeric group id. Defaults to"1"(the temporary list on current firmware; seeadd_plate). Relying on this default warns once.group-"whiteList"("allow"),"blackList"("block"), or"temporaryList"("temporary"). Overridesgroup_idwhen set.
Returns:
True if successful
Raises:
ViewtronAPIError- The camera rejected the command.UnsupportedFeature- This firmware has no LicensePlates API.