API Reference¶
Rendering options (hidden sources, signature annotations, heading level) are
configured globally for the mkdocstrings Python handler in mkdocs.yml.
API Client (uiprotect.api)¶
UniFi Protect Server Wrapper.
BaseApiClient
¶
devices_ws_url: str
property
¶
Get Devices Websocket URL.
events_ws_url: str
property
¶
Get Events Websocket URL.
is_public_only: bool
property
¶
Whether this client was built with only an API key (no private login).
ws_url: str
property
¶
Get Websocket URL.
api_request_raw(url: str, method: str = 'get', require_auth: bool = True, raise_exception: bool = True, api_path: str | None = None, public_api: bool = False, **kwargs: Any) -> bytes | None
async
¶
Make a API request
async_disconnect_ws() -> None
async
¶
Disconnect from Websocket.
authenticate() -> None
async
¶
Authenticate and get a token.
clear_all_sessions() -> None
async
¶
Clears all stored sessions from the config file.
clear_session() -> None
async
¶
Clears stored session for this specific user/host combination.
close_public_api_session() -> None
async
¶
Closing and deletes public API client session.
close_session() -> None
async
¶
Closing and deletes all client sessions.
ensure_authenticated() -> None
async
¶
Ensure we are authenticated.
get_public_api_session() -> aiohttp.ClientSession
async
¶
Gets or creates current public API client session
get_session() -> aiohttp.ClientSession
async
¶
Gets or creates current client session
is_authenticated() -> bool
¶
Check to see if we are already authenticated.
request(method: str, url: str, require_auth: bool = False, auto_close: bool = True, public_api: bool = False, **kwargs: Any) -> aiohttp.ClientResponse
async
¶
Make a request to UniFi Protect with automatic retry on transient errors.
Automatically retries requests that receive 408, 429, 500, 502, 503, or 504 status codes using exponential backoff.
set_header(key: str, value: str | None) -> None
¶
Set header.
CameraPublicApiLcdMessageRequest
¶
Bases: TypedDict
Type for lcdMessage in PATCH /v1/cameras/{id} request body (Public API).
Per the integration spec, type is always required. text is required
for CUSTOM_MESSAGE and IMAGE; resetAt is optional for all variants (UNIX
timestamp in ms; omit to use the NVR default, pass None for "forever").
LightPatchRequest
¶
Bases: TypedDict
Type for PATCH /v1/lights/{id} request body.
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.
You can use the .get_ methods to one off pull devices from the UFP API, but should
not be used for building an application on top of.
All objects inside of .bootstrap have a reference 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 12 | |
connection_host: IPv4Address | IPv6Address | str
property
¶
Connection host to use for generating RTSP URLs.
has_public_bootstrap: bool
property
¶
Whether :meth:update_public has been called at least once.
public_bootstrap: PublicBootstrap
property
¶
In-memory cache of Public Integration API resources.
Must be populated via :meth:update_public first; raises
:class:BadRequest otherwise. This is a conscious mirror of
:attr:bootstrap so that merely reading the property never changes
WS-handler semantics (which keys off _public_bootstrap is not
None).
activate_relay_output_public(relay_id: str, output_id: int, *, state: Literal['on', 'off'] | None = None, pulse_duration_ms: int | None = None) -> None
async
¶
Activate, toggle or pulse a relay output.
Omit state to toggle the current state. pulse_duration_ms is
only valid together with state='on'; the output will auto-turn
off after the given milliseconds.
active_events(device_id: str | None = None) -> list[ProtectEvent]
¶
Return the in-flight public events, optionally filtered by device.
Derived directly from public_bootstrap.events, so it works
before any subscribe_events call (e.g. restoring state after a
reload). Returns [] until update_public() has primed the
public bootstrap.
adopt_device(model_type: ModelType, device_id: str) -> None
async
¶
Adopts a device
clear_tamper_sensor(device_id: str) -> None
async
¶
Clears tamper status for sensor
create_api_key(name: str) -> str
async
¶
Create an API key with the given name and return the full API key.
create_arm_profile_public(*, name: str, automations: list[str], schedules: list[PublicArmScheduleDict], record_everything: bool, activation_delay: int) -> ArmProfile
async
¶
Create a new arm profile.
create_camera_rtsps_streams(camera_id: str, qualities: list[ChannelQuality | str] | ChannelQuality | str) -> RTSPSStreams | None
async
¶
Creates RTSPS streams for a camera using public API.
On success the result is written through to the matching cached
:class:PublicCamera's rtsps_streams field (when
update_public() has primed it), since stream creation is not
signalled over the websocket.
create_liveview_public(*, name: str, is_default: bool, is_global: bool, owner: str, layout: int, slots: list[PublicLiveviewSlotDict]) -> PublicLiveview
async
¶
Create a new liveview using public API.
create_talkback_session_public(camera_id: str) -> TalkbackSession
async
¶
Create a talkback session for a camera using public API.
Returns the talkback stream URL and audio configuration.
delete_arm_profile_public(profile_id: str) -> None
async
¶
Delete an arm profile.
delete_camera_rtsps_streams(camera_id: str, qualities: list[ChannelQuality | str] | ChannelQuality | str) -> bool
async
¶
Deletes RTSPS streams for a camera using public API.
On success the deleted qualities are removed from the matching cached
:class:PublicCamera's rtsps_streams (when present); a camera left
with no streams has the field cleared to None.
disable_arm_alarm_public() -> None
async
¶
Disable the arm alarm.
disable_camera_mic_permanently_public(camera_id: str) -> PublicCamera
async
¶
Permanently disable a camera's microphone.
Irreversible without a factory reset of the camera. The spec returns the updated camera object (not a 204).
emit_devices_message(msg: WSSubscriptionMessage) -> None
¶
Emit message to all devices subscriptions.
emit_events_message(msg: WSSubscriptionMessage) -> None
¶
Emit message to all events subscriptions.
emit_message(msg: WSSubscriptionMessage) -> None
¶
Emit message to all subscriptions.
enable_arm_alarm_public() -> None
async
¶
Enable the arm alarm with the currently selected profile.
get_aiport(device_id: str) -> AiPort
async
¶
Gets a AiPort straight from the NVR.
The websocket is connected and running, you likely just want to use self.bootstrap.aiport[device_id]
get_aiports() -> list[AiPort]
async
¶
Gets the list of aiports straight from the NVR.
The websocket is connected and running, you likely just want to use self.bootstrap.aiports
get_alarm_hub_public(hub_id: str) -> LinkStation
async
¶
Get a specific alarm hub using public API.
get_alarm_hubs_public() -> list[LinkStation]
async
¶
Get all alarm hubs using public API.
get_arm_manager_settings_public() -> NvrArmMode | None
async
¶
Return current arm-manager state from the NVR cache.
The arm-manager state is embedded in the NVR object (armMode
field of GET /v1/nvrs) — there is no dedicated GET endpoint.
If the bootstrap cache is not yet populated, fetches the NVR now
via :meth:get_nvr_public so the full PublicNVR is always
constructed through the same code path.
get_arm_profiles_public() -> list[ArmProfile]
async
¶
Get all arm profiles.
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_bridge_public(bridge_id: str) -> PublicBridge
async
¶
Get a specific bridge using public API.
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_bridges_public() -> list[PublicBridge]
async
¶
Get all bridges using public API.
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_public(camera_id: str) -> PublicCamera
async
¶
Get a specific camera using public API.
get_camera_rtsps_streams(camera_id: str) -> RTSPSStreams | None
async
¶
Fetch a camera's RTSPS streams from the public API.
A flag-free fetch primitive with no cache side-effects: caching policy
lives in the population layer (:meth:update_public priming, the
WS-reconnect refresh, and create/delete write-through).
get_camera_snapshot(camera_id: str, width: int | None = None, height: int | None = None, dt: datetime | None = None) -> bytes | None
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: Path | None = None, iterator_callback: IteratorCallback | None = None, progress_callback: ProgressCallback | None = None, chunk_size: int = 65536, fps: int | None = None) -> bytes | None
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 with 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_cameras_public() -> list[PublicCamera]
async
¶
Get all cameras using public API.
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_chime_public(chime_id: str) -> PublicChime
async
¶
Get a specific chime using public API.
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_chimes_public() -> list[PublicChime]
async
¶
Get all chimes using public API.
get_console_mac() -> str | None
async
¶
Resolve the console/NVR mac via the UniFi-OS /api/system endpoint.
The public Protect Integration API only exposes the NVR mac on
Protect newer than 7.1; older firmware omits it (:attr:PublicNVR.mac
is then None). This helper fills that gap so a :meth:public_only
client on older firmware can still derive the console's stable,
mac-based identity.
This is a transitional workaround for the hybrid/parallel phase in
which the private and public paths coexist: identity must stay
mac-based to match what the private path already produces, so a feature
toggling between the two paths doesn't churn entity ids. The end-state
identity is the public API's own primary key (nvr.id); this helper
is expected to be retired once the private path is dropped and
consumers migrate to id.
/api/system is an off-contract UniFi-OS endpoint (not the
public Protect API): unauthenticated, and it returns the mac of the
device at the configured Protect host. Returns the mac string (e.g.
"AABBCCDDEEFF", matching the private NVR.mac format) or
None when the endpoint is unreachable or carries no mac.
get_device(model_type: ModelType, device_id: str, expected_type: type[ProtectModelWithId] | None = 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: type[ProtectModel] | None = 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_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: int | None = None, height: int | None = None, *, speedup: int = 10, retry_timeout: int = RETRY_TIMEOUT) -> bytes | None
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) -> bytes | None
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: int | None = None, height: int | None = None, retry_timeout: int = RETRY_TIMEOUT) -> bytes | None
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: datetime | None = None, end: datetime | None = None, limit: int | None = None, offset: int | None = None, types: list[EventType] | None = None, smart_detect_types: list[SmartDetectObjectType] | None = 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
Eventobjects 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 | |
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: datetime | None = None, end: datetime | None = None, limit: int | None = None, offset: int | None = None, types: list[EventType] | None = None, smart_detect_types: list[SmartDetectObjectType] | None = None, sorting: Literal['asc', 'desc'] = 'asc', descriptions: bool = True, all_cameras: bool | None = 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 | |
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_files_public(file_type: AssetFileType | str = AssetFileType.ANIMATIONS) -> list[PublicFile]
async
¶
List uploaded device asset files of the given type.
get_fob_public(fob_id: str) -> Fob
async
¶
Get a specific key fob using public API.
get_fobs_public() -> list[Fob]
async
¶
Get all key fobs using public API.
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]
.. deprecated::
Use :meth:get_light_public instead. This method uses the private API
and will be removed in a future version.
get_light_public(light_id: str) -> PublicLight
async
¶
Get a specific light using public API.
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
.. deprecated::
Use :meth:get_lights_public instead. This method uses the private API
and will be removed in a future version.
get_lights_public() -> list[PublicLight]
async
¶
Get all lights using public API.
get_link_station_public(link_station_id: str) -> LinkStation
async
¶
Get a specific link station using public API.
get_link_stations_public() -> list[LinkStation]
async
¶
Get all link stations using public API.
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_liveview_public(liveview_id: str) -> PublicLiveview
async
¶
Get a specific liveview using public API.
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_liveviews_public() -> list[PublicLiveview]
async
¶
Get all liveviews using public API.
get_meta_info() -> MetaInfo
async
¶
Get NVR metadata via the Public Integration API.
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_nvr_public() -> PublicNVR
async
¶
Get NVR information using public API.
get_package_camera_snapshot(camera_id: str, width: int | None = None, height: int | None = None, dt: datetime | None = None) -> bytes | None
async
¶
Gets snapshot from the package camera.
Datetime of screenshot is approximate. It may be +/- a few seconds.
get_patrols_ptz_camera(device_id: str) -> list[PTZPatrol]
async
¶
Get PTZ Patrols for camera.
get_presets_ptz_camera(device_id: str) -> list[PTZPreset]
async
¶
Get PTZ Presets for camera.
get_public_api_camera_snapshot(camera_id: str, high_quality: bool = False, package: bool = False) -> bytes | None
async
¶
Gets snapshot for a camera using public api.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
camera_id
|
str
|
Camera ID. |
required |
high_quality
|
bool
|
Force 1080P+ resolution. |
False
|
package
|
bool
|
If |
False
|
get_relay_public(relay_id: str) -> Relay
async
¶
Get a specific relay using public API.
get_relays_public() -> list[Relay]
async
¶
Get all relays using public API.
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_sensor_public(sensor_id: str) -> PublicSensor
async
¶
Get a specific sensor using public API.
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_sensors_public() -> list[PublicSensor]
async
¶
Get all sensors using public API.
get_siren_public(siren_id: str) -> Siren
async
¶
Get a specific siren using public API.
get_sirens_public() -> list[Siren]
async
¶
Get all sirens using public API.
get_speaker_public(speaker_id: str) -> Speaker
async
¶
Get a specific speaker using public API.
get_speakers_public() -> list[Speaker]
async
¶
Get all speakers using public API.
get_ulp_user_public(ulp_user_id: str) -> PublicUlpUser
async
¶
Get a specific UniFi Identity user using public API.
get_ulp_users_public() -> list[PublicUlpUser]
async
¶
Get all UniFi Identity users using public API.
get_user_public(user_id: str) -> PublicUser
async
¶
Get a specific Protect user using public API.
get_users_public() -> list[PublicUser]
async
¶
Get all Protect users using public API.
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_viewer_public(viewer_id: str) -> PublicViewer
async
¶
Get a specific viewer using public API.
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
get_viewers_public() -> list[PublicViewer]
async
¶
Get all viewers using public API.
is_api_key_set() -> bool
¶
Check if the API key is set.
play_buzzer(device_id: str) -> None
async
¶
Plays chime tones on a chime
play_siren_public(siren_id: str, *, duration: SirenDuration | int | None = None) -> None
async
¶
Activate a siren. duration may be a supported integer or :class:SirenDuration; defaults to 5 seconds.
play_speaker(device_id: str, *, volume: int | None = None, repeat_times: int | None = None, ringtone_id: str | None = None, track_no: int | None = None) -> None
async
¶
Plays chime tones on a chime.
| Text Only | |
|---|---|
1 2 3 4 5 6 7 8 | |
poll_events() -> None
async
¶
Poll for events.
ptz_goto_preset_public(camera_id: str, *, slot: int) -> None
async
¶
Move PTZ camera to preset position using public API.
ptz_patrol_start_public(camera_id: str, *, slot: int) -> None
async
¶
Start a PTZ patrol using public API.
ptz_patrol_stop_public(camera_id: str) -> None
async
¶
Stop the active PTZ patrol using public API.
public_only(host: str, port: int, api_key: str, *, verify_ssl: bool = True, public_api_session: aiohttp.ClientSession | None = None, ws_timeout: int = 30, ws_receive_timeout: int | None = None, subscribed_models: set[ModelType] | None = None, events_ws_subscribed_models: set[ModelType] | None = None, devices_ws_subscribed_models: set[ModelType] | None = None, ignore_unadopted: bool = True, max_retries: int = RETRY_DEFAULT_ATTEMPTS) -> Self
classmethod
¶
Construct a client that operates entirely on the Public Integration API.
No private login is performed. Private-session entry points
(:meth:authenticate, :meth:update, :meth:get_bootstrap) raise
:class:PublicOnlyModeError; use :meth:update_public,
:meth:subscribe_events, :meth:subscribe_devices, the public
get_*_public / update_*_public methods, and
:meth:get_meta_info instead. A revoked or invalid key surfaces as
:class:NotAuthorized.
reboot_device(model_type: ModelType, device_id: str) -> None
async
¶
Reboots an adopted device
reboot_nvr() -> None
async
¶
Reboots NVR
resolve_nvr_mac() -> str | None
async
¶
Resolve the NVR mac, normalized, by source priority: public
bootstrap, then private bootstrap, then the /api/system console
fallback; None if none resolve.
send_alarm_webhook_public(trigger_id: str) -> None
async
¶
Fire the alarm-manager webhook for the given trigger id.
set_api_key(api_key: str) -> None
¶
Set the API key for the NVR.
set_current_arm_profile_public(profile_id: str) -> None
async
¶
Set the currently selected arm profile.
set_light_is_led_force_on(device_id: str, is_led_force_on: bool) -> None
async
¶
Sets isLedForceOn for light.
.. deprecated::
Use :meth:update_light_public instead. This method uses the private API
and will be removed in a future version.
stop_siren_public(siren_id: str) -> None
async
¶
Stop an active siren.
subscribe_devices(callback: Callable[[ProtectDeviceChange], None]) -> Callable[[], None]
¶
Subscribe to typed public device-state lifecycle callbacks.
The device-side analog of subscribe_events: each callback receives
a :class:~uiprotect.devices.ProtectDeviceChange describing an
ADDED / UPDATED / REMOVED device, carrying the merged
public model (None for REMOVED) and, for UPDATED, the
changed-field set. Single and bulk WS envelopes are expanded
transparently to one change per device; state / connection
transitions surface as ordinary UPDATEDs.
Requires update_public() to have primed the public bootstrap at
least once before subscribing (a RuntimeError is raised otherwise)
— the merged public models depend on that cache. Callers that need the
websocket live during priming should use the raw
subscribe_devices_websocket instead, which has no such ordering
requirement.
The callback must not raise: an exception is caught and logged but
otherwise swallowed. device_mac resolves with eventual consistency
— a device not yet in the bootstrap yields None until the next
update_public() / reconnect resync.
A revoked or invalid API key surfaces as WebsocketState.AUTH_FAILED
via subscribe_devices_websocket_state after repeated 401 handshakes;
call set_api_key() with a fresh key to re-arm.
subscribe_devices_and_prime(callback: Callable[[ProtectDeviceChange], None]) -> Callable[[], None]
async
¶
Subscribe to typed device changes and prime the public bootstrap, order-independent.
Connects the devices websocket before priming, then awaits
:meth:update_public. Frames arriving during the prime are buffered and
replayed onto the fresh snapshot, so no update is lost regardless of
when the caller invokes this — it makes the prime/subscribe ordering
question moot. Unlike :meth:subscribe_devices, it does not require the
bootstrap to be primed beforehand.
Returns the same unsubscribe callable as :meth:subscribe_devices. If
priming raises (e.g. :class:NotAuthorized), the subscription is rolled
back before the error propagates.
subscribe_devices_websocket(ws_callback: Callable[[WSSubscriptionMessage], None]) -> Callable[[], None]
¶
Subscribe to devices websocket events.
Returns a callback that will unsubscribe.
subscribe_devices_websocket_state(ws_callback: Callable[[WebsocketState], None]) -> Callable[[], None]
¶
Subscribe to devices websocket state changes.
Returns a callback that will unsubscribe.
subscribe_events(callback: Callable[[ProtectEvent, EventChange], None]) -> Callable[[], None]
¶
Subscribe to typed public event lifecycle callbacks.
Only events whose EventType maps to a non-OTHER
ProtectEventChannel (detection / sensor / alarm-hub /
access) are delivered; administrative events such as
provision, factoryReset and fwUpdate are dropped.
Callers needing the unfiltered stream should use
subscribe_events_websocket instead.
The callback must not raise: an exception is caught and logged but
otherwise swallowed, so a raising callback silently loses that
delivery (e.g. an ENDED that never reaches the consumer). Do any
fallible work inside a guard the callback owns.
Identity and device_mac resolve with eventual consistency: the
first event for a freshly-enrolled ULP user can resolve to
UnknownIdentity(reason="ulp_user_not_cached"), and a device not
yet in the bootstrap yields device_mac=None, until the next
update_public() / reconnect resync refreshes
public_bootstrap.ulp_users and the device stores. Smart-detect
detected attributes (license-plate text, face-match name) are not
exposed over the public API today — fall back to the private path
via event.raw when you need them.
A revoked or invalid API key surfaces as WebsocketState.AUTH_FAILED
via subscribe_events_websocket_state after repeated 401 handshakes;
call set_api_key() with a fresh key to re-arm.
subscribe_events_and_prime(callback: Callable[[ProtectEvent, EventChange], None]) -> Callable[[], None]
async
¶
Subscribe to typed event changes and prime the public bootstrap, order-independent.
The events-side analog of :meth:subscribe_devices_and_prime: connects
the events websocket before priming, then awaits :meth:update_public.
Frames arriving during the prime are buffered and replayed onto the
fresh snapshot, so ordering is moot and the bootstrap need not be primed
beforehand.
Returns the same unsubscribe callable as :meth:subscribe_events. If
priming raises, the subscription is rolled back before the error
propagates.
subscribe_events_websocket(ws_callback: Callable[[WSSubscriptionMessage], None]) -> Callable[[], None]
¶
Subscribe to events websocket events.
Returns a callback that will unsubscribe.
subscribe_events_websocket_state(ws_callback: Callable[[WebsocketState], None]) -> Callable[[], None]
¶
Subscribe to events websocket state changes.
Returns a callback that will unsubscribe.
subscribe_websocket(ws_callback: Callable[[WSSubscriptionMessage], None]) -> Callable[[], None]
¶
Subscribe to websocket events.
Returns a callback that will unsubscribe.
subscribe_websocket_state(ws_callback: Callable[[WebsocketState], None]) -> Callable[[], None]
¶
Subscribe to websocket state changes.
Returns a callback that will unsubscribe.
test_siren_sound_public(siren_id: str, *, volume: int | None = None) -> None
async
¶
Test the siren sound (5 seconds).
test_speaker_sound_public(speaker_id: str, *, volume: int | None = None) -> None
async
¶
Test the speaker sound at the given volume.
trigger_alarm_hub_output_public(hub_id: str, output_id: int, *, enable: bool | None = None, delay: int | None = None, duration: int | None = None) -> None
async
¶
Trigger an alarm-hub output channel using public API.
unadopt_device(model_type: ModelType, device_id: str) -> None
async
¶
Unadopt/Unmanage adopted device
update() -> Bootstrap
async
¶
Updates the state of devices, initializes .bootstrap
The websocket is auto connected once there are any subscriptions to it. update must be called at least once before subscribing to the websocket.
You can use the various other get_ methods if you need one off data from UFP
update_alarm_hub_public(hub_id: str, *, name: str | None = None) -> LinkStation
async
¶
Patch alarm hub settings using public API.
update_arm_profile_public(profile_id: str, *, name: str | None = None, automations: list[str] | None = None, schedules: list[PublicArmScheduleDict] | None = None, record_everything: bool | None = None, activation_delay: int | None = None) -> ArmProfile
async
¶
Update an existing arm profile (partial update).
update_bridge_public(bridge_id: str, *, name: str | None = None) -> PublicBridge
async
¶
Patch bridge settings using public API.
update_camera_public(camera_id: str, *, name: str | None = None, hdr_type: PublicHdrMode | None = None, video_mode: VideoMode | None = None, led_is_enabled: bool | None = None, led_welcome_led: bool | None = None, led_flood_led: bool | None = None, mic_volume: int | None = None, smart_detect_object_types: list[SmartDetectObjectType] | None = None, smart_detect_audio_types: list[SmartDetectAudioType] | None = None, lcd_message: CameraPublicApiLcdMessageRequest | None = None, osd_name_enabled: bool | None = None, osd_date_enabled: bool | None = None, osd_logo_enabled: bool | None = None, osd_nerd_mode_enabled: bool | None = None, osd_overlay_location: OsdOverlayLocation | None = None) -> PublicCamera
async
¶
Patch camera settings using public API.
Returns a fresh Camera object deserialized from the PATCH response. When
a public bootstrap is loaded and holds this camera, the response is also
written through into the cached twin (out-of-band rtsps_streams is
preserved); the private bootstrap, if any, is left to the private-tree
convenience methods.
update_chime_public(chime_id: str, *, name: str | None = None, camera_ids: list[str] | None = None, ring_settings: list[PublicApiChimeRingSettingRequest] | None = None) -> PublicChime
async
¶
Update chime settings using public API.
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_fob_public(fob_id: str, *, name: str | None = None) -> Fob
async
¶
Patch key-fob settings using public API.
update_light_public(light_id: str, *, name: str | None = None, is_light_force_enabled: bool | None = None, light_mode_settings: LightModeSettings | PublicLightModeSettings | None = None, light_device_settings: LightDeviceSettings | PublicLightDeviceSettings | None = None) -> PublicLight
async
¶
Update light settings using public API.
| Text Only | |
|---|---|
1 2 3 4 5 | |
| Text Only | |
|---|---|
1 | |
| Text Only | |
|---|---|
1 | |
update_link_station_public(link_station_id: str, *, name: str | None = None) -> LinkStation
async
¶
Patch link station settings using public API.
update_liveview_public(liveview_id: str, *, name: str | None = None, is_default: bool | None = None, is_global: bool | None = None, owner: str | None = None, layout: int | None = None, slots: list[PublicLiveviewSlotDict] | None = None) -> PublicLiveview
async
¶
Patch an existing liveview (partial update) using public API.
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.
update_public() -> PublicBootstrap
async
¶
Populate :attr:public_bootstrap from the Public Integration API.
This is opt-in and completely independent of :meth:update / the
private bootstrap. Safe to call multiple times — the
:class:PublicBootstrap instance is created on first use and then
updated in place on subsequent calls. All endpoint fetches run
concurrently.
Each endpoint is requested best-effort; endpoints that the NVR
doesn't (yet) expose (BadRequest / NvrError) are logged at
DEBUG and ignored, and a partial public bootstrap is returned.
If an endpoint fails, its previously cached data is left unchanged
(not cleared). All results are classified before any are applied: an
unexpected exception (e.g. a validation error from a new server
payload) propagates to the caller with the snapshot left untouched,
never half-applied.
A revoked or invalid API key surfaces as :class:NotAuthorized; catch
it as the reauth signal.
Public events/devices WS frames that arrive while this method is
priming are captured and replayed onto the fresh snapshot before it
returns, so a subscriber that is already connected does not lose an
update to the prime window — the subscribe-then-prime ordering is a
library guarantee, not a caller obligation. To also make the
prime-then-subscribe ordering moot for the typed callbacks, use
:meth:subscribe_devices_and_prime / :meth:subscribe_events_and_prime.
After priming, public_bootstrap.nvr.mac carries the NVR mac
whenever it is resolvable. On firmware that omits mac from the
public payload it is backfilled from the console fallback and stored
in the native UniFi format (uppercase, no separators) — the same
format newer firmware already provides — so consumers can read a
self-consistent mac regardless of firmware.
Concurrent calls are serialized: an overlapping prime could otherwise apply an older snapshot over a newer one (and over live WS merges in between). Each caller returns the then-current bootstrap.
update_relay_public(relay_id: str, *, name: str | None = None, led_is_enabled: bool | None = None) -> Relay
async
¶
Patch relay settings using public API.
update_sensor_public(sensor_id: str, *, name: str | None = None, light_settings: PublicSensorLightSettings | None = None, humidity_settings: PublicSensorHumiditySettings | None = None, temperature_settings: PublicSensorTemperatureSettings | None = None, motion_settings: PublicSensorMotionSettings | None = None, glass_break_settings: PublicSensorGlassBreakSettingsWrite | None = None, alarm_settings: PublicSensorAlarmSettings | None = None, schedule_mode: SensorScheduleMode | str | None = None, arm_profile_ids: list[str] | None = None, has_custom_sensitivity_when_armed: bool | None = None) -> PublicSensor
async
¶
Patch sensor settings using public API.
Each *_settings argument is a :class:~typing.TypedDict with
total=False — pass only the keys you want to change.
update_siren_public(siren_id: str, *, name: str | None = None, volume: int | None = None, led_is_enabled: bool | None = None) -> Siren
async
¶
Patch siren settings using public API.
update_speaker_public(speaker_id: str, *, name: str | None = None, volume: int | None = None, mic_volume: int | None = None, is_mic_enabled: bool | None = None) -> Speaker
async
¶
Patch speaker settings using public API.
update_viewer_public(viewer_id: str, *, name: str | None = None, liveview: str | None | _UnsetType = _UNSET) -> PublicViewer
async
¶
Patch viewer settings using public API. Pass liveview=None to clear.
upload_file_public(file_type: AssetFileType | str, file: bytes, original_name: str, content_type: str = 'image/png') -> PublicFile
async
¶
Upload a device asset as multipart/form-data.
The spec accepts image/gif, image/jpeg, image/png,
audio/mpeg, audio/mp4, audio/wave, audio/x-caf;
content_type defaults to image/png for the common
doorbell-animation case and must be overridden for other MIME types.
aiohttp sets the multipart Content-Type header (with boundary)
itself when data= is a :class:aiohttp.FormData, so this client
never sets a JSON content-type for this call.
PublicApiChimePatchRequest
¶
Bases: TypedDict
Type for PATCH /v1/chimes/{id} request body (Public API).
PublicApiChimeRingSettingRequest
¶
Bases: TypedDict
Type for ringSettings items in PATCH /v1/chimes/{id} request body (Public API).
calculate_retry_delay(attempt: int, retry_after: float | None = None) -> float
¶
Calculate delay before next retry attempt with exponential backoff and jitter.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attempt
|
int
|
Current retry attempt number (0-based). |
required |
retry_after
|
float | None
|
Optional Retry-After header value in seconds. |
None
|
Returns:
| Type | Description |
|---|---|
float
|
Delay in seconds before next retry. |
parse_retry_after(response: ClientResponse) -> float | None
¶
Parse Retry-After header from response.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
response
|
ClientResponse
|
HTTP response object. |
required |
Returns:
| Type | Description |
|---|---|
float | None
|
Retry delay in seconds, or None if header not present/parseable. |
Data Models (uiprotect.data)¶
AlarmHubBattery
¶
Bases: ProtectBaseObject
Backup battery status of an alarm hub (alarmHub.battery sub-schema).
The battery object declares no required array in the OpenAPI spec,
and a real hub with the backup battery disconnected emits only
connection (omitting charging/voltage/batteryStatus), so
every field is optional.
AlarmHubBatteryStatus
¶
Bases: UnknownValuesEnumMixin, StrEnum
Alarm-hub backup-battery health (alarmHub.battery.batteryStatus field).
AlarmHubConnectionState
¶
Bases: UnknownValuesEnumMixin, StrEnum
Alarm-hub backup-battery wiring state (alarmHub.battery.connection field).
AlarmHubCover
¶
Bases: ProtectBaseObject
Tamper cover status of an alarm hub (alarmHub.cover sub-schema).
The cover object declares no required array in the OpenAPI spec, so
both fields are optional.
AlarmHubCoverStatus
¶
Bases: UnknownValuesEnumMixin, StrEnum
Alarm-hub tamper-cover status (alarmHub.cover.status field).
AlarmHubInput
¶
AlarmHubInputContactType
¶
Bases: UnknownValuesEnumMixin, StrEnum
Alarm-hub input contact wiring (alarmHub.input[].type field).
AlarmHubInputStatus
¶
Bases: UnknownValuesEnumMixin, StrEnum
Alarm-hub input zone status (alarmHub.input[].status field).
AlarmHubInputType
¶
Bases: UnknownValuesEnumMixin, StrEnum
Alarm-hub input zone kind (alarmHub.input[].inputType field).
AlarmHubOutput
¶
AlarmHubOutputStatus
¶
Bases: UnknownValuesEnumMixin, StrEnum
Alarm-hub output channel status (alarmHub.output[].status field).
ArmProfile
¶
Bases: ProtectBaseObject
Public API arm profile (local alarm manager).
Arm profiles are configuration objects, not devices — the
/v1/arm-profiles payload has no modelKey. The class therefore
inherits directly from :class:ProtectBaseObject and carries its own
id field.
AssetFileType
¶
Bases: UnknownValuesEnumMixin, StrEnum
Public-API device asset file kind (/v1/files/{fileType}).
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 earliest 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
¶
[DEPRECATED] Always returns False. Will be removed after HA 2025.8.0.
process_ws_packet(packet: WSPacket, models: set[ModelType] | None = None, ignore_stats: bool = False, is_ping_back: bool = False) -> WSSubscriptionMessage | None
¶
Process a WS packet.
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.
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_currently_detected: bool
property
¶
Is face currently being detected
is_face_detection_on: bool
property
¶
Is Face Detection available and enabled?
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_ptz_patrolling: bool
property
¶
Is PTZ camera currently running a patrol?
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: datetime | None
property
¶
Get the last animal smart detection event.
last_animal_detect_event: Event | None
property
¶
Get the last animal smart detection event.
last_baby_cry_detect: datetime | None
property
¶
Get the last Baby Cry smart detection event.
last_baby_cry_detect_event: Event | None
property
¶
Get the last Baby Cry smart detection event.
last_bark_detect: datetime | None
property
¶
Get the last Bark smart detection event.
last_bark_detect_event: Event | None
property
¶
Get the last Bark smart detection event.
last_car_alarm_detect: datetime | None
property
¶
Get the last Car Alarm smart detection event.
last_car_alarm_detect_event: Event | None
property
¶
Get the last Car Alarm smart detection event.
last_car_horn_detect: datetime | None
property
¶
Get the last Car Horn smart detection event.
last_car_horn_detect_event: Event | None
property
¶
Get the last Car Horn smart detection event.
last_cmonx_detect: datetime | None
property
¶
Get the last CO alarm smart detection event.
last_cmonx_detect_event: Event | None
property
¶
Get the last CO alarm smart detection event.
last_face_detect: datetime | None
property
¶
Get the last face smart detection event.
last_face_detect_event: Event | None
property
¶
Get the last face smart detection event.
last_glass_break_detect: datetime | None
property
¶
Get the last Glass Break smart detection event.
last_glass_break_detect_event: Event | None
property
¶
Get the last Glass Break smart detection event.
last_license_plate_detect: datetime | None
property
¶
Get the last license plate smart detection event.
last_license_plate_detect_event: Event | None
property
¶
Get the last license plate smart detection event.
last_package_detect: datetime | None
property
¶
Get the last package smart detection event.
last_package_detect_event: Event | None
property
¶
Get the last package smart detection event.
last_person_detect: datetime | None
property
¶
Get the last person smart detection event.
last_person_detect_event: Event | None
property
¶
Get the last person smart detection event.
last_siren_detect: datetime | None
property
¶
Get the last Siren smart detection event.
last_siren_detect_event: Event | None
property
¶
Get the last Siren smart detection event.
last_smart_audio_detect_event: Event | None
property
¶
Get the last smart audio detect event id.
last_smart_detect_event: Event | None
property
¶
Get the last smart detect event id.
last_smoke_detect: datetime | None
property
¶
Get the last smoke smart detection event.
last_smoke_detect_event: Event | None
property
¶
Get the last person smart detection event.
last_speaking_detect: datetime | None
property
¶
Get the last Speaking smart detection event.
last_speaking_detect_event: Event | None
property
¶
Get the last Speaking smart detection event.
last_vehicle_detect: datetime | None
property
¶
Get the last vehicle smart detection event.
last_vehicle_detect_event: Event | None
property
¶
Get the last vehicle smart detection event.
create_rtsps_streams(qualities: list[ChannelQuality | str] | ChannelQuality | str) -> RTSPSStreams | None
async
¶
Creates RTSPS streams for camera using public API.
create_talkback_stream(content_url: str, ffmpeg_path: Path | None = None, *, use_public_api: bool = True) -> TalkbackStream
async
¶
Creates a stream to play audio to a camera through its speaker.
Uses PyAV (libav) for audio encoding - compatible with Home Assistant.
| Text Only | |
|---|---|
1 2 3 | |
Use either await stream.run_until_complete() or await stream.start() to start streaming
after getting the stream.
.play_audio() is a helper that wraps this method and automatically runs the stream as well
delete_rtsps_streams(qualities: list[ChannelQuality | str] | ChannelQuality | str) -> bool
async
¶
Deletes RTSPS streams for camera using public API.
get_last_smart_audio_detect_event(smart_type: SmartDetectAudioType) -> Event | None
¶
Get the last smart audio detect event for given type.
get_last_smart_detect_event(smart_type: SmartDetectObjectType) -> Event | None
¶
Get the last smart detect event for given type.
get_package_snapshot(width: int | None = None, height: int | None = None, dt: datetime | None = None) -> bytes | None
async
¶
Gets snapshot from the package camera.
Datetime of screenshot is approximate. It may be +/- a few seconds.
get_ptz_patrols() -> list[PTZPatrol]
async
¶
Get PTZ Patrols for camera.
get_ptz_presets() -> list[PTZPreset]
async
¶
Get PTZ Presets for camera.
get_public_api_snapshot(high_quality: bool | None = None, package: bool = False) -> bytes | None
async
¶
Gets snapshot for camera using public API; package=True fetches the package camera.
get_rtsps_streams() -> RTSPSStreams | None
async
¶
Gets existing RTSPS streams for camera using public API.
get_snapshot(width: int | None = None, height: int | None = None, dt: datetime | None = None) -> bytes | None
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: Path | None = None, iterator_callback: IteratorCallback | None = None, progress_callback: ProgressCallback | None = None, chunk_size: int = 65536, fps: int | None = None) -> bytes | None
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 with the given FPS
value. Protect app gives the options for 60x (fps=4), 120x (fps=8), 300x
(fps=20), and 600x (fps=40).
play_audio(content_url: str, ffmpeg_path: Path | None = None, blocking: bool = True, *, use_public_api: bool = True) -> None
async
¶
Plays audio to a camera through its speaker.
Uses PyAV (libav) for audio encoding - compatible with Home Assistant.
| Text Only | |
|---|---|
1 2 3 4 | |
ptz_goto_preset_public(*, slot: int) -> None
async
¶
Move PTZ camera to preset position using public API.
ptz_patrol_start_public(*, slot: int) -> None
async
¶
Start a PTZ patrol using public API.
ptz_patrol_stop_public() -> None
async
¶
Stop the active PTZ patrol using public API.
set_animal_detection(enabled: bool) -> None
async
¶
Toggles animal smart detection. Requires camera to have smart detection
set_animal_detection_public(enabled: bool) -> None
async
¶
Toggle animal smart detection via public API.
set_baby_cry_detection(enabled: bool) -> None
async
¶
Toggles baby_cry smart detection. Requires camera to have smart detection
set_baby_cry_detection_public(enabled: bool) -> None
async
¶
Toggle baby cry audio detection via public API.
set_bark_detection(enabled: bool) -> None
async
¶
Toggles bark smart detection. Requires camera to have smart detection
set_bark_detection_public(enabled: bool) -> None
async
¶
Toggle bark audio detection via public API.
set_burglar_detection_public(enabled: bool) -> None
async
¶
Toggle burglar audio detection via public API.
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_car_horn_detection_public(enabled: bool) -> None
async
¶
Toggle car horn audio detection via public API.
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_co_detection_public(enabled: bool) -> None
async
¶
Toggle CO audio detection via public API.
set_color_night_vision(enabled: bool) -> None
async
¶
Sets Color Night Vision on camera
set_face_detection(enabled: bool) -> None
async
¶
Toggles face smart detection. Requires camera to have smart detection
set_face_detection_public(enabled: bool) -> None
async
¶
Toggle face smart detection via public API.
set_flood_led_public(enabled: bool) -> None
async
¶
Set flood LED via public API.
set_glass_break_detection(enabled: bool) -> None
async
¶
Toggles glass_break smart detection. Requires camera to have smart detection
set_glass_break_detection_public(enabled: bool) -> None
async
¶
Toggle glass break audio detection via public API.
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_hdr_mode_public(mode: PublicHdrMode) -> None
async
¶
Set HDR mode via public API.
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_message_public(text_type: DoorbellMessageType, text: str | None = None, reset_at: datetime | None | DEFAULT_TYPE = DEFAULT) -> None
async
¶
Set doorbell LCD message via public API.
text is required for CUSTOM_MESSAGE and IMAGE, and must be omitted
for DO_NOT_DISTURB and LEAVE_PACKAGE_AT_DOOR. reset_at controls
when the message is cleared: omit for the NVR default, pass None
for "forever", or pass a specific datetime.
set_lcd_text(text_type: DoorbellMessageType | None, text: str | None = None, reset_at: 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_license_plate_detection_public(enabled: bool) -> None
async
¶
Toggle license plate smart detection via public API.
set_mic_volume(level: int) -> None
async
¶
Sets the mic sensitivity level on camera
set_mic_volume_public(level: float) -> None
async
¶
Set microphone volume via public API.
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
set_osd_date_public(enabled: bool) -> None
async
¶
Toggle date overlay (OSD) via public API.
set_osd_logo(enabled: bool) -> None
async
¶
Sets whether the UniFi logo is in the On Screen Display
set_osd_logo_public(enabled: bool) -> None
async
¶
Toggle logo overlay (OSD) via public API.
set_osd_name(enabled: bool) -> None
async
¶
Sets whether camera name is in the On Screen Display
set_osd_name_public(enabled: bool) -> None
async
¶
Toggle name overlay (OSD) via public API.
set_osd_nerd_mode_public(enabled: bool) -> None
async
¶
Toggle bitrate/debug overlay (OSD) via public API.
set_osd_overlay_location_public(location: OsdOverlayLocation) -> None
async
¶
Set OSD overlay location via public API.
set_package_detection(enabled: bool) -> None
async
¶
Toggles package smart detection. Requires camera to have smart detection
set_package_detection_public(enabled: bool) -> None
async
¶
Toggle package smart detection via public API.
set_person_detection(enabled: bool) -> None
async
¶
Toggles person smart detection. Requires camera to have smart detection
set_person_detection_public(enabled: bool) -> None
async
¶
Toggle person smart detection via public API.
set_person_track(enabled: bool) -> None
async
¶
Sets person tracking on camera
set_privacy(enabled: bool, mic_level: int | None = None, recording_mode: RecordingMode | None = None, reenable_global: bool = False) -> None
async
¶
Adds/removes a privacy zone that blacks out the whole camera.
set_recording_mode(mode: RecordingMode) -> None
async
¶
Sets recording mode on camera
set_ring_volume(level: int) -> None
async
¶
Sets the doorbell ring volume. Requires camera to be a doorbell
set_siren_detection(enabled: bool) -> None
async
¶
Toggles siren smart detection. Requires camera to have smart detection
set_siren_detection_public(enabled: bool) -> None
async
¶
Toggle siren audio detection via public API.
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_smoke_detection_public(enabled: bool) -> None
async
¶
Toggle smoke audio detection via public API.
set_speaker_volume(level: int) -> None
async
¶
Sets the speaker output volume 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_speaking_detection_public(enabled: bool) -> None
async
¶
Toggle speaking audio detection via public API.
set_status_light(enabled: bool) -> None
async
¶
Sets status indicicator light on camera
set_status_light_public(enabled: bool) -> None
async
¶
Set status LED via public API.
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_vehicle_detection_public(enabled: bool) -> None
async
¶
Toggle vehicle smart detection via public API.
set_video_mode(mode: VideoMode) -> None
async
¶
Sets video mode on camera
set_video_mode_public(mode: VideoMode) -> None
async
¶
Set video mode via public API.
set_volume(level: int) -> None
async
¶
Sets the general volume level on camera. Requires camera to have speakers
set_wdr_level(level: int) -> None
async
¶
Sets WDR (Wide Dynamic Range) on camera
set_welcome_led_public(enabled: bool) -> None
async
¶
Set welcome LED via public API.
stop_audio() -> None
async
¶
Stop currently playing audio.
wait_until_audio_completes() -> None
async
¶
Awaits stream completion of audio.
CameraChannel
¶
Bases: ProtectBaseObject
rtsps_quality: ChannelQuality | None
property
¶
RTSPS quality tier for this channel (id 0→HIGH, 1→MEDIUM, 2→LOW, 3→PACKAGE).
ChannelQuality
¶
Bases: UnknownValuesEnumMixin, StrEnum
RTSPS channel quality (qualities field on rtsps-stream endpoints).
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, ringtone_id: str | None = None, track_no: int | None = None) -> None
async
¶
Plays chime tone.
| Text Only | |
|---|---|
1 2 3 4 5 6 | |
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.
.. deprecated::
Use :meth:set_ring_settings_public instead. This method uses
the private API.
set_repeat_times_for_camera(camera: Camera, value: int) -> None
async
¶
Set repeat times on chime for a specific camera.
.. deprecated::
Use :meth:set_ring_settings_public instead. This method uses
the private API.
set_repeat_times_for_camera_public(camera: Camera, value: int) -> None
async
¶
Set the ring repeat times for a specific camera using public API.
This is the preferred method to change ring repeat times as it uses the official public API.
| Text Only | |
|---|---|
1 2 | |
| Text Only | |
|---|---|
1 2 | |
set_ring_settings_public(ring_settings: list[PublicApiChimeRingSettingRequest]) -> None
async
¶
Update ring settings using public API.
This is the preferred method to change ring volume per camera as it uses the official public API.
| Text Only | |
|---|---|
1 2 3 4 5 | |
Example:¶
| Text Only | |
|---|---|
1 2 3 4 5 6 7 8 | |
set_volume(level: int) -> None
async
¶
Set the speaker volume on chime.
.. deprecated::
Use :meth:set_volume_for_camera_public instead. This method
updates the speaker volume but not the doorbell ring volume.
set_volume_for_camera(camera: Camera, level: int) -> None
async
¶
Set the ring volume on chime for a specific camera.
.. deprecated::
Use :meth:set_volume_for_camera_public instead. This method uses
the private API which may not properly update the ring volume.
set_volume_for_camera_public(camera: Camera, level: int) -> None
async
¶
Set the ring volume for a specific camera using public API.
This is the preferred method to change ring volume as it uses the official public API and properly updates the doorbell ring volume.
| Text Only | |
|---|---|
1 2 | |
| Text Only | |
|---|---|
1 2 | |
DeviceState
¶
Bases: UnknownValuesEnumMixin, StrEnum
Public-API device connection state (state field).
Event
¶
Bases: ProtectModelWithId
get_animated_thumbnail(width: int | None = None, height: int | None = None, *, speedup: int = 10) -> bytes | None
async
¶
Gets animated thumbnail for event
get_detected_thumbnail() -> EventDetectedThumbnail | None
¶
Gets best detected thumbnail for event (UFP 6.x+).
Returns the thumbnail marked with clockBestWall, which indicates the optimal frame for this detection (highest confidence, best angle, etc.).
Returns:
| Type | Description |
|---|---|
EventDetectedThumbnail | None
|
EventDetectedThumbnail with the best detection frame, or None if: |
EventDetectedThumbnail | None
|
|
EventDetectedThumbnail | None
|
|
EventDetectedThumbnail | None
|
|
Example usage
License Plate Recognition¶
thumbnail = event.get_detected_thumbnail() if thumbnail and thumbnail.group: ... plate = thumbnail.group.matched_name # "ABC123" ... confidence = thumbnail.group.confidence # 95 ... if thumbnail.attributes: ... color = thumbnail.attributes.get_value("color") # "white" ... vehicle = thumbnail.attributes.get_value("vehicleType") # "sedan"
Face Detection¶
thumbnail = event.get_detected_thumbnail() if thumbnail and thumbnail.group: ... face_name = thumbnail.group.matched_name # "John Doe" ... confidence = thumbnail.group.confidence # 87
get_heatmap() -> bytes | None
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: int | None = None, height: int | None = None) -> bytes | None
async
¶
Gets thumbnail for event
get_video(channel_index: int = 0, output_file: Path | None = None, iterator_callback: IteratorCallback | None = None, progress_callback: ProgressCallback | None = None, chunk_size: int = 65536) -> bytes | None
async
¶
Get the MP4 video clip for this given event
| Text Only | |
|---|---|
1 | |
Will raise an exception if event does not have a camera, end time or the channel index is wrong.
FixSizeOrderedDict
¶
Fob
¶
FobAwayState
¶
Bases: UnknownValuesEnumMixin, StrEnum
Key-fob presence/away state (awayState field).
FobButton
¶
Bases: UnknownValuesEnumMixin, StrEnum
Key-fob button kinds (featureFlags.buttons items).
Light
¶
Bases: ProtectMotionDeviceModel
camera: Camera | None
property
¶
Paired Camera will always be none if no camera is paired
set_duration(duration: timedelta) -> None
async
¶
Sets motion sensitivity
set_duration_public(duration: timedelta) -> None
async
¶
Set how long the light stays on after motion (15s-900s) via public API.
set_flood_light(enabled: bool) -> None
async
¶
Sets the flood light (force on) for the light
set_flood_light_public(enabled: bool) -> None
async
¶
Force the flood light on/off via public API.
set_led_level(led_level: int) -> None
async
¶
Sets the LED level for the light
set_led_level_public(led_level: float) -> None
async
¶
Set the LED brightness level via public API.
set_light(enabled: bool, led_level: int | None = None) -> None
async
¶
Force turns on/off the light
set_light_mode_public(mode: LightModeType, enable_at: LightModeEnableType | None = None) -> None
async
¶
Set the lighting trigger mode (and optional schedule) via public API.
set_light_settings(mode: LightModeType, enable_at: LightModeEnableType | None = None, duration: timedelta | None = None, sensitivity: int | None = None) -> None
async
¶
Updates various Light settings.
| Text Only | |
|---|---|
1 2 3 4 | |
set_light_settings_public(mode: LightModeType, enable_at: LightModeEnableType | None = None, duration: timedelta | None = None, sensitivity: int | None = None) -> None
async
¶
Update mode, enable schedule, duration and PIR sensitivity via public API.
set_name_public(name: str) -> None
async
¶
Set light name via public API.
set_paired_camera(camera: Camera | None) -> None
async
¶
Sets the camera paired with the light
set_sensitivity(sensitivity: int) -> None
async
¶
Sets motion sensitivity
set_sensitivity_public(sensitivity: int) -> None
async
¶
Set PIR motion sensitivity via public API.
set_status_light(enabled: bool) -> None
async
¶
Sets the status indicator light for the light
set_status_light_public(enabled: bool) -> None
async
¶
Toggle the status indicator LED via public API.
LinkStation
¶
Bases: PublicDeviceModel
Public API link station / alarm hub.
A single wire schema (modelKey: "linkstation") covers both the
/v1/link-stations and /v1/alarm-hubs endpoints. The
:attr:is_alarm_hub flag distinguishes the two; alarm_hub is only
populated when :attr:is_alarm_hub is True.
alarm_hub_armed: OnOffState | None
property
¶
Return the typed armed flag, or None when the field is absent.
alarm_hub_battery: AlarmHubBattery | None
property
¶
Return the typed backup-battery status, or None when absent.
alarm_hub_cover: AlarmHubCover | None
property
¶
Return the typed tamper-cover status, or None when absent.
alarm_hub_inputs: dict[int, AlarmHubInput]
property
¶
Return input zones keyed by numeric id; non-integer keys are skipped.
alarm_hub_outputs: dict[int, AlarmHubOutput]
property
¶
Return output channels keyed by numeric id; non-integer keys are skipped.
set_name(name: str) -> LinkStation
async
¶
Rename via the matching endpoint for the device's role.
trigger_output(output_id: int, *, enable: bool | None = None, delay: int | None = None, duration: int | None = None) -> None
async
¶
Trigger an alarm-hub output channel. Raises if this is not an alarm hub.
unifi_dict_conversions() -> dict[str, object | Callable[[Any], Any]]
cached
classmethod
¶
Parse the lastEvent epoch-ms wire value into datetime.
Liveview
¶
Bases: ProtectModelWithId
owner: User | None
property
¶
Owner of liveview.
Will be none if the user only has read only access and it was not made by their user.
LiveviewCycleMode
¶
Bases: UnknownValuesEnumMixin, StrEnum
Public-API liveview slot cycle mode (slots[].cycleMode field).
ModelType
¶
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_face_detection_on: bool
property
¶
Is Face Detection available and enabled?
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
¶
[DEPRECATED] Always returns False. Will be removed after HA 2025.8.0.
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 analytics 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
set_global_osd_logo(enabled: bool) -> None
async
¶
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
NvrArmMode
¶
Bases: ProtectBaseObject
Current arm-manager state embedded in the NVR object (armMode field).
Returned by GET /v1/nvrs as part of the NVR payload. All fields
that may legitimately be null on the wire are typed as Optional
for forward-compatibility.
NvrArmModeStatus
¶
Bases: UnknownValuesEnumMixin, StrEnum
Arm-manager status values embedded in the NVR armMode field.
OnOffState
¶
Bases: UnknownValuesEnumMixin, StrEnum
Generic on/off wire state used by several alarm-hub fields.
OsdOverlayLocation
¶
Bases: UnknownValuesEnumMixin, StrEnum
On-screen-display overlay location (osdSettings.overlayLocation).
Carries an UNKNOWN member so values added by newer firmware coerce
to UNKNOWN instead of raising during Camera deserialization.
PermissionNode
¶
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: str | None = 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_dictto convert UFP JSON to a more Pythonic formatted dict (camel case to snake case) - Add attrs with matching Pythonic name and they will automatically be populated from the UFP JSON if passed in to the constructor
- Provides
.unifi_dictto 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: ProtectApiClient | None = 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: ProtectApiClient | None = None, **data: Any) -> Self
classmethod
¶
Main constructor for ProtectBaseObject
| Text Only | |
|---|---|
1 2 | |
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: dict[str, Any] | None = None, exclude: set[str] | None = 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 | |
unifi_dict_conversions() -> dict[str, object | Callable[[Any], Any]]
cached
classmethod
¶
Helper method for overriding in child classes for converting UFP JSON data to Python data types.
Return format is { "ufpJsonName": Callable[[Any], Any] }
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_dictfor any child UFP objects
| Text Only | |
|---|---|
1 | |
update_from_dict(data: dict[str, Any]) -> Self
¶
Updates current object from a cleaned UFP JSON dict.
The api client is injected into each dict for any child UFP objects that are detected.
ProtectDeviceIdentity
¶
Bases: Protocol
Identity surface shared by the private and public device / NVR model trees.
Consumers that handle "the NVR" or "a camera" generically can type against
this instead of cast()-ing between the unrelated private (NVR /
Camera / ...) and public (PublicNVR / PublicCamera / ...) types.
mac and type are Optional because the public tree omits them on
older firmware.
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
¶
Emits 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 | |
ProtectWSPayloadFormat
¶
Bases: int, Enum
Websocket Payload formats.
PublicArmScheduleDict
¶
Bases: TypedDict
Arm-profile schedule entry (write shape). Fields are cron expressions.
PublicBootstrap
dataclass
¶
In-memory cache of the Public Integration API resources.
All device dicts map id -> object. Empty by default; populated by
:meth:ProtectApiClient.update_public.
Staleness on websocket reconnect. While the devices/events websocket
is connected, incoming add/update/remove messages are merged
into the cache. If the websocket drops and reconnects, any messages
emitted during the gap are lost. :class:ProtectApiClient automatically
schedules an :meth:~ProtectApiClient.update_public refresh on
reconnect (the initial connect does not trigger a refresh).
alarm_hubs: dict[str, LinkStation]
property
¶
Subset of :attr:link_stations filtered to alarm hubs.
arm_mode: NvrArmMode | None
property
¶
Current arm-manager state. Shortcut for nvr.arm_mode.
Returns None when the NVR cache hasn't been primed yet, when the
firmware does not expose the alarm manager, or when the alarm
manager is set to global.
__post_init__() -> None
¶
Validate cache bounds used by event eviction logic.
apply_fetch_result(attr: str, objs: list[ProtectModelWithId]) -> None
¶
Merge fetched objects into self.<attr> without wholesale replace.
Used by :meth:ProtectApiClient.update_public so that add/
update/remove WS messages arriving concurrently with the
HTTP fetch are not clobbered. IDs present in objs overwrite
the cache entry; IDs absent from objs but present in the
cache are removed.
get(model_type: ModelType, obj_id: str) -> ProtectModelWithId | None
¶
Look up a cached device by model type and id.
get_device_mac(device_id: str) -> str | None
¶
Resolve a device id to its mac across the public device stores.
process_devices_ws_message(api: ProtectApiClient, data: dict[str, Any]) -> tuple[ModelType | None, ProtectModelWithId | None, ProtectModelWithId | None]
¶
Apply a public devices WS payload to the cache.
Back-compat façade over :meth:process_devices_ws_messages: returns
the first expanded result's (model_type, new_obj, old_obj) 3-tuple,
or (None, None, None) when nothing was produced. Callers that need
per-device frames for bulk envelopes should use the plural form.
update messages carry partial diffs — only the changed
fields. They are merged into the existing cached object via
:meth:ProtectBaseObject.update_from_dict; reconstructing from a
partial payload would fail strict validation for required fields.
process_devices_ws_messages(api: ProtectApiClient, data: dict[str, Any]) -> list[DeviceWSResult]
¶
Apply a public devices WS frame to the cache, expanding bulk forms.
The bulk envelopes (devicesAdd / devicesBulkUpdate /
devicesBulkRemove) share a single item whose id is a list
of ids with one shared modelKey and payload. This fans that out to
one :class:DeviceWSResult per id (each carrying a scalar-id
item); a single-id frame yields a one-element list. An empty
id array yields an empty list.
process_events_ws_message(api: ProtectApiClient, data: dict[str, Any]) -> EventsFrameResult
¶
Apply a public events WS payload to the event cache.
Returns an :class:EventsFrameResult (a tuple-compatible
NamedTuple of new_event, old_event, model_updates).
new_event /
old_event may be None; old_event is a pre-merge snapshot
of the cached event taken before this frame is applied — update
merges its partial diff into the cached object in place, so without
the snapshot old and new would be the same mutated instance.
The snapshot lets a consumer detect the open→closed transition
(old.end is None and new.end is not None) and reject retransmits
idempotently.
model_updates are devices-WS update messages for any camera
whose derived detection booleans net-flipped over this frame — the
first-class device-model outputs of processing the events frame. The
api handler emits them through the standard devices channel with no
knowledge that they originated from a detection event.
supports_device(model_type: ModelType) -> bool
¶
Return whether model_type maps to a public device store.
PublicBridge
¶
Bases: PublicDeviceModel
Public API bridge device.
ModelType.BRIDGE is already owned by the private :class:Bridge class in
MODEL_TO_CLASS; this public counterpart is routed via a dedicated factory
on :class:~uiprotect.data.public_bootstrap.PublicBootstrap instead.
PublicCamera
¶
Bases: PublicDeviceModel
Public API camera device (GET /v1/cameras).
hdr_mode_display: Literal['auto', 'off', 'always']
property
¶
HDR mode as shown in the Protect interface (inverse of hdr_type).
is_animal_currently_detected: bool
property
¶
Is an animal currently being detected.
is_animal_detection_on: bool
property
¶
Is animal smart detection enabled.
is_audio_currently_detected: bool
property
¶
Is an audio smart-detect event currently active.
is_baby_cry_currently_detected: bool
property
¶
Is a baby cry currently being detected.
is_baby_cry_detection_on: bool
property
¶
Is baby cry smart detection enabled.
is_bark_currently_detected: bool
property
¶
Is a bark currently being detected.
is_bark_detection_on: bool
property
¶
Is bark smart detection enabled.
is_car_alarm_currently_detected: bool
property
¶
Is a car alarm currently being detected.
is_car_alarm_detection_on: bool
property
¶
Is car alarm smart detection enabled.
is_car_horn_currently_detected: bool
property
¶
Is a car horn currently being detected.
is_car_horn_detection_on: bool
property
¶
Is car horn smart detection enabled.
is_cmonx_currently_detected: bool
property
¶
Is a CO alarm currently being detected.
is_co_detection_on: bool
property
¶
Is CO alarm smart detection enabled.
is_face_detection_on: bool
property
¶
Is face smart detection enabled.
is_glass_break_currently_detected: bool
property
¶
Is glass breaking currently being detected.
is_glass_break_detection_on: bool
property
¶
Is glass break smart detection enabled.
is_high_fps_enabled: bool
property
¶
Is the camera running in high-FPS video mode.
is_license_plate_detection_on: bool
property
¶
Is license plate smart detection enabled.
is_motion_detected: bool
property
¶
Is a motion event currently active.
is_package_detection_on: bool
property
¶
Is package smart detection enabled.
is_person_currently_detected: bool
property
¶
Is a person currently being detected.
is_person_detection_on: bool
property
¶
Is person smart detection enabled.
is_siren_currently_detected: bool
property
¶
Is a siren currently being detected.
is_siren_detection_on: bool
property
¶
Is siren smart detection enabled.
is_smart_currently_detected: bool
property
¶
Is a smart-detect event currently active.
is_smoke_currently_detected: bool
property
¶
Is a smoke alarm currently being detected.
is_smoke_detection_on: bool
property
¶
Is smoke alarm smart detection enabled.
is_speaking_currently_detected: bool
property
¶
Is speaking currently being detected.
is_speaking_detection_on: bool
property
¶
Is speaking smart detection enabled.
is_vehicle_currently_detected: bool
property
¶
Is a vehicle currently being detected.
is_vehicle_detection_on: bool
property
¶
Is vehicle smart detection enabled.
hardware_stream_qualities() -> list[ChannelQuality]
¶
Stream qualities the camera hardware supports (not the server's available list).
set_animal_detection(enabled: bool) -> PublicCamera
async
¶
Toggle animal smart detection via the public API.
set_baby_cry_detection(enabled: bool) -> PublicCamera
async
¶
Toggle baby cry audio detection via the public API.
set_bark_detection(enabled: bool) -> PublicCamera
async
¶
Toggle bark audio detection via the public API.
set_burglar_detection(enabled: bool) -> PublicCamera
async
¶
Toggle burglar audio detection via the public API.
set_car_horn_detection(enabled: bool) -> PublicCamera
async
¶
Toggle car horn audio detection via the public API.
set_co_detection(enabled: bool) -> PublicCamera
async
¶
Toggle CO audio detection via the public API.
set_face_detection(enabled: bool) -> PublicCamera
async
¶
Toggle face smart detection via the public API.
set_flood_led(enabled: bool) -> PublicCamera
async
¶
Set the flood LED via the public API.
set_glass_break_detection(enabled: bool) -> PublicCamera
async
¶
Toggle glass break audio detection via the public API.
set_hdr_mode(mode: PublicHdrMode) -> PublicCamera
async
¶
Set HDR mode via the public API.
set_lcd_message(text_type: DoorbellMessageType, text: str | None = None, reset_at: datetime | None | DEFAULT_TYPE = DEFAULT) -> PublicCamera
async
¶
Set the doorbell LCD message via the public API.
text is required for CUSTOM_MESSAGE and IMAGE and must be omitted
otherwise. reset_at controls when the message clears: omit for the
NVR default, pass None for "forever", or a specific datetime.
set_license_plate_detection(enabled: bool) -> PublicCamera
async
¶
Toggle license plate smart detection via the public API.
set_mic_volume(level: int) -> PublicCamera
async
¶
Set microphone volume (1-100) via the public API.
set_osd_date(enabled: bool) -> PublicCamera
async
¶
Toggle the date overlay (OSD) via the public API.
set_osd_logo(enabled: bool) -> PublicCamera
async
¶
Toggle the logo overlay (OSD) via the public API.
set_osd_name(enabled: bool) -> PublicCamera
async
¶
Toggle the name overlay (OSD) via the public API.
set_osd_nerd_mode(enabled: bool) -> PublicCamera
async
¶
Toggle the bitrate/debug overlay (OSD) via the public API.
set_osd_overlay_location(location: OsdOverlayLocation) -> PublicCamera
async
¶
Set the OSD overlay location via the public API.
set_package_detection(enabled: bool) -> PublicCamera
async
¶
Toggle package smart detection via the public API.
set_person_detection(enabled: bool) -> PublicCamera
async
¶
Toggle person smart detection via the public API.
set_siren_detection(enabled: bool) -> PublicCamera
async
¶
Toggle siren audio detection via the public API.
set_smoke_detection(enabled: bool) -> PublicCamera
async
¶
Toggle smoke audio detection via the public API.
set_speaking_detection(enabled: bool) -> PublicCamera
async
¶
Toggle speaking audio detection via the public API.
set_status_light(enabled: bool) -> PublicCamera
async
¶
Set the status LED via the public API.
set_vehicle_detection(enabled: bool) -> PublicCamera
async
¶
Toggle vehicle smart detection via the public API.
set_video_mode(mode: VideoMode) -> PublicCamera
async
¶
Set the video mode via the public API.
set_welcome_led(enabled: bool) -> PublicCamera
async
¶
Set the welcome LED via the public API.
PublicChime
¶
Bases: PublicDeviceModel
Public API chime device (GET /v1/chimes).
set_repeat_times_for_camera(camera_id: str, value: int) -> PublicChime
async
¶
Set the ring repeat count for one paired camera via the public API.
set_ring_settings(ring_settings: list[PublicApiChimeRingSettingRequest]) -> PublicChime
async
¶
Replace the full per-camera ring settings via the public API.
set_volume_for_camera(camera_id: str, level: int) -> PublicChime
async
¶
Set the ring volume for one paired camera via the public API.
PublicDeviceModel
¶
PublicDoorbellCustomImage
¶
PublicDoorbellSettings
¶
Bases: ProtectBaseObject
Doorbell settings exposed by the Public Integration API (GET /v1/nvrs).
Intentionally separate from the private :class:~uiprotect.data.nvr.DoorbellSettings
which carries additional private-API-only fields (allMessages, typed
timedelta, etc.).
All fields have defaults because the doorbellSettings OpenAPI schema
declares no required array — fields may be absent on older firmware or
in partial WS update diffs.
PublicEvent
¶
Bases: ProtectModelWithId
Event delivered over the Public Integration API events websocket.
unifi_dict_conversions() -> dict[str, object | Callable[[Any], Any]]
cached
classmethod
¶
Parse the start / end wire timestamps into datetime.
PublicEventMetadata
¶
Bases: ProtectBaseObject
Union of every public *Event metadata field, all optional.
unifi_dict(data: dict[str, Any] | None = None, exclude: set[str] | None = None) -> dict[str, Any]
¶
Serialise, dropping None fields and re-wrapping metadata envelopes.
unifi_dict_to_dict(data: dict[str, Any]) -> dict[str, Any]
classmethod
¶
Collapse the {text|number: value} metadata envelopes to inner values.
PublicFile
¶
PublicFingerprintMetadata
¶
PublicLight
¶
Bases: PublicDeviceModel
Public API light device (GET /v1/lights).
set_duration(duration: timedelta) -> PublicLight
async
¶
Set how long the light stays on after motion (15s-900s) via the public API.
set_flood_light(enabled: bool) -> PublicLight
async
¶
Force the flood light on/off via the public API.
set_led_level(led_level: int) -> PublicLight
async
¶
Set the indicator LED brightness (1-6) via the public API.
set_light_mode(mode: LightModeType, enable_at: LightModeEnableType | None = None) -> PublicLight
async
¶
Set the lighting trigger mode (and optional schedule) via the public API.
set_light_settings(mode: LightModeType, enable_at: LightModeEnableType | None = None, duration: timedelta | None = None, sensitivity: int | None = None) -> PublicLight
async
¶
Update mode, schedule, duration and PIR sensitivity via the public API.
set_name(name: str) -> PublicLight
async
¶
Set the light name via the public API.
set_sensitivity(sensitivity: int) -> PublicLight
async
¶
Set PIR motion sensitivity (0-100) via the public API.
set_status_light(enabled: bool) -> PublicLight
async
¶
Toggle the status indicator LED via the public API.
PublicLiveview
¶
Bases: ProtectModelWithId
Public API liveview.
owner is a flat userId string (the spec types it as $ref: userId,
which is type: string) — not an embedded user object. layout is the
number of slots the liveview contains (spec: number, 1..26); the field name
matches the wire key exactly.
PublicLiveviewSlot
¶
PublicLiveviewSlotDict
¶
Bases: TypedDict
Liveview slot (write shape).
PublicNVR
¶
Bases: PublicIdentifiedModel
NVR device as exposed by the Public Integration API (GET /v1/nvrs).
This model reflects the public schema: id, modelKey, name,
doorbellSettings, and optionally armMode / mac.
name is nullable — the API schema declares it as oneOf: [string, null].
mac is exposed on GET /v1/nvrs from Protect newer than 7.1 and is
None on older firmware that omits the key (and absent from WS
partial-update diffs).
doorbell_settings is None on older firmware that does not yet
expose the doorbellSettings key, and is absent from WS partial-update
diffs (which only require id + modelKey).
arm_mode is None when the firmware does not yet expose the alarm
manager (older releases) and also None when the alarm manager is set
to global (server returns armMode: null). WS device-update diffs that
include armMode are handled automatically by
:meth:~uiprotect.data.base.ProtectBaseObject.update_from_dict without
any manual extraction.
PublicNfcMetadata
¶
PublicSensor
¶
Bases: PublicDeviceModel
Public API sensor device (GET /v1/sensors).
has_feature_flags: bool
property
¶
Whether a capability map was reported; False means unavailable, not empty.
is_leak_detected: bool
property
¶
Whether a leak is detected on either the internal or external channel.
is_tampering_detected: bool
property
¶
Whether the tamper switch is currently triggered.
set_alarm(enabled: bool) -> PublicSensor
async
¶
Toggle the (audio) alarm detection setting via the public API.
set_arm_profile_ids(arm_profile_ids: list[str]) -> PublicSensor
async
¶
Set the arm-profile ids associated with the sensor via the public API.
set_custom_sensitivity_when_armed(enabled: bool) -> PublicSensor
async
¶
Toggle custom armed sensitivity via the public API.
set_glass_break_settings(*, is_enabled: bool | None = None, sensitivity: float | None = None, sensitivity_when_armed: float | None = None) -> PublicSensor
async
¶
Update glass-break detection settings via the public API.
set_glass_break_status(enabled: bool) -> PublicSensor
async
¶
Toggle glass-break detection via the public API.
set_humidity_settings(*, is_enabled: bool | None = None, low_threshold: float | None = None, high_threshold: float | None = None, margin: int | None = None) -> PublicSensor
async
¶
Update humidity alert settings via the public API.
set_humidity_status(enabled: bool) -> PublicSensor
async
¶
Toggle humidity alerts via the public API.
set_light_settings(*, is_enabled: bool | None = None, low_threshold: float | None = None, high_threshold: float | None = None, margin: int | None = None) -> PublicSensor
async
¶
Update light (lux) alert settings via the public API.
set_light_status(enabled: bool) -> PublicSensor
async
¶
Toggle light (lux) alerts via the public API.
set_motion_sensitivity(sensitivity: float) -> PublicSensor
async
¶
Set motion detection sensitivity via the public API.
set_motion_settings(*, is_enabled: bool | None = None, sensitivity: float | None = None, sensitivity_when_armed: float | None = None) -> PublicSensor
async
¶
Update motion detection settings via the public API.
set_motion_status(enabled: bool) -> PublicSensor
async
¶
Toggle motion detection via the public API.
set_name(name: str) -> PublicSensor
async
¶
Set the sensor name via the public API.
set_schedule_mode(mode: SensorScheduleMode) -> PublicSensor
async
¶
Set the arm-schedule mode via the public API.
set_temperature_settings(*, is_enabled: bool | None = None, low_threshold: float | None = None, high_threshold: float | None = None, margin: float | None = None) -> PublicSensor
async
¶
Update temperature alert settings via the public API.
set_temperature_status(enabled: bool) -> PublicSensor
async
¶
Toggle temperature alerts via the public API.
supports(capability: SensorFeatureCapability) -> bool
¶
Whether the sensor advertises capability (False without a feature map).
PublicSensorFeatureCapability
¶
PublicSensorFeatureFlags
¶
Bases: ProtectBaseObject
Per-sensor capability map. An absent key means the capability is unsupported.
PublicSirenStatus
¶
Bases: ProtectBaseObject
turn_off_at: datetime | None
property
¶
When the siren is expected to stop playing.
Returns None when the siren is idle — either because activated_at
/ duration are not set, or because is_active is False (e.g.
after a manual stop, where the server may leave the timing fields
populated). Derived from the websocket payload so no extra API call is
needed — HA can compare against datetime.now(UTC) instead of
maintaining its own timer.
PublicUlpUser
¶
PublicUser
¶
PublicViewer
¶
Bases: PublicDeviceModel
Public API viewer device.
ModelType.VIEWPORT is already owned by the private :class:Viewer class
in MODEL_TO_CLASS; this public counterpart is routed via a dedicated
factory on :class:~uiprotect.data.public_bootstrap.PublicBootstrap instead.
The wire field liveview is a flat liveviewId string (nullable);
snake-cased to :attr:liveview_id via :meth:_get_unifi_remaps.
RTSPSStreams
¶
Bases: ProtectBaseObject
RTSPS stream URLs for a camera.
get_active_stream_qualities() -> list[str]
¶
Get list of currently active RTSPS stream quality levels (only those with stream URLs).
get_available_stream_qualities() -> list[str]
¶
List available RTSPS quality keys from the server.
Returns raw strings; may include values not in :class:ChannelQuality.
get_inactive_stream_qualities() -> list[str]
¶
Get list of inactive RTSPS stream quality levels (supported but not currently active).
get_stream_url(quality: str, srtp: bool = True) -> str | None
¶
Get stream URL for a quality level; srtp=False strips ?enableSrtp.
Relay
¶
Bases: PublicDeviceModel
Public API relay device.
Use :meth:__getitem__ (relay[output_id]) for "fail loud" lookup or
:meth:get_output for the None-returning variant.
__getitem__(output_id: int) -> PublicRelayOutput
¶
Return the output with the given id; raises :class:KeyError if unknown.
activate_output(output_id: int, state: Literal['on', 'off'] | None = None, pulse_duration_ms: int | None = None) -> None
async
¶
Activate / toggle a relay output channel.
get_output(output_id: int) -> PublicRelayOutput | None
¶
Return the output with the given id, or None if not found.
RelayInputActionTrigger
¶
Bases: UnknownValuesEnumMixin, StrEnum
Relay input action trigger condition (inputs[].actionTrigger field).
RelayInputActionType
¶
Bases: UnknownValuesEnumMixin, StrEnum
Relay input action effect (inputs[].actionType field).
RelayInputState
¶
Bases: UnknownValuesEnumMixin, StrEnum
State of a single relay input channel.
RelayOutputRebootState
¶
Bases: UnknownValuesEnumMixin, StrEnum
State the relay output is set to after a reboot/power cycle (rebootState field).
RelayOutputState
¶
Bases: UnknownValuesEnumMixin, StrEnum
State of a single relay output channel (state field).
RelayOutputType
¶
Bases: UnknownValuesEnumMixin, StrEnum
Relay output device type (outputs[].type field).
RingSetting
¶
Bases: ProtectBaseObject
Ring settings for a paired doorbell camera.
camera: Camera | None
property
¶
Paired Camera will always be none if no camera is paired.
to_api_dict(volume: int | None = None, repeat_times: int | None = None) -> PublicApiChimeRingSettingRequest
¶
Convert to API dict format for Public API requests.
| Text Only | |
|---|---|
1 2 3 | |
| Text Only | |
|---|---|
1 | |
Sensor
¶
Bases: ProtectAdoptableDeviceModel
camera: Camera | None
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_public(enabled: bool) -> None
async
¶
Toggle the (audio) alarm detection setting via public API.
set_alarm_status(enabled: bool) -> None
async
¶
Sets the alarm detection type for the sensor
set_arm_profile_ids_public(arm_profile_ids: list[str]) -> None
async
¶
Set the arm-profile ids associated with the sensor via public API.
set_custom_sensitivity_when_armed_public(enabled: bool) -> None
async
¶
Toggle custom armed sensitivity via public API.
set_glass_break_settings_public(*, is_enabled: bool | None = None, sensitivity: float | None = None, sensitivity_when_armed: float | None = None) -> None
async
¶
Update glass-break detection settings via public API.
set_glass_break_status_public(enabled: bool) -> None
async
¶
Toggle glass-break detection via public API.
set_humidity_safe_range(low: float, high: float) -> None
async
¶
Sets the humidity safe range for the sensor
set_humidity_settings_public(*, is_enabled: bool | None = None, low_threshold: float | None = None, high_threshold: float | None = None, margin: int | None = None) -> None
async
¶
Update humidity alert settings via public API.
set_humidity_status(enabled: bool) -> None
async
¶
Sets the humidity detection type for the sensor
set_humidity_status_public(enabled: bool) -> None
async
¶
Toggle humidity alerts via public API.
set_light_safe_range(low: float, high: float) -> None
async
¶
Sets the light safe range for the sensor
set_light_settings_public(*, is_enabled: bool | None = None, low_threshold: float | None = None, high_threshold: float | None = None, margin: int | None = None) -> None
async
¶
Update light (lux) alert settings via public API.
set_light_status(enabled: bool) -> None
async
¶
Sets the light detection type for the sensor
set_light_status_public(enabled: bool) -> None
async
¶
Toggle light (lux) alerts via public API.
set_motion_sensitivity(sensitivity: int) -> None
async
¶
Sets the motion sensitivity for the sensor
set_motion_sensitivity_public(sensitivity: float) -> None
async
¶
Set motion detection sensitivity via public API.
set_motion_settings_public(*, is_enabled: bool | None = None, sensitivity: float | None = None, sensitivity_when_armed: float | None = None) -> None
async
¶
Update motion detection settings via public API.
set_motion_status(enabled: bool) -> None
async
¶
Sets the motion detection type for the sensor
set_motion_status_public(enabled: bool) -> None
async
¶
Toggle motion detection via public API.
set_mount_type(mount_type: MountType) -> None
async
¶
Sets current mount type for sensor
set_name_public(name: str) -> None
async
¶
Set sensor name via public API.
set_paired_camera(camera: Camera | None) -> None
async
¶
Sets the camera paired with the sensor
set_schedule_mode_public(mode: SensorScheduleMode) -> None
async
¶
Set the arm-schedule mode via public API.
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_settings_public(*, is_enabled: bool | None = None, low_threshold: float | None = None, high_threshold: float | None = None, margin: float | None = None) -> None
async
¶
Update temperature alert settings via public API.
set_temperature_status(enabled: bool) -> None
async
¶
Sets the temperature detection type for the sensor
set_temperature_status_public(enabled: bool) -> None
async
¶
Toggle temperature alerts via public API.
SensorAlarmType
¶
Bases: UnknownValuesEnumMixin, StrEnum
Alarm sound of a sensorAlarm / alarmHub* event (metadata.alarmType.text).
SensorFeatureCapability
¶
Bases: StrEnum
A capability a sensor can advertise in :class:PublicSensorFeatureFlags.
Siren
¶
Bases: PublicDeviceModel
Public API siren device.
is_active: bool
property
¶
Whether the siren is currently playing.
The server does not emit a stop event when the siren finishes its
timed run, so sirenStatus.isActive in the WS payload stays
True until the next update. turn_off_at is only set while
the server flag is true and the timing fields are populated, so a
clock check against it catches the timed-expiry case. A manual stop
clears the server flag and turn_off_at becomes None,
falling back to the (now-false) server flag.
play(duration: int | SirenDuration | None = None) -> None
async
¶
Play the siren. duration may be a supported integer or :class:SirenDuration; defaults to 5 seconds.
stop() -> None
async
¶
Stop an active siren.
test_sound(volume: int | None = None) -> None
async
¶
Test the siren sound at the given volume.
SirenConnectionType
¶
Bases: UnknownValuesEnumMixin, StrEnum
Public-API siren wireless connection type (connectionType field).
SirenDuration
¶
Bases: int, Enum
Valid siren play durations in seconds (as accepted by the public API).
Speaker
¶
Bases: PublicDeviceModel
Public API speaker device.
test_sound(volume: int | None = None) -> None
async
¶
Test the speaker sound at the given volume.
SpeakerMode
¶
Bases: UnknownValuesEnumMixin, StrEnum
Public-API speaker mode (speakerState.mode field).
SpeakerStatus
¶
Bases: UnknownValuesEnumMixin, StrEnum
Public-API speaker runtime status (speakerState.status field).
UlpUserStatus
¶
Bases: UnknownValuesEnumMixin, StrEnum
Public-API UniFi Identity (ULP) user status (status field).
User
¶
Bases: ProtectModelWithId
VideoMode
¶
Bases: UnknownValuesEnumMixin, StrEnum
Camera video pipeline mode; unknown wire values coerce to UNKNOWN.
Viewer
¶
Bases: ProtectAdoptableDeviceModel
set_liveview(liveview: Liveview) -> None
async
¶
Set the liveview for this viewer.
.. deprecated::
Use :meth:ProtectApiClient.update_viewer_public instead; the
public-API counterpart is feature-complete for renaming and
liveview assignment.
set_liveview_public(liveview_id: str | None) -> None
async
¶
Set the viewer liveview via public API. Pass None to clear.
set_name_public(name: str) -> None
async
¶
Set viewer name via public API.
WSPacket
¶
Class to handle a unifi protect websocket packet.
channel_id_for_quality(quality: ChannelQuality) -> int | None
¶
Channel id for an RTSPS quality tier (inverse of quality_for_channel_id).
create_from_unifi_dict(data: dict[str, Any], api: ProtectApiClient | None = None, klass: type[ProtectModel] | None = None, model_type: ModelType | None = None) -> ProtectModel
¶
Convert a UFP JSON dict to the correct Python class.
When model_type is provided (e.g. from WS action headers), modelKey
will be synthesised if absent (Protect 7+).
Raises DataDecodeError if the model cannot be resolved.
quality_for_channel_id(channel_id: int) -> ChannelQuality | None
¶
RTSPS quality tier for a channel id (0→HIGH, 1→MEDIUM, 2→LOW, 3→PACKAGE).
Enums and Types (uiprotect.data.types)¶
AlarmHubBatteryStatus
¶
Bases: UnknownValuesEnumMixin, StrEnum
Alarm-hub backup-battery health (alarmHub.battery.batteryStatus field).
AlarmHubConnectionState
¶
Bases: UnknownValuesEnumMixin, StrEnum
Alarm-hub backup-battery wiring state (alarmHub.battery.connection field).
AlarmHubCoverStatus
¶
Bases: UnknownValuesEnumMixin, StrEnum
Alarm-hub tamper-cover status (alarmHub.cover.status field).
AlarmHubInputContactType
¶
Bases: UnknownValuesEnumMixin, StrEnum
Alarm-hub input contact wiring (alarmHub.input[].type field).
AlarmHubInputStatus
¶
Bases: UnknownValuesEnumMixin, StrEnum
Alarm-hub input zone status (alarmHub.input[].status field).
AlarmHubInputType
¶
Bases: UnknownValuesEnumMixin, StrEnum
Alarm-hub input zone kind (alarmHub.input[].inputType field).
AlarmHubOutputStatus
¶
Bases: UnknownValuesEnumMixin, StrEnum
Alarm-hub output channel status (alarmHub.output[].status field).
AssetFileType
¶
Bases: UnknownValuesEnumMixin, StrEnum
Public-API device asset file kind (/v1/files/{fileType}).
ChannelQuality
¶
Bases: UnknownValuesEnumMixin, StrEnum
RTSPS channel quality (qualities field on rtsps-stream endpoints).
DeviceState
¶
Bases: UnknownValuesEnumMixin, StrEnum
Public-API device connection state (state field).
EventButtonType
¶
Bases: UnknownValuesEnumMixin, StrEnum
Button of a sensorButtonPressed / alarmHubButtonPress event.
Sourced from metadata.button.text.
FixSizeOrderedDict
¶
FobAwayState
¶
Bases: UnknownValuesEnumMixin, StrEnum
Key-fob presence/away state (awayState field).
FobButton
¶
Bases: UnknownValuesEnumMixin, StrEnum
Key-fob button kinds (featureFlags.buttons items).
LiveviewCycleMode
¶
Bases: UnknownValuesEnumMixin, StrEnum
Public-API liveview slot cycle mode (slots[].cycleMode field).
ModelType
¶
NvrArmModeStatus
¶
Bases: UnknownValuesEnumMixin, StrEnum
Arm-manager status values embedded in the NVR armMode field.
OnOffState
¶
Bases: UnknownValuesEnumMixin, StrEnum
Generic on/off wire state used by several alarm-hub fields.
OsdOverlayLocation
¶
Bases: UnknownValuesEnumMixin, StrEnum
On-screen-display overlay location (osdSettings.overlayLocation).
Carries an UNKNOWN member so values added by newer firmware coerce
to UNKNOWN instead of raising during Camera deserialization.
PermissionNode
¶
ProtectWSPayloadFormat
¶
Bases: int, Enum
Websocket Payload formats.
RelayInputActionTrigger
¶
Bases: UnknownValuesEnumMixin, StrEnum
Relay input action trigger condition (inputs[].actionTrigger field).
RelayInputActionType
¶
Bases: UnknownValuesEnumMixin, StrEnum
Relay input action effect (inputs[].actionType field).
RelayInputCircuitState
¶
Bases: UnknownValuesEnumMixin, StrEnum
Relay input circuit state (relayInputChanged metadata.inputState.text).
RelayInputState
¶
Bases: UnknownValuesEnumMixin, StrEnum
State of a single relay input channel.
RelayOutputRebootState
¶
Bases: UnknownValuesEnumMixin, StrEnum
State the relay output is set to after a reboot/power cycle (rebootState field).
RelayOutputState
¶
Bases: UnknownValuesEnumMixin, StrEnum
State of a single relay output channel (state field).
RelayOutputType
¶
Bases: UnknownValuesEnumMixin, StrEnum
Relay output device type (outputs[].type field).
SensorAlarmType
¶
Bases: UnknownValuesEnumMixin, StrEnum
Alarm sound of a sensorAlarm / alarmHub* event (metadata.alarmType.text).
SensorExtremeMetricType
¶
Bases: UnknownValuesEnumMixin, StrEnum
Metric of a sensorExtremeValues event (metadata.sensorType.text).
SirenConnectionType
¶
Bases: UnknownValuesEnumMixin, StrEnum
Public-API siren wireless connection type (connectionType field).
SirenDuration
¶
Bases: int, Enum
Valid siren play durations in seconds (as accepted by the public API).
SmokeTestSource
¶
Bases: UnknownValuesEnumMixin, StrEnum
Origin of a sensorSmokeTest event (flat metadata.source).
SpeakerMode
¶
Bases: UnknownValuesEnumMixin, StrEnum
Public-API speaker mode (speakerState.mode field).
SpeakerStatus
¶
Bases: UnknownValuesEnumMixin, StrEnum
Public-API speaker runtime status (speakerState.status field).
UlpUserStatus
¶
Bases: UnknownValuesEnumMixin, StrEnum
Public-API UniFi Identity (ULP) user status (status field).
VideoMode
¶
Bases: UnknownValuesEnumMixin, StrEnum
Camera video pipeline mode; unknown wire values coerce to UNKNOWN.
get_field_type(annotation: type[Any] | None) -> tuple[type | None, Any]
cached
¶
Extract the origin and type from an annotation.
Public Bootstrap (uiprotect.data.public_bootstrap)¶
UniFi Protect Public Integration API bootstrap.
This is an opt-in, separate cache for the Public Integration API. It is
not populated by :meth:ProtectApiClient.update and does not
touch the private :class:~uiprotect.data.bootstrap.Bootstrap in any way.
Prime/subscribe ordering is a library guarantee, not a caller obligation:
update_public() buffers any public WS frame that arrives while it is
priming and replays it onto the fresh snapshot before returning, so a
subscriber that is already connected never loses an update to the prime
window. Consumers may subscribe and prime in either order:
- Typed (
subscribe_devices/subscribe_events): deliver merged public models, so they require a primed cache and raiseRuntimeErrorif it is missing. Usesubscribe_devices_and_prime/subscribe_events_and_primeto subscribe and prime in one call — these connect the websocket before priming so the buffer catches every frame, making the prime-then-subscribe question moot. - Raw (
subscribe_devices_websocket/subscribe_events_websocket): subscribe in any order relative toupdate_public(). Frames that land while priming are held and replayed once the snapshot is applied, so they reach subscribers with a mergednew_objinstead of being dropped.
WS messages that arrive after priming are merged into the fresh cache
normally. An update for an object still not in the cache after a replay
is dropped — the cache catches up on the next update_public() / reconnect
refresh.
WS messages carry partial diffs for update actions; the cache therefore
merges updates into the existing in-memory object instead of reconstructing
it from the partial payload. Only add messages are treated as full
payloads.
DeviceWSResult
dataclass
¶
One expanded per-device outcome of a public devices WS frame.
EventsFrameResult
¶
Bases: NamedTuple
Outputs of applying one public events-WS frame to the cache.
PublicBootstrap
dataclass
¶
In-memory cache of the Public Integration API resources.
All device dicts map id -> object. Empty by default; populated by
:meth:ProtectApiClient.update_public.
Staleness on websocket reconnect. While the devices/events websocket
is connected, incoming add/update/remove messages are merged
into the cache. If the websocket drops and reconnects, any messages
emitted during the gap are lost. :class:ProtectApiClient automatically
schedules an :meth:~ProtectApiClient.update_public refresh on
reconnect (the initial connect does not trigger a refresh).
alarm_hubs: dict[str, LinkStation]
property
¶
Subset of :attr:link_stations filtered to alarm hubs.
arm_mode: NvrArmMode | None
property
¶
Current arm-manager state. Shortcut for nvr.arm_mode.
Returns None when the NVR cache hasn't been primed yet, when the
firmware does not expose the alarm manager, or when the alarm
manager is set to global.
__post_init__() -> None
¶
Validate cache bounds used by event eviction logic.
apply_fetch_result(attr: str, objs: list[ProtectModelWithId]) -> None
¶
Merge fetched objects into self.<attr> without wholesale replace.
Used by :meth:ProtectApiClient.update_public so that add/
update/remove WS messages arriving concurrently with the
HTTP fetch are not clobbered. IDs present in objs overwrite
the cache entry; IDs absent from objs but present in the
cache are removed.
get(model_type: ModelType, obj_id: str) -> ProtectModelWithId | None
¶
Look up a cached device by model type and id.
get_device_mac(device_id: str) -> str | None
¶
Resolve a device id to its mac across the public device stores.
process_devices_ws_message(api: ProtectApiClient, data: dict[str, Any]) -> tuple[ModelType | None, ProtectModelWithId | None, ProtectModelWithId | None]
¶
Apply a public devices WS payload to the cache.
Back-compat façade over :meth:process_devices_ws_messages: returns
the first expanded result's (model_type, new_obj, old_obj) 3-tuple,
or (None, None, None) when nothing was produced. Callers that need
per-device frames for bulk envelopes should use the plural form.
update messages carry partial diffs — only the changed
fields. They are merged into the existing cached object via
:meth:ProtectBaseObject.update_from_dict; reconstructing from a
partial payload would fail strict validation for required fields.
process_devices_ws_messages(api: ProtectApiClient, data: dict[str, Any]) -> list[DeviceWSResult]
¶
Apply a public devices WS frame to the cache, expanding bulk forms.
The bulk envelopes (devicesAdd / devicesBulkUpdate /
devicesBulkRemove) share a single item whose id is a list
of ids with one shared modelKey and payload. This fans that out to
one :class:DeviceWSResult per id (each carrying a scalar-id
item); a single-id frame yields a one-element list. An empty
id array yields an empty list.
process_events_ws_message(api: ProtectApiClient, data: dict[str, Any]) -> EventsFrameResult
¶
Apply a public events WS payload to the event cache.
Returns an :class:EventsFrameResult (a tuple-compatible
NamedTuple of new_event, old_event, model_updates).
new_event /
old_event may be None; old_event is a pre-merge snapshot
of the cached event taken before this frame is applied — update
merges its partial diff into the cached object in place, so without
the snapshot old and new would be the same mutated instance.
The snapshot lets a consumer detect the open→closed transition
(old.end is None and new.end is not None) and reject retransmits
idempotently.
model_updates are devices-WS update messages for any camera
whose derived detection booleans net-flipped over this frame — the
first-class device-model outputs of processing the events frame. The
api handler emits them through the standard devices channel with no
knowledge that they originated from a detection event.
supports_device(model_type: ModelType) -> bool
¶
Return whether model_type maps to a public device store.
Public Devices (uiprotect.data.public_devices)¶
UniFi Protect Public API (Integration) data models.
These models represent resources that are exposed only through the Public
Integration API. They live in a separate module so
that the existing private-API data models (in :mod:uiprotect.data.devices)
are not affected and older Protect installations remain unaffected.
Fields the NVR is contractually required to return are modelled as required;
only fields that are genuinely optional on the wire (bridge link, battery
status on mains-powered devices, siren activation metadata while idle, ...)
are Optional.
AlarmHubBattery
¶
Bases: ProtectBaseObject
Backup battery status of an alarm hub (alarmHub.battery sub-schema).
The battery object declares no required array in the OpenAPI spec,
and a real hub with the backup battery disconnected emits only
connection (omitting charging/voltage/batteryStatus), so
every field is optional.
AlarmHubCover
¶
Bases: ProtectBaseObject
Tamper cover status of an alarm hub (alarmHub.cover sub-schema).
The cover object declares no required array in the OpenAPI spec, so
both fields are optional.
AlarmHubInput
¶
AlarmHubOutput
¶
ArmProfile
¶
Bases: ProtectBaseObject
Public API arm profile (local alarm manager).
Arm profiles are configuration objects, not devices — the
/v1/arm-profiles payload has no modelKey. The class therefore
inherits directly from :class:ProtectBaseObject and carries its own
id field.
Fob
¶
LinkStation
¶
Bases: PublicDeviceModel
Public API link station / alarm hub.
A single wire schema (modelKey: "linkstation") covers both the
/v1/link-stations and /v1/alarm-hubs endpoints. The
:attr:is_alarm_hub flag distinguishes the two; alarm_hub is only
populated when :attr:is_alarm_hub is True.
alarm_hub_armed: OnOffState | None
property
¶
Return the typed armed flag, or None when the field is absent.
alarm_hub_battery: AlarmHubBattery | None
property
¶
Return the typed backup-battery status, or None when absent.
alarm_hub_cover: AlarmHubCover | None
property
¶
Return the typed tamper-cover status, or None when absent.
alarm_hub_inputs: dict[int, AlarmHubInput]
property
¶
Return input zones keyed by numeric id; non-integer keys are skipped.
alarm_hub_outputs: dict[int, AlarmHubOutput]
property
¶
Return output channels keyed by numeric id; non-integer keys are skipped.
set_name(name: str) -> LinkStation
async
¶
Rename via the matching endpoint for the device's role.
trigger_output(output_id: int, *, enable: bool | None = None, delay: int | None = None, duration: int | None = None) -> None
async
¶
Trigger an alarm-hub output channel. Raises if this is not an alarm hub.
unifi_dict_conversions() -> dict[str, object | Callable[[Any], Any]]
cached
classmethod
¶
Parse the lastEvent epoch-ms wire value into datetime.
NvrArmMode
¶
Bases: ProtectBaseObject
Current arm-manager state embedded in the NVR object (armMode field).
Returned by GET /v1/nvrs as part of the NVR payload. All fields
that may legitimately be null on the wire are typed as Optional
for forward-compatibility.
PublicArmScheduleDict
¶
Bases: TypedDict
Arm-profile schedule entry (write shape). Fields are cron expressions.
PublicBridge
¶
Bases: PublicDeviceModel
Public API bridge device.
ModelType.BRIDGE is already owned by the private :class:Bridge class in
MODEL_TO_CLASS; this public counterpart is routed via a dedicated factory
on :class:~uiprotect.data.public_bootstrap.PublicBootstrap instead.
PublicCamera
¶
Bases: PublicDeviceModel
Public API camera device (GET /v1/cameras).
hdr_mode_display: Literal['auto', 'off', 'always']
property
¶
HDR mode as shown in the Protect interface (inverse of hdr_type).
is_animal_currently_detected: bool
property
¶
Is an animal currently being detected.
is_animal_detection_on: bool
property
¶
Is animal smart detection enabled.
is_audio_currently_detected: bool
property
¶
Is an audio smart-detect event currently active.
is_baby_cry_currently_detected: bool
property
¶
Is a baby cry currently being detected.
is_baby_cry_detection_on: bool
property
¶
Is baby cry smart detection enabled.
is_bark_currently_detected: bool
property
¶
Is a bark currently being detected.
is_bark_detection_on: bool
property
¶
Is bark smart detection enabled.
is_car_alarm_currently_detected: bool
property
¶
Is a car alarm currently being detected.
is_car_alarm_detection_on: bool
property
¶
Is car alarm smart detection enabled.
is_car_horn_currently_detected: bool
property
¶
Is a car horn currently being detected.
is_car_horn_detection_on: bool
property
¶
Is car horn smart detection enabled.
is_cmonx_currently_detected: bool
property
¶
Is a CO alarm currently being detected.
is_co_detection_on: bool
property
¶
Is CO alarm smart detection enabled.
is_face_detection_on: bool
property
¶
Is face smart detection enabled.
is_glass_break_currently_detected: bool
property
¶
Is glass breaking currently being detected.
is_glass_break_detection_on: bool
property
¶
Is glass break smart detection enabled.
is_high_fps_enabled: bool
property
¶
Is the camera running in high-FPS video mode.
is_license_plate_detection_on: bool
property
¶
Is license plate smart detection enabled.
is_motion_detected: bool
property
¶
Is a motion event currently active.
is_package_detection_on: bool
property
¶
Is package smart detection enabled.
is_person_currently_detected: bool
property
¶
Is a person currently being detected.
is_person_detection_on: bool
property
¶
Is person smart detection enabled.
is_siren_currently_detected: bool
property
¶
Is a siren currently being detected.
is_siren_detection_on: bool
property
¶
Is siren smart detection enabled.
is_smart_currently_detected: bool
property
¶
Is a smart-detect event currently active.
is_smoke_currently_detected: bool
property
¶
Is a smoke alarm currently being detected.
is_smoke_detection_on: bool
property
¶
Is smoke alarm smart detection enabled.
is_speaking_currently_detected: bool
property
¶
Is speaking currently being detected.
is_speaking_detection_on: bool
property
¶
Is speaking smart detection enabled.
is_vehicle_currently_detected: bool
property
¶
Is a vehicle currently being detected.
is_vehicle_detection_on: bool
property
¶
Is vehicle smart detection enabled.
hardware_stream_qualities() -> list[ChannelQuality]
¶
Stream qualities the camera hardware supports (not the server's available list).
set_animal_detection(enabled: bool) -> PublicCamera
async
¶
Toggle animal smart detection via the public API.
set_baby_cry_detection(enabled: bool) -> PublicCamera
async
¶
Toggle baby cry audio detection via the public API.
set_bark_detection(enabled: bool) -> PublicCamera
async
¶
Toggle bark audio detection via the public API.
set_burglar_detection(enabled: bool) -> PublicCamera
async
¶
Toggle burglar audio detection via the public API.
set_car_horn_detection(enabled: bool) -> PublicCamera
async
¶
Toggle car horn audio detection via the public API.
set_co_detection(enabled: bool) -> PublicCamera
async
¶
Toggle CO audio detection via the public API.
set_face_detection(enabled: bool) -> PublicCamera
async
¶
Toggle face smart detection via the public API.
set_flood_led(enabled: bool) -> PublicCamera
async
¶
Set the flood LED via the public API.
set_glass_break_detection(enabled: bool) -> PublicCamera
async
¶
Toggle glass break audio detection via the public API.
set_hdr_mode(mode: PublicHdrMode) -> PublicCamera
async
¶
Set HDR mode via the public API.
set_lcd_message(text_type: DoorbellMessageType, text: str | None = None, reset_at: datetime | None | DEFAULT_TYPE = DEFAULT) -> PublicCamera
async
¶
Set the doorbell LCD message via the public API.
text is required for CUSTOM_MESSAGE and IMAGE and must be omitted
otherwise. reset_at controls when the message clears: omit for the
NVR default, pass None for "forever", or a specific datetime.
set_license_plate_detection(enabled: bool) -> PublicCamera
async
¶
Toggle license plate smart detection via the public API.
set_mic_volume(level: int) -> PublicCamera
async
¶
Set microphone volume (1-100) via the public API.
set_osd_date(enabled: bool) -> PublicCamera
async
¶
Toggle the date overlay (OSD) via the public API.
set_osd_logo(enabled: bool) -> PublicCamera
async
¶
Toggle the logo overlay (OSD) via the public API.
set_osd_name(enabled: bool) -> PublicCamera
async
¶
Toggle the name overlay (OSD) via the public API.
set_osd_nerd_mode(enabled: bool) -> PublicCamera
async
¶
Toggle the bitrate/debug overlay (OSD) via the public API.
set_osd_overlay_location(location: OsdOverlayLocation) -> PublicCamera
async
¶
Set the OSD overlay location via the public API.
set_package_detection(enabled: bool) -> PublicCamera
async
¶
Toggle package smart detection via the public API.
set_person_detection(enabled: bool) -> PublicCamera
async
¶
Toggle person smart detection via the public API.
set_siren_detection(enabled: bool) -> PublicCamera
async
¶
Toggle siren audio detection via the public API.
set_smoke_detection(enabled: bool) -> PublicCamera
async
¶
Toggle smoke audio detection via the public API.
set_speaking_detection(enabled: bool) -> PublicCamera
async
¶
Toggle speaking audio detection via the public API.
set_status_light(enabled: bool) -> PublicCamera
async
¶
Set the status LED via the public API.
set_vehicle_detection(enabled: bool) -> PublicCamera
async
¶
Toggle vehicle smart detection via the public API.
set_video_mode(mode: VideoMode) -> PublicCamera
async
¶
Set the video mode via the public API.
set_welcome_led(enabled: bool) -> PublicCamera
async
¶
Set the welcome LED via the public API.
PublicChime
¶
Bases: PublicDeviceModel
Public API chime device (GET /v1/chimes).
set_repeat_times_for_camera(camera_id: str, value: int) -> PublicChime
async
¶
Set the ring repeat count for one paired camera via the public API.
set_ring_settings(ring_settings: list[PublicApiChimeRingSettingRequest]) -> PublicChime
async
¶
Replace the full per-camera ring settings via the public API.
set_volume_for_camera(camera_id: str, level: int) -> PublicChime
async
¶
Set the ring volume for one paired camera via the public API.
PublicDeviceModel
¶
PublicDoorbellCustomImage
¶
PublicDoorbellSettings
¶
Bases: ProtectBaseObject
Doorbell settings exposed by the Public Integration API (GET /v1/nvrs).
Intentionally separate from the private :class:~uiprotect.data.nvr.DoorbellSettings
which carries additional private-API-only fields (allMessages, typed
timedelta, etc.).
All fields have defaults because the doorbellSettings OpenAPI schema
declares no required array — fields may be absent on older firmware or
in partial WS update diffs.
PublicFile
¶
PublicIdentifiedModel
¶
Bases: ProtectModelWithId
Public model carrying the optional device self-description (type / guid).
PublicLight
¶
Bases: PublicDeviceModel
Public API light device (GET /v1/lights).
set_duration(duration: timedelta) -> PublicLight
async
¶
Set how long the light stays on after motion (15s-900s) via the public API.
set_flood_light(enabled: bool) -> PublicLight
async
¶
Force the flood light on/off via the public API.
set_led_level(led_level: int) -> PublicLight
async
¶
Set the indicator LED brightness (1-6) via the public API.
set_light_mode(mode: LightModeType, enable_at: LightModeEnableType | None = None) -> PublicLight
async
¶
Set the lighting trigger mode (and optional schedule) via the public API.
set_light_settings(mode: LightModeType, enable_at: LightModeEnableType | None = None, duration: timedelta | None = None, sensitivity: int | None = None) -> PublicLight
async
¶
Update mode, schedule, duration and PIR sensitivity via the public API.
set_name(name: str) -> PublicLight
async
¶
Set the light name via the public API.
set_sensitivity(sensitivity: int) -> PublicLight
async
¶
Set PIR motion sensitivity (0-100) via the public API.
set_status_light(enabled: bool) -> PublicLight
async
¶
Toggle the status indicator LED via the public API.
PublicLiveview
¶
Bases: ProtectModelWithId
Public API liveview.
owner is a flat userId string (the spec types it as $ref: userId,
which is type: string) — not an embedded user object. layout is the
number of slots the liveview contains (spec: number, 1..26); the field name
matches the wire key exactly.
PublicLiveviewSlot
¶
PublicLiveviewSlotDict
¶
Bases: TypedDict
Liveview slot (write shape).
PublicNVR
¶
Bases: PublicIdentifiedModel
NVR device as exposed by the Public Integration API (GET /v1/nvrs).
This model reflects the public schema: id, modelKey, name,
doorbellSettings, and optionally armMode / mac.
name is nullable — the API schema declares it as oneOf: [string, null].
mac is exposed on GET /v1/nvrs from Protect newer than 7.1 and is
None on older firmware that omits the key (and absent from WS
partial-update diffs).
doorbell_settings is None on older firmware that does not yet
expose the doorbellSettings key, and is absent from WS partial-update
diffs (which only require id + modelKey).
arm_mode is None when the firmware does not yet expose the alarm
manager (older releases) and also None when the alarm manager is set
to global (server returns armMode: null). WS device-update diffs that
include armMode are handled automatically by
:meth:~uiprotect.data.base.ProtectBaseObject.update_from_dict without
any manual extraction.
PublicSensor
¶
Bases: PublicDeviceModel
Public API sensor device (GET /v1/sensors).
has_feature_flags: bool
property
¶
Whether a capability map was reported; False means unavailable, not empty.
is_leak_detected: bool
property
¶
Whether a leak is detected on either the internal or external channel.
is_tampering_detected: bool
property
¶
Whether the tamper switch is currently triggered.
set_alarm(enabled: bool) -> PublicSensor
async
¶
Toggle the (audio) alarm detection setting via the public API.
set_arm_profile_ids(arm_profile_ids: list[str]) -> PublicSensor
async
¶
Set the arm-profile ids associated with the sensor via the public API.
set_custom_sensitivity_when_armed(enabled: bool) -> PublicSensor
async
¶
Toggle custom armed sensitivity via the public API.
set_glass_break_settings(*, is_enabled: bool | None = None, sensitivity: float | None = None, sensitivity_when_armed: float | None = None) -> PublicSensor
async
¶
Update glass-break detection settings via the public API.
set_glass_break_status(enabled: bool) -> PublicSensor
async
¶
Toggle glass-break detection via the public API.
set_humidity_settings(*, is_enabled: bool | None = None, low_threshold: float | None = None, high_threshold: float | None = None, margin: int | None = None) -> PublicSensor
async
¶
Update humidity alert settings via the public API.
set_humidity_status(enabled: bool) -> PublicSensor
async
¶
Toggle humidity alerts via the public API.
set_light_settings(*, is_enabled: bool | None = None, low_threshold: float | None = None, high_threshold: float | None = None, margin: int | None = None) -> PublicSensor
async
¶
Update light (lux) alert settings via the public API.
set_light_status(enabled: bool) -> PublicSensor
async
¶
Toggle light (lux) alerts via the public API.
set_motion_sensitivity(sensitivity: float) -> PublicSensor
async
¶
Set motion detection sensitivity via the public API.
set_motion_settings(*, is_enabled: bool | None = None, sensitivity: float | None = None, sensitivity_when_armed: float | None = None) -> PublicSensor
async
¶
Update motion detection settings via the public API.
set_motion_status(enabled: bool) -> PublicSensor
async
¶
Toggle motion detection via the public API.
set_name(name: str) -> PublicSensor
async
¶
Set the sensor name via the public API.
set_schedule_mode(mode: SensorScheduleMode) -> PublicSensor
async
¶
Set the arm-schedule mode via the public API.
set_temperature_settings(*, is_enabled: bool | None = None, low_threshold: float | None = None, high_threshold: float | None = None, margin: float | None = None) -> PublicSensor
async
¶
Update temperature alert settings via the public API.
set_temperature_status(enabled: bool) -> PublicSensor
async
¶
Toggle temperature alerts via the public API.
supports(capability: SensorFeatureCapability) -> bool
¶
Whether the sensor advertises capability (False without a feature map).
PublicSensorFeatureCapability
¶
PublicSensorFeatureFlags
¶
Bases: ProtectBaseObject
Per-sensor capability map. An absent key means the capability is unsupported.
PublicSirenStatus
¶
Bases: ProtectBaseObject
turn_off_at: datetime | None
property
¶
When the siren is expected to stop playing.
Returns None when the siren is idle — either because activated_at
/ duration are not set, or because is_active is False (e.g.
after a manual stop, where the server may leave the timing fields
populated). Derived from the websocket payload so no extra API call is
needed — HA can compare against datetime.now(UTC) instead of
maintaining its own timer.
PublicUlpUser
¶
PublicUser
¶
PublicViewer
¶
Bases: PublicDeviceModel
Public API viewer device.
ModelType.VIEWPORT is already owned by the private :class:Viewer class
in MODEL_TO_CLASS; this public counterpart is routed via a dedicated
factory on :class:~uiprotect.data.public_bootstrap.PublicBootstrap instead.
The wire field liveview is a flat liveviewId string (nullable);
snake-cased to :attr:liveview_id via :meth:_get_unifi_remaps.
RTSPSStreams
¶
Bases: ProtectBaseObject
RTSPS stream URLs for a camera.
get_active_stream_qualities() -> list[str]
¶
Get list of currently active RTSPS stream quality levels (only those with stream URLs).
get_available_stream_qualities() -> list[str]
¶
List available RTSPS quality keys from the server.
Returns raw strings; may include values not in :class:ChannelQuality.
get_inactive_stream_qualities() -> list[str]
¶
Get list of inactive RTSPS stream quality levels (supported but not currently active).
get_stream_url(quality: str, srtp: bool = True) -> str | None
¶
Get stream URL for a quality level; srtp=False strips ?enableSrtp.
Relay
¶
Bases: PublicDeviceModel
Public API relay device.
Use :meth:__getitem__ (relay[output_id]) for "fail loud" lookup or
:meth:get_output for the None-returning variant.
__getitem__(output_id: int) -> PublicRelayOutput
¶
Return the output with the given id; raises :class:KeyError if unknown.
activate_output(output_id: int, state: Literal['on', 'off'] | None = None, pulse_duration_ms: int | None = None) -> None
async
¶
Activate / toggle a relay output channel.
get_output(output_id: int) -> PublicRelayOutput | None
¶
Return the output with the given id, or None if not found.
SensorFeatureCapability
¶
Bases: StrEnum
A capability a sensor can advertise in :class:PublicSensorFeatureFlags.
Siren
¶
Bases: PublicDeviceModel
Public API siren device.
is_active: bool
property
¶
Whether the siren is currently playing.
The server does not emit a stop event when the siren finishes its
timed run, so sirenStatus.isActive in the WS payload stays
True until the next update. turn_off_at is only set while
the server flag is true and the timing fields are populated, so a
clock check against it catches the timed-expiry case. A manual stop
clears the server flag and turn_off_at becomes None,
falling back to the (now-false) server flag.
play(duration: int | SirenDuration | None = None) -> None
async
¶
Play the siren. duration may be a supported integer or :class:SirenDuration; defaults to 5 seconds.
stop() -> None
async
¶
Stop an active siren.
test_sound(volume: int | None = None) -> None
async
¶
Test the siren sound at the given volume.
Speaker
¶
Bases: PublicDeviceModel
Public API speaker device.
test_sound(volume: int | None = None) -> None
async
¶
Test the speaker sound at the given volume.
Events (uiprotect.events)¶
Public events contract for UniFi Protect.
EventChange
¶
Bases: StrEnum
Lifecycle tag for a ProtectEvent dispatch.
ProtectEvent
¶
Bases: BaseModel
Frozen public value type emitted by subscribe_events.
ProtectEventChannel
¶
Bases: StrEnum
High-level grouping for public events.
UlpUserIdentity
¶
Bases: BaseModel
ULP-cached identity attached to a credential event.
UnknownIdentity
¶
Bases: BaseModel
Identity unresolvable from the cached public bootstrap.
Exceptions (uiprotect.exceptions)¶
ArmedModeError
¶
Bases: BadRequest
Operation not available while the arm alarm is armed.
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
GlobalAlarmManagerError
¶
Bases: BadRequest
Operation not available when global alarm manager is enabled.
Invalid
¶
Bases: ClientError
Invalid return from Authorization Request.
NotAuthorized
¶
Bases: PermissionError, BadRequest
Wrong username, password or permission error.
NvrError
¶
Bases: ClientError
Other error.
PublicOnlyModeError
¶
Bases: BadRequest
Private-API operation attempted on a public-only (API-key-only) client.
StreamError
¶
Bases: UnifiProtectError
Exception 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 (uiprotect.stream)¶
Audio streaming utilities for UniFi Protect cameras using PyAV.
CodecConfig
¶
Bases: NamedTuple
Audio codec configuration for talkback streaming.
Attributes:
| Name | Type | Description |
|---|---|---|
encoder |
str
|
PyAV/libav encoder name (e.g., "aac", "libopus"). |
format |
str
|
Output container format (e.g., "adts", "rtp"). |
TalkbackSession
dataclass
¶
Talkback session configuration from the UniFi Protect public API.
Attributes:
| Name | Type | Description |
|---|---|---|
url |
str
|
Streaming URL (UDP or RTP, e.g., "rtp://192.168.1.1:7004"). |
codec |
str
|
Audio codec name ("aac", "opus", or "vorbis"). |
sampling_rate |
int
|
Audio sampling rate in Hz. |
host: str
property
¶
Get hostname from talkback URL.
port: int
property
¶
Get port from talkback URL, defaults to 7004.
__post_init__() -> None
¶
Parse URL on initialization.
from_unifi_dict(**data: object) -> TalkbackSession
classmethod
¶
Create from UniFi API response.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**data
|
object
|
Raw API response fields (url, codec, samplingRate). |
{}
|
Returns:
| Type | Description |
|---|---|
TalkbackSession
|
Configured TalkbackSession instance. |
TalkbackStream
¶
Stream audio to a UniFi Protect camera's speaker using PyAV.
This class handles audio transcoding and UDP streaming to camera speakers. It runs the actual streaming in a separate thread to avoid blocking the event loop.
Example
is_running: bool
property
¶
Check if the stream is currently running.
__aenter__() -> Self
async
¶
Start streaming when entering async context.
__aexit__(exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: object) -> None
async
¶
Stop streaming when exiting async context.
__init__(camera: Camera, content_url: str, session: TalkbackSession | None = None) -> None
¶
Initialize talkback stream.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
camera
|
Camera
|
Camera device to stream audio to. |
required |
content_url
|
str
|
URL or file path of audio source. |
required |
session
|
TalkbackSession | None
|
Optional talkback session from public API. |
None
|
Raises:
| Type | Description |
|---|---|
BadRequest
|
If camera does not have a speaker. |
run_until_complete() -> None
async
¶
Run the stream until it completes naturally.
start() -> None
async
¶
Start the audio stream.
stop() -> None
async
¶
Stop the audio stream gracefully and wait for completion.
Utils (uiprotect.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_to_datetime(source_time: float | str | datetime | None) -> datetime | None
cached
¶
Converts timestamp to datetime object
convert_unifi_data(value: Any, field: FieldInfo) -> 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_token_cookie(token_cookie: Morsel[str]) -> dict[str, Any] | None
¶
Decode a token cookie if it is still valid.
format_datetime(dt: datetime | None, default: str | None = None) -> str | None
¶
Formats a datetime object in a consistent format
format_duration(duration: timedelta) -> str
¶
Formats a timedelta as a string.
format_host_for_url(host: IPv4Address | IPv6Address | str) -> str
¶
Format host for URLs. IPv6 addresses are wrapped in brackets.
from_js_time(num: float | str | datetime) -> datetime
¶
Converts Javascript timestamp or ISO-8601 string to Python datetime
get_local_timezone() -> tzinfo
¶
Gets Olson timezone name for localizing datetimes
get_nested_attr(attrs: tuple[str, ...], obj: Any) -> Any
¶
Fetch a nested attribute.
get_nested_attr_as_bool(attrs: tuple[str, ...], obj: Any) -> bool
¶
Fetch a nested attribute as a bool.
get_top_level_attr_as_bool(attr: str, obj: Any) -> Any
¶
Fetch a top level attribute as a bool.
ip_from_host(host: str) -> IPv4Address | IPv6Address
async
¶
Resolve hostname to IP address (IPv4 or IPv6).
Raises:
| Type | Description |
|---|---|
ValueError
|
If host cannot be resolved to IP address |
is_debug() -> bool
cached
¶
Returns if debug ENV is on (True)
local_datetime(dt: datetime | None = None) -> datetime
¶
Returns datetime in local timezone
make_enabled_getter(ufp_enabled: str) -> Callable[[T], bool]
¶
Return a function to get a value from a Protect device.
make_required_getter(ufp_required_field: str) -> Callable[[T], bool]
¶
Return a function to get a value from a Protect device.
make_value_getter(ufp_value: str) -> Callable[[T], Any]
¶
Return a function to get a value from a Protect device.
normalize_mac(mac: str) -> str
cached
¶
Normalize MAC address.
pybool_to_json_bool(value: bool) -> str
¶
Convert a Python bool to a JSON boolean string ('true'/'false').
run_async(callback: Coroutine[Any, Any, T]) -> T
¶
Run async coroutine.
serialize_coord(coord: CoordType) -> 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[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) -> int | None
¶
Converts Python datetime to Javascript timestamp
to_ms(duration: timedelta | None) -> int | None
¶
Converts python timedelta to Milliseconds
to_snake_case(name: str) -> str
cached
¶
Converts string to snake_case
Websocket (uiprotect.websocket)¶
UniFi Protect Websockets.
Websocket
¶
UniFi Protect Websocket manager.
is_connected: bool
property
¶
Return if the websocket connection is open.
__init__(get_url: Callable[[], URL], auth_callback: AuthCallbackType, update_bootstrap: UpdateBootstrapCallbackType, get_session: GetSessionCallbackType, subscription: Callable[[WSMessage], None], state_callback: Callable[[WebsocketState], None], *, timeout: float = 30.0, backoff: int = 10, auth_failed_backoff: int = 120, verify: bool = True, receive_timeout: float | None = None, heartbeat: float | None = None) -> None
¶
Init Websocket.
reset_auth_failure() -> None
¶
Clear the auth-failure backoff and wake the reconnect loop.
Call after installing a fresh credential (e.g. a new API key) so a
websocket parked on the long auth_failed_backoff retries at once.
start() -> None
¶
Start the websocket.
stop() -> None
¶
Disconnect the websocket.
wait_closed() -> None
async
¶
Wait for the websocket to close.