Skip to content

API Reference

API Client (pyunifiprotect.api)

UniFi Protect Server Wrapper.

BaseApiClient

api_request_raw(url: str, method: str = 'get', require_auth: bool = True, raise_exception: bool = True, **kwargs: Any) -> Optional[bytes] async

Make a request to UniFi Protect API

async_connect_ws(force: bool) -> None async

Connect to Websocket.

async_disconnect_ws() -> None async

Disconnect from Websocket.

authenticate() -> None async

Authenticate and get a token.

check_ws() -> bool

Checks current state of Websocket.

close_session() -> None async

Closing and delets client session

ensure_authenticated() -> None async

Ensure we are authenticated.

get_session() -> aiohttp.ClientSession async

Gets or creates current client session

get_websocket() -> Websocket async

Gets or creates current Websocket.

is_authenticated() -> bool

Check to see if we are already authenticated.

request(method: str, url: str, require_auth: bool = False, auto_close: bool = True, **kwargs: Any) -> aiohttp.ClientResponse async

Make a request to UniFi Protect

set_header(key: str, value: str | None) -> None

Set header.

ProtectApiClient

Bases: BaseApiClient

Main UFP API Client

UniFi Protect is a full async application. "normal" use of interacting with it is to call .update() which will initialize the .bootstrap and create a Websocket connection to UFP. This Websocket connection will emit messages that will automatically update the .bootstrap over time. Caling .udpate again (without force) will verify the integry of the Websocket connection.

You can use the .get_ methods to one off pull devices from the UFP API, but should not be used for building an aplication on top of.

All objects inside of .bootstrap have a refernce back to the API client so they can use .save_device() and update themselves using their own .set_ methods on the object.


Text Only
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
host: UFP hostname / IP address
port: UFP HTTPS port
username: UFP username
password: UFP password
verify_ssl: Verify HTTPS certificate (default: `True`)
session: Optional aiohttp session to use (default: generate one)
override_connection_host: Use `host` as your `connection_host` for RTSP stream instead of using the one provided by UniFi Protect.
minimum_score: minimum score for events (default: `0`)
subscribed_models: Model types you want to filter events for WS. You will need to manually check the bootstrap for updates for events that not subscibred.
ignore_stats: Ignore storage, system, etc. stats/metrics from NVR and cameras (default: false)
debug: Use full type validation (default: false)

connection_host: Union[IPv4Address, IPv6Address, str] property

Connection host to use for generating RTSP URLs

adopt_device(model_type: ModelType, device_id: str) -> None async

Adopts a device

calibrate_lock(device_id: str) -> None async

Calibrate the doorlock.

Door must be open and lock unlocked.

center_ptz_camera(device_id: str, *, x: int, y: int, z: int) -> None async

Center PTZ Camera on point in viewport.

x, y, z values range from 0 to 1000.

x, y are relative coords for the current viewport: * (0, 0) is top left * (500, 500) is the center * (1000, 1000) is the bottom right

z value is zoom, but since it is capped at 1000, probably better to use ptz_zoom_camera.

clear_tamper_sensor(device_id: str) -> None async

Clears tamper status for sensor

close_lock(device_id: str) -> None async

Close doorlock (lock)

create_preset_ptz_camera(device_id: str, *, name: str) -> PTZPreset async

Create PTZ Preset for camera based on current camera settings.

delete_preset_ptz_camera(device_id: str, *, slot: int) -> None async

Delete PTZ preset for camera.

get_bootstrap() -> Bootstrap async

Gets bootstrap object from UFP instance

This is a great alternative if you need metadata about the NVR without connecting to the Websocket

get_bridge(device_id: str) -> Bridge async

Gets a bridge straight from the NVR.

The websocket is connected and running, you likely just want to use self.bootstrap.bridges[device_id]

get_bridges() -> list[Bridge] async

Gets the list of bridges straight from the NVR.

The websocket is connected and running, you likely just want to use self.bootstrap.bridges

get_camera(device_id: str) -> Camera async

Gets a camera straight from the NVR.

The websocket is connected and running, you likely just want to use self.bootstrap.cameras[device_id]

get_camera_snapshot(camera_id: str, width: Optional[int] = None, height: Optional[int] = None, dt: Optional[datetime] = None) -> Optional[bytes] async

Gets snapshot for a camera.

Datetime of screenshot is approximate. It may be +/- a few seconds.

get_camera_video(camera_id: str, start: datetime, end: datetime, channel_index: int = 0, validate_channel_id: bool = True, output_file: Optional[Path] = None, iterator_callback: Optional[IteratorCallback] = None, progress_callback: Optional[ProgressCallback] = None, chunk_size: int = 65536, fps: Optional[int] = None) -> Optional[bytes] async

Exports MP4 video from a given camera at a specific time.

Start/End of video export are approximate. It may be +/- a few seconds.

It is recommended to provide a output file or progress callback for larger video clips, otherwise the full video must be downloaded to memory before being written.

Providing the fps parameter creates a "timelapse" export wtih the given FPS value. Protect app gives the options for 60x (fps=4), 120x (fps=8), 300x (fps=20), and 600x (fps=40).

get_cameras() -> list[Camera] async

Gets the list of cameras straight from the NVR.

The websocket is connected and running, you likely just want to use self.bootstrap.cameras

get_chime(device_id: str) -> Chime async

Gets a chime straight from the NVR.

The websocket is connected and running, you likely just want to use self.bootstrap.chimes[device_id]

get_chimes() -> list[Chime] async

Gets the list of chimes straight from the NVR.

The websocket is connected and running, you likely just want to use self.bootstrap.chimes

get_device(model_type: ModelType, device_id: str, expected_type: Optional[type[ProtectModelWithId]] = None) -> ProtectModelWithId async

Gets a device give the device model_type and id, converted into Python object

get_device_raw(model_type: ModelType, device_id: str) -> dict[str, Any] async

Gets a raw device give the device model_type and id

get_devices(model_type: ModelType, expected_type: Optional[type[ProtectModel]] = None) -> list[ProtectModel] async

Gets a device list given a model_type, converted into Python objects

get_devices_raw(model_type: ModelType) -> list[dict[str, Any]] async

Gets a raw device list given a model_type

get_doorlock(device_id: str) -> Doorlock async

Gets a doorlock straight from the NVR.

The websocket is connected and running, you likely just want to use self.bootstrap.doorlocks[device_id]

get_doorlocks() -> list[Doorlock] async

Gets the list of doorlocks straight from the NVR.

The websocket is connected and running, you likely just want to use self.bootstrap.doorlocks

get_event(event_id: str) -> Event async

Gets an event straight from the NVR.

This is a great alternative if the event is no longer in the self.bootstrap.events[event_id] cache

get_event_animated_thumbnail(thumbnail_id: str, width: Optional[int] = None, height: Optional[int] = None, *, speedup: int = 10, retry_timeout: int = RETRY_TIMEOUT) -> Optional[bytes] async

Gets given animated thumbanil from a given event.

Animated thumbnail response is a GIF image.

Note: thumbnails / do not generate until after the event ends. Events that last longer then your retry timeout will always return 404.

get_event_heatmap(heatmap_id: str, retry_timeout: int = RETRY_TIMEOUT) -> Optional[bytes] async

Gets given heatmap from a given event.

Heatmap response is a PNG image.

Note: thumbnails / heatmaps do not generate until after the event ends. Events that last longer then your retry timeout will always return None.

get_event_smart_detect_track(event_id: str) -> SmartDetectTrack async

Gets raw Smart Detect Track for a Smart Detection

get_event_smart_detect_track_raw(event_id: str) -> dict[str, Any] async

Gets raw Smart Detect Track for a Smart Detection

get_event_thumbnail(thumbnail_id: str, width: Optional[int] = None, height: Optional[int] = None, retry_timeout: int = RETRY_TIMEOUT) -> Optional[bytes] async

Gets given thumbanail from a given event.

Thumbnail response is a JPEG image.

Note: thumbnails / heatmaps do not generate until after the event ends. Events that last longer then your retry timeout will always return 404.

get_events(start: Optional[datetime] = None, end: Optional[datetime] = None, limit: Optional[int] = None, offset: Optional[int] = None, types: Optional[list[EventType]] = None, smart_detect_types: Optional[list[SmartDetectObjectType]] = None, sorting: Literal['asc', 'desc'] = 'asc', descriptions: bool = True, category: EventCategories | None = None, _allow_manual_paginate: bool = True) -> list[Event] async

Same as get_events_raw, except

  • returns actual Event objects instead of raw Python dictionaries
  • filers out non-device events
  • filters out events with too low of a score

Text Only
1
2
3
4
5
6
7
8
9
start: start time for events
end: end time for events
limit: max number of events to return
offset: offset to start fetching events from
types: list of EventTypes to get events for
smart_detect_types: Filters the Smart detection types for the events
sorting: sort events by ascending or decending, defaults to ascending (chronologic order)
description: included additional event metadata
category: event category, will provide additional category/subcategory fields

If limit, start and end are not provided, it will default to all events in the last 24 hours.

If start is provided, then end or limit must be provided. If end is provided, then start or limit must be provided. Otherwise, you will get a 400 error from UniFi Protect

get_events_raw(*, start: Optional[datetime] = None, end: Optional[datetime] = None, limit: Optional[int] = None, offset: Optional[int] = None, types: Optional[list[EventType]] = None, smart_detect_types: Optional[list[SmartDetectObjectType]] = None, sorting: Literal['asc', 'desc'] = 'asc', descriptions: bool = True, all_cameras: Optional[bool] = None, category: EventCategories | None = None, _allow_manual_paginate: bool = True) -> list[dict[str, Any]] async

Get list of events from Protect


Text Only
1
2
3
4
5
6
7
8
9
start: start time for events
end: end time for events
limit: max number of events to return
offset: offset to start fetching events from
types: list of EventTypes to get events for
smart_detect_types: Filters the Smart detection types for the events
sorting: sort events by ascending or decending, defaults to ascending (chronologic order)
description: included additional event metadata
category: event category, will provide additional category/subcategory fields

If limit, start and end are not provided, it will default to all events in the last 24 hours.

If start is provided, then end or limit must be provided. If end is provided, then start or limit must be provided. Otherwise, you will get a 400 error from UniFi Protect

get_home_ptz_camera(device_id: str) -> PTZPreset async

Get PTZ home preset (-1).

get_light(device_id: str) -> Light async

Gets a light straight from the NVR.

The websocket is connected and running, you likely just want to use self.bootstrap.lights[device_id]

get_lights() -> list[Light] async

Gets the list of lights straight from the NVR.

The websocket is connected and running, you likely just want to use self.bootstrap.lights

get_liveview(device_id: str) -> Liveview async

Gets a liveview straight from the NVR.

The websocket is connected and running, you likely just want to use self.bootstrap.liveviews[device_id]

get_liveviews() -> list[Liveview] async

Gets the list of liveviews straight from the NVR.

The websocket is connected and running, you likely just want to use self.bootstrap.liveviews

get_nvr() -> NVR async

Gets an NVR object straight from the NVR.

This is a great alternative if you need metadata about the NVR without connecting to the Websocket

get_package_camera_snapshot(camera_id: str, width: Optional[int] = None, height: Optional[int] = None, dt: Optional[datetime] = None) -> Optional[bytes] async

Gets snapshot from the package camera.

Datetime of screenshot is approximate. It may be +/- a few seconds.

get_position_ptz_camera(device_id: str) -> PTZPosition async

Get current PTZ camera position.

get_presets_ptz_camera(device_id: str) -> list[PTZPreset] async

Get PTZ Presets for camera.

get_release_versions() -> set[Version] async

Get all release versions for UniFi Protect

get_sensor(device_id: str) -> Sensor async

Gets a sensor straight from the NVR.

The websocket is connected and running, you likely just want to use self.bootstrap.sensors[device_id]

get_sensors() -> list[Sensor] async

Gets the list of sensors straight from the NVR.

The websocket is connected and running, you likely just want to use self.bootstrap.sensors

get_viewer(device_id: str) -> Viewer async

Gets a viewer straight from the NVR.

The websocket is connected and running, you likely just want to use self.bootstrap.viewers[device_id]

get_viewers() -> list[Viewer] async

Gets the list of viewers straight from the NVR.

The websocket is connected and running, you likely just want to use self.bootstrap.viewers

goto_ptz_camera(device_id: str, *, slot: int = -1) -> None async

Goto PTZ slot position.

-1 is Home slot.

open_lock(device_id: str) -> None async

Open doorlock (unlock)

play_buzzer(device_id: str) -> None async

Plays chime tones on a chime

play_speaker(device_id: str, *, volume: int | None = None, repeat_times: int | None = None) -> None async

Plays chime tones on a chime

reboot_device(model_type: ModelType, device_id: str) -> None async

Reboots an adopted device

reboot_nvr() -> None async

Reboots NVR

relative_move_ptz_camera(device_id: str, *, pan: float, tilt: float, pan_speed: int = 10, tilt_speed: int = 10, scale: int = 0) -> None async

Move PTZ Camera relatively.

Pan/tilt values vary from camera to camera, but for G4 PTZ: * Pan values range from 1 (0°) to 35200 (360°/0°). * Tilt values range from 1 (-20°) to 9777 (90°).

Relative positions cannot move more then 4095 units in either direction at a time.

Camera objects have ptz values in feature flags and the methods on them provide better control.

set_home_ptz_camera(device_id: str) -> PTZPreset async

Set PTZ home preset (-1) to current position.

subscribe_websocket(ws_callback: Callable[[WSSubscriptionMessage], None]) -> Callable[[], None]

Subscribe to websocket events.

Returns a callback that will unsubscribe.

unadopt_device(model_type: ModelType, device_id: str) -> None async

Unadopt/Unmanage adopted device

update(force: bool = False) -> Optional[Bootstrap] async

Updates the state of devices, initalizes .bootstrap and connects to UFP Websocket for real time updates

You can use the various other get_ methods if you need one off data from UFP

update_device(model_type: ModelType, device_id: str, data: dict[str, Any]) -> None async

Sends an update for a device back to UFP

USE WITH CAUTION, all possible combinations of updating objects have not been fully tested. May have unexpected side effects.

Tested updates have been added a methods on applicable devices.

update_nvr(data: dict[str, Any]) -> None async

Sends an update for main UFP NVR device

USE WITH CAUTION, all possible combinations of updating objects have not been fully tested. May have unexpected side effects.

Tested updates have been added a methods on applicable devices.

zoom_ptz_camera(device_id: str, *, zoom: float, speed: int = 10) -> None async

Zoom PTZ Camera.

Zoom levels vary from camera to camera, but for G4 PTZ it goes from 0 (1x) to 2010 (22x).

Zoom speed does not seem to do much, if anything.

Camera objects have ptz values in feature flags and the methods on them provide better control.

Data Models (pyunifiprotect.data)

Bootstrap

Bases: ProtectBaseObject

has_media: bool property

Checks if user can read media for any camera.

has_smart_detections: bool property

Check if any camera has smart detections.

recording_start: datetime | None property

Get earilest recording date.

get_device_from_id(device_id: str) -> ProtectAdoptableDeviceModel | None

Retrieve a device from device ID (without knowing model type).

get_device_from_mac(mac: str) -> ProtectAdoptableDeviceModel | None

Retrieve a device from MAC address.

get_is_prerelease() -> bool async

Get if current version of Protect is a prerelease version.

refresh_device(model_type: ModelType, device_id: str) -> None async

Refresh a device in the bootstrap.

Camera

Bases: ProtectMotionDeviceModel

active_audio_detect_types: set[SmartDetectAudioType] property

Get active audio detection types.

active_recording_settings: RecordingSettings property

Get active recording settings.

active_smart_detect_settings: SmartDetectSettings property

Get active smart detection settings.

active_smart_detect_types: set[SmartDetectObjectType] property

Get active smart detection types.

can_manage_face_detections: bool property

Can this camera manage its own face detection settings?

can_manage_license_plate_detections: bool property

Can this camera manage its own license plate settings?

can_manage_recording_setting: bool property

Can this camera manage its own recording settings?

can_manage_smart_detections: bool property

Can this camera manage its own recording settings?

hdr_mode_display: Literal['auto', 'off', 'always'] property

Get HDR mode similar to how Protect interface works.

icr_lux_display: int | None property

Get ICR Custom Lux value similar to how the Protect interface works.

is_animal_currently_detected: bool property

Is animal currently being detected

is_animal_detection_on: bool property

Is Animal Detection available and enabled (camera will produce package smart detection events)?

is_audio_currently_detected: bool property

Is audio detection currently being detected

is_baby_cry_currently_detected: bool property

Is Baby Cry currently being detected

is_baby_cry_detection_on: bool property

Is Baby Cry Detection available and enabled (camera will produce baby cry smart detection events)?

is_bark_currently_detected: bool property

Is Bark currently being detected

is_bark_detection_on: bool property

Is Bark Detection available and enabled (camera will produce barking smart detection events)?

is_car_alarm_currently_detected: bool property

Is Car Alarm currently being detected

is_car_alarm_detection_on: bool property

Is Car Alarm Detection available and enabled (camera will produce car alarm smart detection events)?

is_car_horn_currently_detected: bool property

Is Car Horn currently being detected

is_car_horn_detection_on: bool property

Is Car Horn Detection available and enabled (camera will produce car horn smart detection events)?

is_cmonx_currently_detected: bool property

Is CO alarm currently being detected

is_co_detection_on: bool property

Is CO Alarm Detection available and enabled (camera will produce smoke smart detection events)?

is_face_detections_allowed: bool property

Is face detections allowed for this camera?

is_glass_break_currently_detected: bool property

Is Glass Break currently being detected

is_glass_break_detection_on: bool property

Is Glass Break available and enabled (camera will produce glass break smart detection events)?

is_ir_led_slider_enabled: bool property

Return if IR LED custom slider is enabled.

is_license_plate_currently_detected: bool property

Is license plate currently being detected

is_license_plate_detection_on: bool property

Is License Plate Detection available and enabled (camera will produce face license plate detection events)?

is_license_plate_detections_allowed: bool property

Is license plate detections allowed for this camera?

is_motion_currently_detected: bool property

Is motion currently being detected

is_motion_detection_on: bool property

Is Motion Detection available and enabled (camera will produce motion events)?

is_package_currently_detected: bool property

Is package currently being detected

is_package_detection_on: bool property

Is Package Detection available and enabled (camera will produce package smart detection events)?

is_person_currently_detected: bool property

Is person currently being detected

is_person_detection_on: bool property

Is Person Detection available and enabled (camera will produce person smart detection events)?

is_person_tracking_enabled: bool property

Is person tracking enabled

is_recording_enabled: bool property

Is recording footage/events from the camera enabled?

If recording is not enabled, cameras will not produce any footage, thumbnails, motion/smart detection events.

is_siren_currently_detected: bool property

Is Siren currently being detected

is_siren_detection_on: bool property

Is Siren Detection available and enabled (camera will produce siren smart detection events)?

is_smart_currently_detected: bool property

Is smart detection currently being detected

is_smart_detections_allowed: bool property

Is smart detections allowed for this camera?

is_smoke_currently_detected: bool property

Is smoke alarm currently being detected

is_smoke_detection_on: bool property

Is Smoke Alarm Detection available and enabled (camera will produce smoke smart detection events)?

is_speaking_currently_detected: bool property

Is Speaking currently being detected

is_speaking_detection_on: bool property

Is Speaking Detection available and enabled (camera will produce speaking smart detection events)?

is_vehicle_currently_detected: bool property

Is vehicle currently being detected

is_vehicle_detection_on: bool property

Is Vehicle Detection available and enabled (camera will produce vehicle smart detection events)?

last_animal_detect: Optional[datetime] property

Get the last animal smart detection event.

last_animal_detect_event: Optional[Event] property

Get the last animal smart detection event.

last_baby_cry_detect: Optional[datetime] property

Get the last Baby Cry smart detection event.

last_baby_cry_detect_event: Optional[Event] property

Get the last Baby Cry smart detection event.

last_bark_detect: Optional[datetime] property

Get the last Bark smart detection event.

last_bark_detect_event: Optional[Event] property

Get the last Bark smart detection event.

last_car_alarm_detect: Optional[datetime] property

Get the last Car Alarm smart detection event.

last_car_alarm_detect_event: Optional[Event] property

Get the last Car Alarm smart detection event.

last_car_horn_detect: Optional[datetime] property

Get the last Car Horn smart detection event.

last_car_horn_detect_event: Optional[Event] property

Get the last Car Horn smart detection event.

last_cmonx_detect: Optional[datetime] property

Get the last CO alarm smart detection event.

last_cmonx_detect_event: Optional[Event] property

Get the last CO alarm smart detection event.

last_glass_break_detect: Optional[datetime] property

Get the last Glass Break smart detection event.

last_glass_break_detect_event: Optional[Event] property

Get the last Glass Break smart detection event.

last_license_plate_detect: Optional[datetime] property

Get the last license plate smart detection event.

last_license_plate_detect_event: Optional[Event] property

Get the last license plate smart detection event.

last_package_detect: Optional[datetime] property

Get the last package smart detection event.

last_package_detect_event: Optional[Event] property

Get the last package smart detection event.

last_person_detect: Optional[datetime] property

Get the last person smart detection event.

last_person_detect_event: Optional[Event] property

Get the last person smart detection event.

last_siren_detect: Optional[datetime] property

Get the last Siren smart detection event.

last_siren_detect_event: Optional[Event] property

Get the last Siren smart detection event.

last_smart_audio_detect_event: Optional[Event] property

Get the last smart audio detect event id.

last_smart_detect_event: Optional[Event] property

Get the last smart detect event id.

last_smoke_detect: Optional[datetime] property

Get the last smoke smart detection event.

last_smoke_detect_event: Optional[Event] property

Get the last person smart detection event.

last_speaking_detect: Optional[datetime] property

Get the last Speaking smart detection event.

last_speaking_detect_event: Optional[Event] property

Get the last Speaking smart detection event.

last_vehicle_detect: Optional[datetime] property

Get the last vehicle smart detection event.

last_vehicle_detect_event: Optional[Event] property

Get the last vehicle smart detection event.

create_ptz_preset(*, name: str) -> PTZPreset async

Create PTZ Preset for camera based on current camera settings.

create_talkback_stream(content_url: str, ffmpeg_path: Optional[Path] = None) -> TalkbackStream

Creates a subprocess to play audio to a camera through its speaker.

Requires ffmpeg to use.


Text Only
1
2
content_url: Either a URL accessible by python or a path to a file (ffmepg's `-i` parameter)
ffmpeg_path: Optional path to ffmpeg binary

Use either await stream.run_until_complete() or await stream.start() to start subprocess command after getting the stream.

.play_audio() is a helper that wraps this method and automatically runs the subprocess as well

delete_ptz_preset(*, slot: int) -> None async

Delete PTZ preset for camera.

get_last_smart_audio_detect_event(smart_type: SmartDetectAudioType) -> Optional[Event]

Get the last smart audio detect event for given type.

get_last_smart_detect_event(smart_type: SmartDetectObjectType) -> Optional[Event]

Get the last smart detect event for given type.

get_package_snapshot(width: Optional[int] = None, height: Optional[int] = None, dt: Optional[datetime] = None) -> Optional[bytes] async

Gets snapshot from the package camera.

Datetime of screenshot is approximate. It may be +/- a few seconds.

get_ptz_home() -> PTZPreset async

Get PTZ home preset (-1).

get_ptz_position() -> PTZPosition async

Get current PTZ Position.

get_ptz_presets() -> list[PTZPreset] async

Get PTZ Presets for camera.

get_snapshot(width: Optional[int] = None, height: Optional[int] = None, dt: Optional[datetime] = None) -> Optional[bytes] async

Gets snapshot for camera.

Datetime of screenshot is approximate. It may be +/- a few seconds.

get_video(start: datetime, end: datetime, channel_index: int = 0, output_file: Optional[Path] = None, iterator_callback: Optional[IteratorCallback] = None, progress_callback: Optional[ProgressCallback] = None, chunk_size: int = 65536, fps: Optional[int] = None) -> Optional[bytes] async

Exports MP4 video from a given camera at a specific time.

Start/End of video export are approximate. It may be +/- a few seconds.

It is recommended to provide a output file or progress callback for larger video clips, otherwise the full video must be downloaded to memory before being written.

Providing the fps parameter creates a "timelapse" export wtih the given FPS value. Protect app gives the options for 60x (fps=4), 120x (fps=8), 300x (fps=20), and 600x (fps=40).

goto_ptz_slot(*, slot: int) -> None async

Goto PTZ slot position.

-1 is Home slot.

play_audio(content_url: str, ffmpeg_path: Optional[Path] = None, blocking: bool = True) -> None async

Plays audio to a camera through its speaker.

Requires ffmpeg to use.


Text Only
1
2
3
content_url: Either a URL accessible by python or a path to a file (ffmepg's `-i` parameter)
ffmpeg_path: Optional path to ffmpeg binary
blocking: Awaits stream completion and logs stdout/stderr

ptz_center(*, x: int, y: int, z: int) -> None async

Center PTZ Camera on point in viewport.

x, y, z values range from 0 to 1000.

x, y are relative coords for the current viewport: * (0, 0) is top left * (500, 500) is the center * (1000, 1000) is the bottom right

z value is zoom, but since it is capped at 1000, probably better to use ptz_zoom.

ptz_relative_move(*, pan: float, tilt: float, pan_speed: int = 10, tilt_speed: int = 10, scale: int = 0, use_native: bool = False) -> None async

Move PTZ relative to current position.

Pan/tilt values vary from camera to camera, but for G4 PTZ: * Pan values range from 0° and go to 360°/0° * Tilt values range from -20° and go to 90°

Relative positions cannot move more then 4095 steps at a time in any direction.

For the G4 PTZ, 4095 steps is ~41° for pan and ~45° for tilt.

use_native lets you use the native step values instead of degrees.

ptz_zoom(*, zoom: float, speed: int = 100, use_native: bool = False) -> None async

Zoom PTZ Camera.

Zoom levels vary from camera to camera, but for G4 PTZ it goes from 1x to 22x.

Zoom speed seems to range from 0 to 100. Any value over 100 results in a speed of 0.

set_animal_detection(enabled: bool) -> None async

Toggles animal smart detection. Requires camera to have smart detection

set_baby_cry_detection(enabled: bool) -> None async

Toggles baby_cry smart detection. Requires camera to have smart detection

set_bark_detection(enabled: bool) -> None async

Toggles bark smart detection. Requires camera to have smart detection

set_camera_zoom(level: int) -> None async

Sets zoom level for camera

set_car_alarm_detection(enabled: bool) -> None async

Toggles car_alarm smart detection. Requires camera to have smart detection

set_car_horn_detection(enabled: bool) -> None async

Toggles car_horn smart detection. Requires camera to have smart detection

set_chime_duration(duration: timedelta | float) -> None async

Sets chime duration for doorbell. Requires camera to be a doorbell

set_chime_type(chime_type: ChimeType) -> None async

Sets chime type for doorbell. Requires camera to be a doorbell

set_cmonx_detection(enabled: bool) -> None async

Toggles smoke smart detection. Requires camera to have smart detection

set_color_night_vision(enabled: bool) -> None async

Sets Color Night Vision on camera

set_glass_break_detection(enabled: bool) -> None async

Toggles glass_break smart detection. Requires camera to have smart detection

set_hdr(enabled: bool) -> None async

Sets HDR (High Dynamic Range) on camera

set_hdr_mode(mode: Literal['auto', 'off', 'always']) -> None async

Sets HDR mode similar to how Protect interface works.

set_icr_custom_lux(value: ICRLuxValue) -> None async

Set ICRCustomValue from lux value.

set_ir_led_model(mode: IRLEDMode) -> None async

Sets IR LED mode on camera

set_lcd_text(text_type: Optional[DoorbellMessageType], text: Optional[str] = None, reset_at: Union[None, datetime, DEFAULT_TYPE] = None) -> None async

Sets doorbell LCD text. Requires camera to be doorbell

set_license_plate_detection(enabled: bool) -> None async

Toggles license plate smart detection. Requires camera to have smart detection

set_mic_volume(level: int) -> None async

Sets the mic sensitivity level on camera

set_motion_detection(enabled: bool) -> None async

Sets motion detection on camera

set_osd_bitrate(enabled: bool) -> None async

Sets whether camera bitrate is in the On Screen Display

set_osd_date(enabled: bool) -> None async

Sets whether current date is in the On Screen Display

Sets whether the UniFi logo is in the On Screen Display

set_osd_name(enabled: bool) -> None async

Sets whether camera name is in the On Screen Display

set_package_detection(enabled: bool) -> None async

Toggles package smart detection. Requires camera to have smart detection

set_person_detection(enabled: bool) -> None async

Toggles person smart detection. Requires camera to have smart detection

set_person_track(enabled: bool) -> None async

Sets person tracking on camera

set_privacy(enabled: bool, mic_level: Optional[int] = None, recording_mode: Optional[RecordingMode] = None, reenable_global: bool = False) -> None async

Adds/removes a privacy zone that blacks out the whole camera.

set_ptz_home() -> PTZPreset async

Get PTZ home preset (-1) to current position.

set_recording_mode(mode: RecordingMode) -> None async

Sets recording mode on camera

set_siren_detection(enabled: bool) -> None async

Toggles siren smart detection. Requires camera to have smart detection

set_smart_audio_detect_types(types: list[SmartDetectAudioType]) -> None async

Sets current enabled smart audio detection types. Requires camera to have smart detection

set_smart_detect_types(types: list[SmartDetectObjectType]) -> None async

Sets current enabled smart detection types. Requires camera to have smart detection

set_smoke_detection(enabled: bool) -> None async

Toggles smoke smart detection. Requires camera to have smart detection

set_speaker_volume(level: int) -> None async

Sets the speaker sensitivity level on camera. Requires camera to have speakers

set_speaking_detection(enabled: bool) -> None async

Toggles speaking smart detection. Requires camera to have smart detection

set_status_light(enabled: bool) -> None async

Sets status indicicator light on camera

set_system_sounds(enabled: bool) -> None async

Sets system sound playback through speakers. Requires camera to have speakers

set_use_global(enabled: bool) -> None async

Sets if camera should use global recording settings or not.

set_vehicle_detection(enabled: bool) -> None async

Toggles vehicle smart detection. Requires camera to have smart detection

set_video_mode(mode: VideoMode) -> None async

Sets video mode on camera

set_wdr_level(level: int) -> None async

Sets WDR (Wide Dynamic Range) on camera

stop_audio() -> None async

Stop currently playing audio.

wait_until_audio_completes() -> None async

Awaits stream completion of audio and logs stdout/stderr.

Chime

Bases: ProtectAdoptableDeviceModel

cameras: list[Camera] property

Paired Cameras for chime

add_camera(camera: Camera) -> None async

Adds new paired camera to chime

play(*, volume: int | None = None, repeat_times: int | None = None) -> None async

Plays chime tone

play_buzzer() -> None async

Plays chime buzzer

remove_camera(camera: Camera) -> None async

Removes paired camera from chime

set_repeat_times(value: int) -> None async

Set repeat times on chime.

set_repeat_times_for_camera(camera: Camera, value: int) -> None async

Set repeat times on chime for specific camera.

set_volume(level: int) -> None async

Set the volume on chime.

set_volume_for_camera(camera: Camera, level: int) -> None async

Set the volume on chime for specific camera.

Doorlock

Bases: ProtectAdoptableDeviceModel

camera: Optional[Camera] property

Paired Camera will always be none if no camera is paired

calibrate() -> None async

Calibrate the doorlock.

Door must be open and lock unlocked.

close_lock() -> None async

Close doorlock (lock)

open_lock() -> None async

Open doorlock (unlock)

set_auto_close_time(duration: timedelta) -> None async

Sets the auto-close time for doorlock. 0 seconds = disabled.

set_paired_camera(camera: Optional[Camera]) -> None async

Sets the camera paired with the sensor

set_status_light(enabled: bool) -> None async

Sets the status indicator light for the doorlock

Event

Bases: ProtectModelWithId

get_animated_thumbnail(width: Optional[int] = None, height: Optional[int] = None, *, speedup: int = 10) -> Optional[bytes] async

Gets animated thumbnail for event

get_heatmap() -> Optional[bytes] async

Gets heatmap for event

get_smart_detect_track() -> SmartDetectTrack async

Gets smart detect track for given smart detect event.

If event is not a smart detect event, it will raise a BadRequest

get_smart_detect_zones() -> dict[int, CameraZone] async

Gets the triggering zones for the smart detection

get_thumbnail(width: Optional[int] = None, height: Optional[int] = None) -> Optional[bytes] async

Gets thumbnail for event

get_video(channel_index: int = 0, output_file: Optional[Path] = None, iterator_callback: Optional[IteratorCallback] = None, progress_callback: Optional[ProgressCallback] = None, chunk_size: int = 65536) -> Optional[bytes] async

Get the MP4 video clip for this given event


Text Only
1
channel_index: index of `CameraChannel` on the camera to use to retrieve video from

Will raise an exception if event does not have a camera, end time or the channel index is wrong.

FixSizeOrderedDict

Bases: dict[KT, VT]

A fixed size ordered dict.

__init__(*args: Any, max_size: int = 0, **kwargs: Any) -> None

Create the FixSizeOrderedDict.

__setitem__(key: KT, value: VT) -> None

Set an update up to the max size.

Light

Bases: ProtectMotionDeviceModel

camera: Optional[Camera] property

Paired Camera will always be none if no camera is paired

set_duration(duration: timedelta) -> None async

Sets motion sensitivity

set_led_level(led_level: int) -> None async

Sets the LED level for the light

set_light(enabled: bool, led_level: Optional[int] = None) -> None async

Force turns on/off the light

set_light_settings(mode: LightModeType, enable_at: Optional[LightModeEnableType] = None, duration: Optional[timedelta] = None, sensitivity: Optional[int] = None) -> None async

Updates various Light settings.


Text Only
1
2
3
4
mode: Light trigger mode
enable_at: Then the light automatically turns on by itself
duration: How long the light should remain on after motion, must be timedelta between 15s and 900s
sensitivity: PIR Motion sensitivity

set_paired_camera(camera: Optional[Camera]) -> None async

Sets the camera paired with the light

set_sensitivity(sensitivity: int) -> None async

Sets motion sensitivity

set_status_light(enabled: bool) -> None async

Sets the status indicator light for the light

Liveview

Bases: ProtectModelWithId

owner: Optional[User] property

Owner of liveview.

Will be none if the user only has read only access and it was not made by their user.

NVR

Bases: ProtectDeviceModel

is_face_detections_enabled: bool property

If smart detected enabled globally.

is_global_animal_detection_on: bool property

Is Animal Detection available and enabled (camera will produce package smart detection events)?

is_global_baby_cry_detection_on: bool property

Is Baby Cry Detection available and enabled (camera will produce baby cry smart detection events)?

is_global_bark_detection_on: bool property

Is Bark Detection available and enabled (camera will produce barking smart detection events)?

is_global_car_alarm_detection_on: bool property

Is Car Alarm Detection available and enabled (camera will produce car alarm smart detection events)?

is_global_car_horn_detection_on: bool property

Is Car Horn Detection available and enabled (camera will produce car horn smart detection events)?

is_global_co_detection_on: bool property

Is CO Alarm Detection available and enabled (camera will produce smoke smart detection events)?

is_global_glass_break_detection_on: bool property

Is Glass Break available and enabled (camera will produce glass break smart detection events)?

is_global_license_plate_detection_on: bool property

Is License Plate Detection available and enabled (camera will produce face license plate detection events)?

is_global_package_detection_on: bool property

Is Package Detection available and enabled (camera will produce package smart detection events)?

is_global_person_detection_on: bool property

Is Person Detection available and enabled (camera will produce person smart detection events)?

is_global_person_tracking_enabled: bool property

Is person tracking enabled

is_global_recording_enabled: bool property

Is recording footage/events from the camera enabled?

If recording is not enabled, cameras will not produce any footage, thumbnails, motion/smart detection events.

is_global_siren_detection_on: bool property

Is Siren Detection available and enabled (camera will produce siren smart detection events)?

is_global_smoke_detection_on: bool property

Is Smoke Alarm Detection available and enabled (camera will produce smoke smart detection events)?

is_global_speaking_detection_on: bool property

Is Speaking Detection available and enabled (camera will produce speaking smart detection events)?

is_global_vehicle_detection_on: bool property

Is Vehicle Detection available and enabled (camera will produce vehicle smart detection events)?

is_license_plate_detections_enabled: bool property

If smart detected enabled globally.

is_smart_detections_enabled: bool property

If smart detected enabled globally.

vault_cameras: list[Camera] property

Vault Cameras for NVR

add_custom_doorbell_message(message: str) -> None async

Adds custom doorbell message

get_is_prerelease() -> bool async

Get if current version of Protect is a prerelease version.

reboot() -> None async

Reboots the NVR

remove_custom_doorbell_message(message: str) -> None async

Removes custom doorbell message

set_analytics(value: AnalyticsOption) -> None async

Sets analytics collection for NVR

set_anonymous_analytics(enabled: bool) -> None async

Enables or disables anonymous analystics for NVR

set_default_doorbell_message(message: str) -> None async

Sets default doorbell message

set_default_reset_timeout(timeout: timedelta) -> None async

Sets the default message reset timeout

set_face_recognition(value: bool) -> None async

Set if face detections are enabled. Requires smart detections to be enabled.

set_global_motion_detection(enabled: bool) -> None async

Sets motion detection on camera

set_global_osd_bitrate(enabled: bool) -> None async

Sets whether camera bitrate is in the On Screen Display

set_global_osd_date(enabled: bool) -> None async

Sets whether current date is in the On Screen Display

Sets whether the UniFi logo is in the On Screen Display

set_global_osd_name(enabled: bool) -> None async

Sets whether camera name is in the On Screen Display

set_global_recording_mode(mode: RecordingMode) -> None async

Sets recording mode on camera

set_insights(enabled: bool) -> None async

Sets analytics collection for NVR

set_license_plate_recognition(value: bool) -> None async

Set if license plate detections are enabled. Requires smart detections to be enabled.

set_smart_detections(value: bool) -> None async

Set if smart detections are enabled.

update_all_messages() -> None

Updates doorbell_settings.all_messages after adding/removing custom message

ProtectAdoptableDeviceModel

Bases: ProtectDeviceModel

is_adopted_by_us: bool property

Verifies device is adopted and controlled by this NVR.

protect_url: str property

UFP Web app URL for this device

adopt(name: Optional[str] = None) -> None async

Adopts a device

get_changed(data_before_changes: dict[str, Any]) -> dict[str, Any]

Gets dictionary of all changed fields

reboot() -> None async

Reboots an adopted device

set_ssh(enabled: bool) -> None async

Sets ssh status for protect device

unadopt() -> None async

Unadopt/Unmanage adopted device

ProtectBaseObject

Bases: BaseModel

Base class for building Python objects from UniFi Protect JSON.

  • Provides .unifi_dict_to_dict to convert UFP JSON to a more Pythonic formatted dict (camel case to snake case)
  • Add attrs with matching Pyhonic name and they will automatically be populated from the UFP JSON if passed in to the constructer
  • Provides .unifi_dict to convert object back into UFP JSON

api: ProtectApiClient property

ProtectApiClient that the UFP object was created with. If no API Client was passed in time of creation, will raise BadRequest

__init__(api: Optional[ProtectApiClient] = None, **data: Any) -> None

Base class for creating Python objects from UFP JSON data.

Use the static method .from_unifi_dict() to create objects from UFP JSON data from then the main class constructor.

dict_with_excludes() -> dict[str, Any]

Returns a dict of the current object without any UFP objects converted to dicts.

from_unifi_dict(api: Optional[ProtectApiClient] = None, **data: Any) -> Self classmethod

Main constructor for ProtectBaseObject


Text Only
1
2
api: Optional reference to the ProtectAPIClient that created generated the UFP JSON
**data: decoded UFP JSON

api is is expected as a @property. If it is None and accessed, a BadRequest will be raised.

API can be used for saving updates for the Protect object or fetching references to other objects (cameras, users, etc.)

unifi_dict(data: Optional[dict[str, Any]] = None, exclude: Optional[set[str]] = None) -> dict[str, Any]

Can either convert current Python object into UFP JSON dict or take the output of a .dict() call and convert it.

  • Remaps items from ._get_unifi_remaps() in reverse
  • Converts snake_case to camelCase
  • Automatically removes any ProtectApiClient instances that might still be in the data
  • Automatically calls .unifi_dict() for any UFP Python objects that are detected

Text Only
1
2
3
data: Optional output of `.dict()` for the Python object. If `None`, will call `.dict` first
exclude: Optional set of fields to exclude from convert. Useful for subclassing and having custom
    processing for dumping to UFP JSON data.

unifi_dict_to_dict(data: dict[str, Any]) -> dict[str, Any] classmethod

Takes a decoded UFP JSON dict and converts it into a Python dict

  • Remaps items from ._get_unifi_remaps()
  • Converts camelCase keys to snake_case keys
  • Injects ProtectAPIClient into any child UFP object Dicts
  • Runs .unifi_dict_to_dict for any child UFP objects

Text Only
1
data: decoded UFP JSON dict

update_from_dict(data: dict[str, Any]) -> ProtectObject

Updates current object from a cleaned UFP JSON dict

ProtectDeviceModel

Bases: ProtectModelWithId

set_name(name: str | None) -> None async

Sets name for the device

ProtectModel

Bases: ProtectBaseObject

Base class for UFP objects with a modelKey attr. Provides .from_unifi_dict() static helper method for automatically decoding a modelKey object into the correct UFP object and type

ProtectModelWithId

Bases: ProtectModel

emit_message(updated: dict[str, Any]) -> None async

Emites fake WS message for ProtectApiClient to process.

queue_update(callback: Callable[[], None]) -> None async

Queues a device update.

This allows aggregating devices updates so if multiple ones come in all at once, they can be combined in a single PATCH.

revert_changes(data_before_changes: dict[str, Any]) -> None

Reverts current changes to device and resets it back to initial state

save_device(data_before_changes: dict[str, Any], force_emit: bool = False, revert_on_fail: bool = True) -> None async

Generates a diff for unsaved changed on the device and sends them back to UFP

USE WITH CAUTION, updates all fields for the current object that have been changed. May have unexpected side effects.

Tested updates have been added a methods on applicable devices.


Text Only
1
force_emit: Emit a fake UFP WS message. Should only be use for when UFP does not properly emit a WS message

ProtectWSPayloadFormat

Bases: int, Enum

Websocket Payload formats.

RingSetting

Bases: ProtectBaseObject

camera: Optional[Camera] property

Paired Camera will always be none if no camera is paired

Sensor

Bases: ProtectAdoptableDeviceModel

camera: Optional[Camera] property

Paired Camera will always be none if no camera is paired

clear_tamper() -> None async

Clears tamper status for sensor

remove_humidity_safe_range() -> None async

Removes the humidity safe range for the sensor

remove_light_safe_range() -> None async

Removes the light safe range for the sensor

remove_temperature_safe_range() -> None async

Removes the temperature safe range for the sensor

set_alarm_status(enabled: bool) -> None async

Sets the alarm detection type for the sensor

set_humidity_safe_range(low: float, high: float) -> None async

Sets the humidity safe range for the sensor

set_humidity_status(enabled: bool) -> None async

Sets the humidity detection type for the sensor

set_light_safe_range(low: float, high: float) -> None async

Sets the light safe range for the sensor

set_light_status(enabled: bool) -> None async

Sets the light detection type for the sensor

set_motion_sensitivity(sensitivity: int) -> None async

Sets the motion sensitivity for the sensor

set_motion_status(enabled: bool) -> None async

Sets the motion detection type for the sensor

set_mount_type(mount_type: MountType) -> None async

Sets current mount type for sensor

set_paired_camera(camera: Optional[Camera]) -> None async

Sets the camera paired with the sensor

set_status_light(enabled: bool) -> None async

Sets the status indicator light for the sensor

set_temperature_safe_range(low: float, high: float) -> None async

Sets the temperature safe range for the sensor

set_temperature_status(enabled: bool) -> None async

Sets the temperature detection type for the sensor

User

Bases: ProtectModelWithId

groups: list[Group] property

Groups the user is in

Will always be empty if the user only has read only access.

can(model: ModelType, node: PermissionNode, obj: Optional[ProtectModelWithId] = None) -> bool

Checks if a user can do a specific action

Viewer

Bases: ProtectAdoptableDeviceModel

set_liveview(liveview: Liveview) -> None async

Sets the liveview current set for the viewer


Text Only
1
liveview: The liveview you want to set

create_from_unifi_dict(data: dict[str, Any], api: Optional[ProtectApiClient] = None, klass: Optional[type[ProtectModel]] = None) -> ProtectModel

Helper method to read the modelKey from a UFP JSON dict and convert to currect Python class. Will raise DataDecodeError if the modelKey is for an unknown object.

Exceptions (pyunifiprotect.exception)

BadRequest

Bases: ClientError

Invalid request from API Client

ClientError

Bases: UnifiProtectError

Base Class for all other UniFi Protect client errors

DataDecodeError

Bases: UnifiProtectError

Exception raised when trying to decode a UniFi Protect object

Invalid

Bases: ClientError

Invalid return from Authorization Request.

NotAuthorized

Bases: PermissionError, BadRequest

Wrong username, password or permission error.

NvrError

Bases: ClientError

Other error.

StreamError

Bases: UnifiProtectError

Expcetion raised when trying to stream content

UnifiProtectError

Bases: Exception

Base class for all other UniFi Protect errors

WSDecodeError

Bases: UnifiProtectError

Exception raised when decoding Websocket packet

WSEncodeError

Bases: UnifiProtectError

Exception raised when encoding Websocket packet

Stream (pyunifiprotect.stream)

Utils (pyunifiprotect.utils)

clamp_value(value: float, step_size: float) -> float

Clamps value to multiples of step size.

convert_smart_audio_types(items: Iterable[str]) -> list[SmartDetectAudioType]

Converts list of str into SmartDetectAudioType. Any unknown values will be ignored and logged.

convert_smart_types(items: Iterable[str]) -> list[SmartDetectObjectType]

Converts list of str into SmartDetectObjectType. Any unknown values will be ignored and logged.

convert_unifi_data(value: Any, field: ModelField) -> Any

Converts value from UFP data into pydantic field class

convert_video_modes(items: Iterable[str]) -> list[VideoMode]

Converts list of str into VideoMode. Any unknown values will be ignored and logged.

Decode a token cookie if it is still valid.

format_datetime(dt: Optional[datetime], default: Optional[str] = None) -> Optional[str]

Formats a datetime object in a consisent format

format_duration(duration: timedelta) -> str

Formats a timedelta as a string.

from_js_time(num: Union[float, str, datetime]) -> datetime

Converts Javascript timestamp to Python datetime

get_local_timezone() -> tzinfo

Gets Olson timezone name for localizing datetimes

is_debug() -> bool

Returns if debug ENV is on (True)

local_datetime(dt: datetime | None = None) -> datetime

Returns datetime in local timezone

process_datetime(data: dict[str, Any], key: str) -> Optional[datetime]

Extracts datetime object from Protect dictionary

run_async(callback: Coroutine[Any, Any, T]) -> T

Run async coroutine.

serialize_coord(coord: CoordType) -> Union[int, float]

Serializes UFP zone coordinate

serialize_dict(data: dict[str, Any], levels: int = -1) -> dict[str, Any]

Serializes UFP data dict

serialize_list(items: Iterable[Any], levels: int = -1) -> list[Any]

Serializes UFP data list

serialize_point(point: tuple[CoordType, CoordType]) -> list[Union[int, float]]

Serializes UFP zone coordinate point

serialize_unifi_obj(value: Any, levels: int = -1) -> Any

Serializes UFP data

set_debug() -> None

Sets ENV variable for UFP_DEBUG to on (True)

set_no_debug() -> None

Sets ENV variable for UFP_DEBUG to off (False)

to_camel_case(name: str) -> str

Converts string to camelCase

to_js_time(dt: datetime | int | None) -> Optional[int]

Converts Python datetime to Javascript timestamp

to_ms(duration: Optional[timedelta]) -> Optional[int]

Converts python timedelta to Milliseconds

to_snake_case(name: str) -> str cached

Converts string to snake_case

Websocket (pyunifiprotect.websocket)

UniFi Protect Websockets.

Websocket

UniFi Protect Websocket manager.

has_recent_connect: bool property

Check if Websocket has recent connection.

is_connected: bool property

Check if Websocket connected.

__init__(url: str, auth_callback: CALLBACK_TYPE, *, timeout: int = 30, backoff: int = 10, verify: bool = True) -> None

Init Websocket.

connect() -> bool async

Connect the websocket.

disconnect() -> None async

Disconnect the websocket.

reconnect() -> bool async

Reconnect the websocket.

subscribe(ws_callback: Callable[[WSMessage], None]) -> Callable[[], None]

Subscribe to raw websocket messages.

Returns a callback that will unsubscribe.