Skip to main content

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 - Device errorCode as 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_version str or None - apiVersion from GetDeviceInfo. When that field is missing, GetDeviceDetail is used.
  • http_post_version str or None - httpPostVersion from GetDeviceInfo, with the same GetDeviceDetail fallback.
  • config_version str or None - version attribute on the device's response \<config> element. Outgoing requests still use config version 2.1.0.
  • supported_apis frozenset 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:

  • host str - Camera IP address (e.g., "192.168.0.20").
  • username str - Camera admin username.
  • password str - Camera admin password.
  • port int - 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 is whiteList, typically group 2. Relying on this default warns once.
  • group - "whiteList" ("allow"), "blackList" ("block"), or "temporaryList" ("temporary"). Matching ignores case. The id is resolved with get_plate_groups(). When set, this overrides group_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 a datetime or a string. A datetime is formatted as YYYY-MM-DD HH:MM:SS. Omitted when None.
  • end_time - Validity end, same forms as begin_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 strings
  • group_id - Numeric group id. Defaults to "1" (the temporary list on current firmware; see add_plate). Relying on this default warns once.
  • group - "whiteList" ("allow"), "blackList" ("block"), or "temporaryList" ("temporary"). Overrides group_id when 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 return
  • offset - 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 is whiteList, typically group 2. Relying on this default warns once.
  • group - "whiteList" ("allow"), "blackList" ("block"), or "temporaryList" ("temporary"). Overrides group_id when 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 with group_id, every group from get_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 when group is set.
  • page_size - Page size sent as maxResult.

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; see add_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"). Overrides group_id when set.
  • card_number - Card number (optional). Appended so existing positional calls stay valid.
  • begin_time - New validity start, datetime or string.
  • end_time - New validity end, datetime or 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 delete
  • group_id - Numeric group id. Defaults to "1" (the temporary list on current firmware; see add_plate). Relying on this default warns once.
  • group - "whiteList" ("allow"), "blackList" ("block"), or "temporaryList" ("temporary"). Overrides group_id when set.

Returns:

True if successful

Raises:

  • ViewtronAPIError - The camera rejected the command.
  • UnsupportedFeature - This firmware has no LicensePlates API.