Skip to content

Sensors

Typed detection sensors (motion, object, face, license-plate, audio, classifier, clip) and smart-home sensors (contact, doorbell, lock, garage, light, switch, ptz, security system, environmental).

camera_ui_sdk.sensor

AudioDetectorSensor

AudioDetectorSensor(name: str = 'Audio Sensor')

Bases: AudioSensor[TStorage], Generic[TStorage]

Audio detector that receives audio frames from the backend pipeline.

Extend this class and implement detectAudio and modelSpec. The backend resamples and buffers audio to match modelSpec before each call.

modelSpec abstractmethod property

modelSpec: AudioModelSpec

Declares the expected audio input format. The backend resamples to match.

detectAudio abstractmethod async

detectAudio(audio: AudioFrameData) -> AudioResult

Analyze a single audio frame for events. Called by the backend at the configured cadence.

AudioFrameData

Bases: TypedDict

Audio frame data delivered to audio detector sensors by the backend pipeline.

AudioResult

Bases: TypedDict

Return type for AudioDetectorSensor.detectAudio().

AudioSensor

AudioSensor(name: str = 'Audio Sensor')

Bases: Sensor[AudioSensorProperties, TStorage, str], Generic[TStorage]

Audio sensor that reports audio events and decibel levels.

Plugin authors call reportDetections(list) to push detected audio events (auto-derives detected) and setDecibels(value) to update the audio level.

detected property

detected: bool

Whether an audio event is currently detected.

detections property

detections: list[Detection]

Current detection list.

decibels property

decibels: float

Current audio level in decibels.

reportDetections

reportDetections(detected: bool, detections: list[Detection] | None = None) -> None

Report detected audio events.

  • reportDetections(True) — audio detected without specifics. The SDK synthesizes a single full-frame 'audio' detection.
  • reportDetections(True, [...]) — audio detected with explicit detections.
  • reportDetections(False) — clear.

Parameters:

Name Type Description Default
detected bool

Whether an audio event is currently detected.

required
detections list[Detection] | None

Optional explicit detections produced for this event.

None
Example
sensor.reportDetections(
    True,
    [
        Detection(
            label="glass_break",
            confidence=0.91,
            box=BoundingBox(x=0, y=0, width=1, height=1),
        )
    ],
)
sensor.reportDetections(False)

clearDetections

clearDetections() -> None

Explicitly clear audio detection state (detected = False, detections = []).

setDecibels

setDecibels(value: float) -> None

Update the current audio level (in decibels).

Parameters:

Name Type Description Default
value float

Audio level in decibels.

required
Example
sensor.setDecibels(72)

updateValue async

updateValue(property: str, value: Any) -> None

Read-only sensor: external writes are ignored.

Sensor

Sensor(name: str)

Bases: ABC, Generic[TProperties, TStorage, TCapability]

Abstract base class for all sensors. Plugins extend this (or use specialized subclasses like MotionSensor, LightControl, etc.) to implement sensor logic.

storage_schema property

storage_schema: list[JsonSchema]

Override to provide a JSON schema for per-sensor storage settings UI.

storage property

storage: DeviceStorage[TStorage]

Per-sensor persistent storage. Raises if not yet added to a camera.

onAssignmentChanged property

onAssignmentChanged: Observable[bool]

Observable for assignment state changes (sensor added/removed from camera).

onPropertyChanged property

onPropertyChanged: Observable[SensorPropertyChangeData]

Observable for property changes.

onCapabilitiesChanged property

onCapabilitiesChanged: Observable[list[TCapability]]

Observable for capability changes. Emits the full capabilities array when capabilities change.

on_assigned

on_assigned() -> Any

Lifecycle hook: the sensor just became assigned to a camera.

Override to start background work that should only run while this sensor is live — polling loops, event subscriptions, timers, external connections.

Called AFTER cameraId, storage, and RPC channels are wired up, so the override can safely access self.cameraId, self.storage, and publish properties via the semantic helper methods.

May be either a plain def or an async def. If async, the SDK schedules it on the running event loop (fire-and-forget). Errors are caught and swallowed — they will NOT break assignment bookkeeping.

Paired 1:1 with on_deassigned — for every on_assigned call there is exactly one matching on_deassigned later (on deassignment or cleanup).

Default: no-op. Most sensors don't need lifecycle hooks.

Example
async def on_assigned(self) -> None:
    self._task = asyncio.create_task(self._poll_loop())

on_deassigned

on_deassigned() -> Any

Lifecycle hook: the sensor is being deassigned.

Override to tear down whatever was started in on_assigned — clear timers, close subscriptions, release external resources.

Always called exactly once for each prior on_assigned. Also called from _cleanup if the sensor is being removed while still assigned, so you can rely on this as the single teardown point.

May be either a plain def or an async def. See on_assigned for scheduling semantics.

Default: no-op.

Example
def on_deassigned(self) -> None:
    if self._task:
        self._task.cancel()

toJSON

toJSON() -> SensorJSON

Serialize this sensor to a JSON-safe dict for RPC transport.

getValue

getValue(property: str) -> Any | None

Get the current value of a sensor property.

getValues

getValues() -> dict[str, Any]

Get a read-only snapshot of all property values.

Returns:

Type Description
dict[str, Any]

Snapshot of every property currently held by the sensor.

Example
snapshot = sensor.getValues()
print(snapshot)

updateValue abstractmethod async

updateValue(property: str, value: Any) -> None

External-consumer entry point that satisfies the SensorLike.updateValue contract. Each concrete sensor class implements this — read-only sensors leave it as a no-op, control sensors dispatch known properties to the appropriate semantic methods (setOn, setActive, setTargetState, ...) so plugin overrides drive hardware. Unknown / non-writable properties are silently ignored.

Plugin authors must not call this — they should call the semantic methods directly on the concrete sensor class.

SensorCategory

Bases: str, Enum

Categorizes a sensor's role in the system.

SensorLike

Bases: Protocol

Read-only proxy interface for a sensor. Use this type when consuming sensors, not creating them.

All state-modifying methods (setOn, reportDetections, etc.) live on the concrete sensor classes, not on SensorLike. Code that holds a SensorLike reference can only READ state and observe changes.

getValue

getValue(property: str) -> Any | None

Get the current value of a sensor property.

getValues

getValues() -> dict[str, Any]

Get a read-only snapshot of all property values.

updateValue async

updateValue(property: str, value: Any) -> None

Write a property generically. Cross-process bridges (e.g. HomeKit) bind generic property names to UI characteristics and call this on a sensor proxy — the proxy forwards via RPC to the owning sensor, where control sensor classes (Light, Siren, etc.) override updateValue to dispatch to the appropriate semantic method (setOn, setActive, ...). This means plugin-side hardware-action overrides ARE honored end-to-end.

Plugin authors must not call this — they should call the semantic methods directly on the concrete sensor class.

SensorPropertyChangeData

Bases: TypedDict

Emitted on the onPropertyChanged Observable.

SensorType

Bases: str, Enum

Type of sensor. Each maps to a smart-home concept (HomeKit service).

BatteryCapability

Bases: str, Enum

Optional capabilities for battery info sensors.

LowBattery class-attribute instance-attribute

LowBattery = 'lowBattery'

Sensor reports low-battery alerts.

Charging class-attribute instance-attribute

Charging = 'charging'

Sensor reports charging state.

BatteryInfo

BatteryInfo(name: str = 'Battery')

Bases: Sensor[BatteryInfoProperties, TStorage, BatteryCapability], Generic[TStorage]

Battery info sensor. Reports battery level, charging state, and low-battery alerts.

Plugin authors call setLevel(value), setCharging(state), and setLow(value) to push updates from the device.

setLevel

setLevel(value: int) -> None

Report a new battery level (percentage). Clamped to [0, 100].

Parameters:

Name Type Description Default
value int

Battery level percentage in the range 0–100.

required
Example
battery.setLevel(87)

setCharging

setCharging(value: ChargingState) -> None

Report the current charging state.

Parameters:

Name Type Description Default
value ChargingState

Current charging state from the ChargingState enum.

required
Example
from camera_ui_sdk import ChargingState

battery.setCharging(ChargingState.Charging)

setLow

setLow(value: bool) -> None

Report whether the battery is critically low.

Parameters:

Name Type Description Default
value bool

True when the battery has crossed the low-battery threshold.

required
Example
battery.setLow(True)

updateValue async

updateValue(property: str, value: Any) -> None

Read-only sensor: external writes are ignored.

ChargingState

Bases: str, Enum

Battery charging state.

NotChargeable class-attribute instance-attribute

NotChargeable = 'NOT_CHARGEABLE'

Device has no rechargeable battery.

NotCharging class-attribute instance-attribute

NotCharging = 'NOT_CHARGING'

Battery is not charging.

Charging class-attribute instance-attribute

Charging = 'CHARGING'

Battery is currently charging.

Full class-attribute instance-attribute

Full = 'FULL'

Battery is fully charged.

ClassifierDetection

Bases: Detection

A classifier detection result with an open attribute for classifier categories.

ClassifierDetectorSensor

ClassifierDetectorSensor(name: str = 'Classifier')

Bases: ClassifierSensor[TStorage], Generic[TStorage]

Classifier detector that receives video frames from the backend pipeline.

Extend this class and implement detectClassifications to run image classification models against trigger regions.

modelSpec abstractmethod property

modelSpec: ModelSpec

Declares the expected input dimensions and trigger labels. The backend scales frames to match.

detectClassifications abstractmethod async

detectClassifications(frames: list[VideoFrameData]) -> list[ClassifierResult]

Classify frames in batch. Each frame is a pre-cropped, pre-scaled trigger region produced by the upstream object detector. Must return exactly one ClassifierResult per input frame, in the same order.

ClassifierResult

Bases: TypedDict

Return type for ClassifierDetectorSensor.detectClassifications().

ClassifierSensor

ClassifierSensor(name: str = 'Classifier')

Bases: Sensor[ClassifierSensorProperties, TStorage, str], Generic[TStorage]

General-purpose image classifier sensor.

Plugin authors call reportDetections(list) to push classification results. detected and labels are auto-derived from the detection list.

detected property

detected: bool

Whether any classification result is active.

detections property

detections: list[ClassifierDetection]

Current detection list.

labels property

labels: list[str]

Unique labels of the current detections.

reportDetections

reportDetections(detected: bool, detections: list[ClassifierDetection] | None = None) -> None

Report classification results. Auto-derives detected and labels from the list.

  • reportDetections(True) — generic classification trigger. The SDK synthesizes a single full-frame detection with empty attribute and sub-attribute.
  • reportDetections(True, [...]) — explicit classifier detections.
  • reportDetections(False) — clear.

Parameters:

Name Type Description Default
detected bool

Whether any classification result is active.

required
detections list[ClassifierDetection] | None

Optional explicit classifier detections to publish.

None
Example
sensor.reportDetections(
    True,
    [
        ClassifierDetection(
            label="animal",
            confidence=0.88,
            box=BoundingBox(x=0.1, y=0.2, width=0.3, height=0.4),
            attribute="bird",
            subAttribute="woodpecker",
        )
    ],
)
sensor.reportDetections(False)

clearDetections

clearDetections() -> None

Explicitly clear classifier state (detected = False, detections = [], labels = []).

updateValue async

updateValue(property: str, value: Any) -> None

Read-only sensor: external writes are ignored.

ClipDetectorSensor

ClipDetectorSensor(name: str = 'CLIP Sensor')

Bases: Sensor[dict[str, Any], TStorage, str], Generic[TStorage]

CLIP detector sensor that receives video frames and generates semantic embeddings.

Extend this class and implement detectEmbeddings to produce CLIP embeddings for downstream semantic search.

modelSpec abstractmethod property

modelSpec: ModelSpec

Declares the expected input dimensions and trigger labels.

detectEmbeddings abstractmethod async

detectEmbeddings(frames: list[VideoFrameData]) -> list[ClipResult]

Generate CLIP embeddings in batch. Each frame is a pre-cropped, pre-scaled trigger region produced by the upstream object detector. Must return exactly one ClipResult per input frame, in the same order. Use frame['label'] to tag the emitted embedding.

updateValue async

updateValue(property: str, value: Any) -> None

Frame-only sensor: no externally writable properties.

ClipEmbedding

Bases: TypedDict

A CLIP embedding result for a detected region.

ClipResult

Bases: TypedDict

Return type for ClipDetectorSensor.detectEmbeddings().

ContactSensor

ContactSensor(name: str = 'Contact Sensor')

Bases: Sensor[ContactSensorProperties, TStorage, str], Generic[TStorage]

Contact sensor for door/window open-close state.

setDetected

setDetected(value: bool) -> None

Report contact state (True = open, False = closed).

Parameters:

Name Type Description Default
value bool

True when the contact is open, False when closed.

required
Example
contact.setDetected(True)

updateValue async

updateValue(property: str, value: Any) -> None

Read-only sensor: external writes are ignored.

BoundingBox

Bases: TypedDict

Bounding box of a detection.

All coordinates are normalized to 0-1 (fraction of frame dimensions), so they are independent of resolution.

Detection

Bases: TypedDict

A single detection result emitted by any detection sensor.

VideoFrameData

Bases: TypedDict

Video frame data delivered to detector sensors by the backend pipeline.

The backend handles capture, decoding, and scaling — detectors only need to process the pixel payload.

DoorbellTrigger

DoorbellTrigger(name: str = 'Doorbell')

Bases: Sensor[DoorbellTriggerProperties, TStorage, str], Generic[TStorage]

Doorbell trigger sensor.

Plugin authors call trigger() to fire a doorbell event. The ring property is set to True and automatically reset to False after a short delay (RING_AUTO_RESET_MS). Calling trigger() again while still ringing resets the timer (extends the ring phase).

trigger

trigger() -> None

Trigger a doorbell ring. Sets ring = True and auto-resets after a short delay. Re-triggering while still ringing extends the ring phase.

Example
doorbell.trigger()

updateValue async

updateValue(property: str, value: Any) -> None

Cross-process consumer entry point. Writing ring=true (any truthy value) dispatches to trigger() so a UI test button or external automation can fire the doorbell using the same flow as a real hardware ring (auto-reset included). Writing ring=false is ignored — the auto-reset timer owns the off transition.

FaceDetection

Bases: Detection

A face detection result, extending Detection with face-specific fields.

FaceDetectorSensor

FaceDetectorSensor(name: str = 'Face Sensor')

Bases: FaceSensor[TStorage], Generic[TStorage]

Face detector that receives video frames from the backend pipeline.

Extend this class and implement detectFaces for face detection and recognition.

modelSpec abstractmethod property

modelSpec: ModelSpec

Declares the expected input dimensions and trigger labels. The backend scales frames to match.

detectFaces abstractmethod async

detectFaces(frames: list[VideoFrameData]) -> list[FaceResult]

Detect faces in batch. Each frame is a pre-cropped, pre-scaled person region produced by the upstream object detector. Must return exactly one FaceResult per input frame, in the same order.

FaceResult

Bases: TypedDict

Return type for FaceDetectorSensor.detectFaces().

FaceSensor

FaceSensor(name: str = 'Face Sensor')

Bases: Sensor[FaceSensorProperties, TStorage, str], Generic[TStorage]

Face sensor that reports detected faces and optional identity matches.

Plugin authors call reportDetections(list) to push detected faces. detected is auto-derived from the detection list.

detected property

detected: bool

Whether any face is currently detected.

detections property

detections: list[FaceDetection]

Current detection list.

reportDetections

reportDetections(detected: bool, detections: list[FaceDetection] | None = None) -> None

Report detected faces.

  • reportDetections(True) — face detected without specifics (e.g. a bare face-event from a discovery provider). The SDK synthesizes a single full-frame face detection without identity.
  • reportDetections(True, [...]) — explicit face detections with identity, embedding, and/or thumbnail.
  • reportDetections(False) — clear.

Parameters:

Name Type Description Default
detected bool

Whether any face is currently detected.

required
detections list[FaceDetection] | None

Optional explicit face detections to publish.

None
Example
sensor.reportDetections(
    True,
    [
        FaceDetection(
            label="person",
            confidence=0.94,
            box=BoundingBox(x=0.4, y=0.2, width=0.15, height=0.25),
            attribute="face",
            identity="Alice",
        )
    ],
)
sensor.reportDetections(False)

clearDetections

clearDetections() -> None

Explicitly clear face detection state (detected = False, detections = []).

updateValue async

updateValue(property: str, value: Any) -> None

Read-only sensor: external writes are ignored.

GarageControl

GarageControl(name: str = 'Garage')

Bases: Sensor[GarageControlProperties, TStorage, str], Generic[TStorage]

Garage door control.

Override setTargetState() to drive hardware and call await super().setTargetState(value) once the hardware confirms — the base implementation updates both targetState and currentState.

For long-running transitions (Opening/Closing intermediate states) override setTargetState and write currentState separately as the door moves.

setTargetState async

setTargetState(value: GarageState) -> None

Set the target state. Override to drive hardware and call await super().setTargetState(value) after success — the base implementation syncs both targetState and currentState to the new value.

Parameters:

Name Type Description Default
value GarageState

Desired target state from the GarageState enum.

required
Example
from camera_ui_sdk import GarageState

await garage.setTargetState(GarageState.Open)

setCurrentState

setCurrentState(value: GarageState) -> None

Publish the actual door state. Use this to drive long-running transitions (e.g. Open → Closing → Closed) independently of the user-requested target state. Read-only from cross-process consumers (updateValue ignores it).

Parameters:

Name Type Description Default
value GarageState

Current physical door state from the GarageState enum.

required
Example
from camera_ui_sdk import GarageState

garage.setCurrentState(GarageState.Closing)

setObstructionDetected

setObstructionDetected(value: bool) -> None

Publish the obstruction-detected state. Read-only from the consumer side (updateValue ignores it) — plugin code calls this when its hardware reports an obstruction sensor change.

Parameters:

Name Type Description Default
value bool

True when an obstruction is currently detected.

required
Example
garage.setObstructionDetected(True)

updateValue async

updateValue(property: str, value: Any) -> None

Routes generic property writes to semantic methods.

GarageState

Bases: IntEnum

Garage door states (HomeKit-compatible values).

HumidityInfo

HumidityInfo(name: str = 'Humidity')

Bases: Sensor[HumidityInfoProperties, TStorage, str], Generic[TStorage]

Humidity info sensor. Reports current relative humidity in %.

setCurrent

setCurrent(value: float) -> None

Report a new humidity reading. Clamped to [0, 100] %.

updateValue async

updateValue(property: str, value: Any) -> None

Read-only sensor: external writes are ignored.

LeakSensor

LeakSensor(name: str = 'Leak Sensor')

Bases: Sensor[LeakSensorProperties, TStorage, str], Generic[TStorage]

Leak sensor for water leak detection.

setDetected

setDetected(value: bool) -> None

Report leak detection state.

Parameters:

Name Type Description Default
value bool

True when a water leak is currently detected.

required
Example
leak.setDetected(True)

updateValue async

updateValue(property: str, value: Any) -> None

Read-only sensor: external writes are ignored.

LicensePlateDetection

Bases: Detection

A license plate detection result, extending Detection with OCR fields.

LicensePlateDetectorSensor

LicensePlateDetectorSensor(name: str = 'License Plate Sensor')

Bases: LicensePlateSensor[TStorage], Generic[TStorage]

License plate detector that receives video frames from the backend pipeline.

Extend this class and implement detectLicensePlates for plate detection and OCR.

modelSpec abstractmethod property

modelSpec: ModelSpec

Declares the expected input dimensions and trigger labels. The backend scales frames to match.

detectLicensePlates abstractmethod async

detectLicensePlates(frames: list[VideoFrameData]) -> list[LicensePlateResult]

Detect license plates in batch. Each frame is a pre-cropped, pre-scaled vehicle region produced by the upstream object detector. Must return exactly one LicensePlateResult per input frame, in the same order.

LicensePlateResult

Bases: TypedDict

Return type for LicensePlateDetectorSensor.detectLicensePlates().

LicensePlateSensor

LicensePlateSensor(name: str = 'License Plate Sensor')

Bases: Sensor[LicensePlateSensorProperties, TStorage, str], Generic[TStorage]

License plate sensor that reports detected plates with OCR text.

Plugin authors call reportDetections(list) to push detected plates. detected is auto-derived from the detection list.

detected property

detected: bool

Whether any license plate is currently detected.

detections property

detections: list[LicensePlateDetection]

Current detection list.

reportDetections

reportDetections(detected: bool, detections: list[LicensePlateDetection] | None = None) -> None

Report detected license plates.

  • reportDetections(True) — plate detected without specifics. The SDK synthesizes a single full-frame detection with empty plateText.
  • reportDetections(True, [...]) — explicit plate detections with OCR text.
  • reportDetections(False) — clear.

Parameters:

Name Type Description Default
detected bool

Whether any license plate is currently detected.

required
detections list[LicensePlateDetection] | None

Optional explicit plate detections to publish.

None
Example
sensor.reportDetections(
    True,
    [
        LicensePlateDetection(
            label="vehicle",
            confidence=0.93,
            box=BoundingBox(x=0.2, y=0.5, width=0.2, height=0.08),
            attribute="license_plate",
            plateText="ABC 1234",
        )
    ],
)
sensor.reportDetections(False)

clearDetections

clearDetections() -> None

Explicitly clear license plate state (detected = False, detections = []).

updateValue async

updateValue(property: str, value: Any) -> None

Read-only sensor: external writes are ignored. State is reported via reportDetections.

LightCapability

Bases: str, Enum

Optional capabilities for light controls.

Brightness class-attribute instance-attribute

Brightness = 'brightness'

Light supports brightness adjustment (0–100).

LightControl

LightControl(name: str = 'Light')

Bases: Sensor[LightControlProperties, TStorage, LightCapability], Generic[TStorage]

Light control sensor. Override setOn()/setOff() to drive your hardware, then await super().setOn() / await super().setOff() to sync the SDK state.

Plugins that have no hardware-action use case can leave the methods unoverridden — the base implementation just updates the state.

For hardware-pushed updates (someone manually flipped the switch), call super().setOn() / super().setOff() from your event handler — that bypasses any plugin override and only syncs state.

setOn async

setOn() -> None

Turn the light on. Override to drive hardware and call await super().setOn() after the hardware call succeeds to sync the SDK state.

Example
await light.setOn()

setOff async

setOff() -> None

Turn the light off. Override to drive hardware and call await super().setOff() after the hardware call succeeds to sync the SDK state.

Example
await light.setOff()

setBrightness async

setBrightness(value: int) -> None

Set brightness. Override to drive hardware and call await super().setBrightness(value) after the hardware call succeeds. The default implementation clamps the value to [0, 100].

Parameters:

Name Type Description Default
value int

Brightness level in the range 0–100.

required
Example
await light.setBrightness(75)

updateValue async

updateValue(property: str, value: Any) -> None

Routes generic property writes to semantic methods.

LockControl

LockControl(name: str = 'Lock')

Bases: Sensor[LockControlProperties, TStorage, str], Generic[TStorage]

Lock control.

Override setTargetState() to drive hardware and call await super().setTargetState(value) once the hardware confirms — the base implementation updates both targetState and currentState to the new value.

For asymmetric flows (long-running unlock with intermediate state) override setTargetState and write currentState separately when transitions complete.

setTargetState async

setTargetState(value: LockState) -> None

Set the target state. Override to drive hardware and call await super().setTargetState(value) after success — the base implementation syncs both targetState and currentState to the new value.

Parameters:

Name Type Description Default
value LockState

Desired lock state from the LockState enum.

required
Example
from camera_ui_sdk import LockState

await lock.setTargetState(LockState.Secured)

setCurrentState

setCurrentState(value: LockState) -> None

Publish the actual lock state. Use this to drive transitions where the physical state diverges from the user-requested target — e.g. motorized smart locks that take time to rotate (publish Unknown while moving), or hardware reporting an out-of-band state change. Read-only from cross-process consumers (updateValue ignores it).

Parameters:

Name Type Description Default
value LockState

Current physical lock state from the LockState enum.

required
Example
from camera_ui_sdk import LockState

lock.setCurrentState(LockState.Unknown)

updateValue async

updateValue(property: str, value: Any) -> None

Routes generic property writes to semantic methods.

LockState

Bases: IntEnum

Lock states (HomeKit-compatible values).

MotionDetectorSensor

MotionDetectorSensor(name: str = 'Motion Sensor')

Bases: MotionSensor[TStorage], Generic[TStorage]

Motion detector that receives video frames from the backend pipeline.

Extend this class and implement detectMotion to analyze frames for motion. The backend calls detectMotion at the configured frame interval and applies the returned result to the sensor.

detectMotion abstractmethod async

detectMotion(frame: VideoFrameData) -> MotionResult

Analyze a single video frame for motion. Called by the backend at the configured interval.

MotionResult

Bases: TypedDict

Return type for MotionDetectorSensor.detectMotion().

MotionSensor

MotionSensor(name: str = 'Motion Sensor')

Bases: Sensor[MotionSensorProperties, TStorage, str], Generic[TStorage]

Motion sensor that reports motion state and detection results.

Plugin authors call reportDetections(list) to push detection results. detected is auto-derived from the detection list. blocked is read-only and is set by the backend (dwell logic) — reportDetections() becomes a no-op while the sensor is blocked.

detected property

detected: bool

Whether motion is currently detected.

detections property

detections: list[Detection]

Current detection list.

blocked property

blocked: bool

Whether the sensor is currently blocked. Read-only — set by the backend dwell logic, not by plugin code.

reportDetections

reportDetections(detected: bool, detections: list[Detection] | None = None) -> None

Report a motion detection result.

  • reportDetections(True) — motion detected without bbox (e.g. Ring camera). The SDK synthesizes a single full-frame 'motion' detection.
  • reportDetections(True, [...]) — motion detected with explicit detections.
  • reportDetections(False) — no motion (clears detections).

No-op while the sensor is blocked by backend dwell logic.

Parameters:

Name Type Description Default
detected bool

Whether motion is currently detected.

required
detections list[Detection] | None

Optional explicit detections produced for this frame.

None
Example
sensor.reportDetections(
    True,
    [
        Detection(
            label="motion",
            confidence=0.85,
            box=BoundingBox(x=0.1, y=0.2, width=0.3, height=0.4),
        )
    ],
)
sensor.reportDetections(False)

clearDetections

clearDetections() -> None

Explicitly clear motion state (detected = False, detections = []).

updateValue async

updateValue(property: str, value: Any) -> None

Read-only sensor: external writes are ignored. State is reported via reportDetections.

ObjectDetectorSensor

ObjectDetectorSensor(name: str = 'Object Sensor')

Bases: ObjectSensor[TStorage], Generic[TStorage]

Object detector that receives video frames from the backend pipeline.

Extend this class and implement detectObjects and modelSpec. The backend scales frames to match modelSpec.input dimensions before each call.

modelSpec abstractmethod property

modelSpec: ObjectModelSpec

Declares the expected input dimensions. The backend scales frames to match.

detectObjects abstractmethod async

detectObjects(frame: VideoFrameData) -> ObjectResult

Analyze a single video frame for objects. Called by the backend at the configured interval.

ObjectResult

Bases: TypedDict

Return type for ObjectDetectorSensor.detectObjects().

ObjectSensor

ObjectSensor(name: str = 'Object Sensor')

Bases: Sensor[ObjectSensorProperties, TStorage, str], Generic[TStorage]

Object detection sensor that reports detected objects (person, vehicle, animal, etc.).

Plugin authors call reportDetections(list) to push detection results. detected and labels are auto-derived from the detection list.

detected property

detected: bool

Whether any object is currently detected.

detections property

detections: list[TrackedDetection]

Current detection list.

labels property

labels: list[DetectionLabel]

Unique labels of the current detections.

reportDetections

reportDetections(detected: bool, detections: list[TrackedDetection] | None = None) -> None

Report detected objects. Auto-derives detected and labels from the list.

  • reportDetections(True) — something detected without specific data. The SDK synthesizes a single full-frame 'motion' detection as a generic fallback.
  • reportDetections(True, [...]) — explicit detections (typical case).
  • reportDetections(False) — clear.

Parameters:

Name Type Description Default
detected bool

Whether any object is currently detected.

required
detections list[TrackedDetection] | None

Optional explicit object detections (with optional tracking metadata).

None
Example
sensor.reportDetections(
    True,
    [
        TrackedDetection(
            label="person",
            confidence=0.92,
            box=BoundingBox(x=0.1, y=0.2, width=0.3, height=0.4),
        )
    ],
)
sensor.reportDetections(False)

clearDetections

clearDetections() -> None

Explicitly clear detection state (detected = False, detections = [], labels = []).

updateValue async

updateValue(property: str, value: Any) -> None

Read-only sensor: external writes are ignored. State is reported via reportDetections.

TrackedDetection

Bases: Detection

Detection enriched with tracking metadata (stable IDs, velocity).

OccupancySensor

OccupancySensor(name: str = 'Occupancy Sensor')

Bases: Sensor[OccupancySensorProperties, TStorage, str], Generic[TStorage]

Occupancy sensor for detecting presence in a room or area.

setDetected

setDetected(value: bool) -> None

Report occupancy state.

Parameters:

Name Type Description Default
value bool

True when the area is currently occupied.

required
Example
occupancy.setDetected(True)

updateValue async

updateValue(property: str, value: Any) -> None

Read-only sensor: external writes are ignored.

PTZCapability

Bases: str, Enum

Optional capabilities for PTZ controls.

PTZControl

PTZControl(name: str = 'PTZ')

Bases: Sensor[PTZControlProperties, TStorage, PTZCapability], Generic[TStorage]

Pan-tilt-zoom camera control.

Override setPosition() / setVelocity() / setTargetPreset() to drive hardware, then call the corresponding super().X() method after success to sync the SDK state. For hardware-pushed state updates (e.g. PTZ position change events), call the super methods from your event handler — that bypasses any plugin override and only syncs state.

Set capabilities to advertise supported axes and features. Use setPresets() to publish the discovered preset list and setMoving() to publish movement state.

setPosition async

setPosition(value: PTZPosition) -> None

Move to an absolute pan/tilt/zoom position. Override to drive hardware and call await super().setPosition(value) after success to sync the SDK state.

Parameters:

Name Type Description Default
value PTZPosition

Absolute pan/tilt/zoom target position.

required
Example
await ptz.setPosition({"pan": 0.25, "tilt": -0.1, "zoom": 0.5})

setVelocity async

setVelocity(value: PTZDirection | None) -> None

Continuous-move command. Override to drive hardware and call await super().setVelocity(value) after success to sync the SDK state.

Parameters:

Name Type Description Default
value PTZDirection | None

Per-axis speeds in [-1, 1], or None to stop.

required
Example
await ptz.setVelocity({"panSpeed": 0.5, "tiltSpeed": 0, "zoomSpeed": 0})
await ptz.setVelocity(None)  # stop

setTargetPreset async

setTargetPreset(value: str | None) -> None

Preset-move command. Override to drive hardware and call await super().setTargetPreset(value) after success to sync the SDK state.

Parameters:

Name Type Description Default
value str | None

Preset name to move to, or None to clear.

required
Example
await ptz.setTargetPreset("Driveway")

setPresets

setPresets(value: list[str]) -> None

Publish the discovered preset list (typically called once at startup).

Parameters:

Name Type Description Default
value list[str]

List of preset names supported by the camera.

required
Example
ptz.setPresets(["Home", "Driveway", "Backyard"])

setMoving

setMoving(value: bool) -> None

Publish movement state (e.g. when continuous-move starts/stops).

Parameters:

Name Type Description Default
value bool

True while the camera is moving.

required
Example
ptz.setMoving(True)

goHome async

goHome() -> None

Move the camera to the home position (pan=0, tilt=0, zoom=0).

Example
await ptz.goHome()

updateValue async

updateValue(property: str, value: Any) -> None

Routes generic property writes to semantic methods.

moving and presets are observed/discovered state and not externally writable; only Position, Velocity, and TargetPreset may be set.

PTZDirection

Bases: TypedDict

PTZ movement speed for continuous move commands.

Speeds are in normalized range [-1, 1] where:

  • -1 = maximum speed in negative direction
  • 0 = stop movement
  • 1 = maximum speed in positive direction

Conventions: positive panSpeed = right, positive tiltSpeed = up, positive zoomSpeed = zoom in. Plugins should clamp values to [-1, 1] and map them to hardware-specific speeds.

PTZPosition

Bases: TypedDict

Absolute PTZ position.

SecuritySystem

SecuritySystem(name: str = 'Security System')

Bases: Sensor[SecuritySystemProperties, TStorage, str], Generic[TStorage]

Security system control.

Override setTargetState() to drive hardware and call await super().setTargetState(value) once the hardware confirms — the base implementation updates both targetState and currentState.

setTargetState async

setTargetState(value: SecuritySystemState) -> None

Set the target state. Override to drive hardware and call await super().setTargetState(value) after success — the base implementation syncs both targetState and currentState to the new value.

Parameters:

Name Type Description Default
value SecuritySystemState

Desired armed/disarmed state from SecuritySystemState.

required
Example
from camera_ui_sdk import SecuritySystemState

await alarm.setTargetState(SecuritySystemState.AwayArm)

setCurrentState

setCurrentState(value: SecuritySystemState) -> None

Publish the actual security system state. Use this to drive transitions that diverge from the user-requested target — most notably the AlarmTriggered state when an intruder is detected, or arming-delay intermediate states. Read-only from cross-process consumers (updateValue ignores it).

Parameters:

Name Type Description Default
value SecuritySystemState

Current security system state from SecuritySystemState.

required
Example
from camera_ui_sdk import SecuritySystemState

alarm.setCurrentState(SecuritySystemState.AlarmTriggered)

updateValue async

updateValue(property: str, value: Any) -> None

Routes generic property writes to semantic methods.

SecuritySystemState

Bases: IntEnum

Security system arm/disarm states (HomeKit-compatible values).

StayArm class-attribute instance-attribute

StayArm = 0

Armed, occupants home.

AwayArm class-attribute instance-attribute

AwayArm = 1

Armed, occupants away.

NightArm class-attribute instance-attribute

NightArm = 2

Armed for night mode.

Disarmed class-attribute instance-attribute

Disarmed = 3

System disarmed.

AlarmTriggered class-attribute instance-attribute

AlarmTriggered = 4

Alarm is triggered.

SirenCapability

Bases: str, Enum

Optional capabilities for siren controls.

Volume class-attribute instance-attribute

Volume = 'volume'

Siren supports volume adjustment (0–100).

SirenControl

SirenControl(name: str = 'Siren')

Bases: Sensor[SirenControlProperties, TStorage, SirenCapability], Generic[TStorage]

Siren control sensor. Override setActive()/setInactive() to drive your hardware, then await super().setActive() / await super().setInactive() to sync the SDK state. For hardware-pushed updates, call the super methods from your event handler — that bypasses any plugin override and only syncs state.

setActive async

setActive() -> None

Activate the siren. Override to drive hardware and call await super().setActive() after success to sync the SDK state.

Example
await siren.setActive()

setInactive async

setInactive() -> None

Deactivate the siren. Override to drive hardware and call await super().setInactive() after success to sync the SDK state.

Example
await siren.setInactive()

setVolume async

setVolume(value: int) -> None

Set volume. Override to drive hardware and call await super().setVolume(value) after success. The default implementation clamps the value to [0, 100].

Parameters:

Name Type Description Default
value int

Volume level in the range 0–100.

required
Example
await siren.setVolume(80)

updateValue async

updateValue(property: str, value: Any) -> None

Routes generic property writes to semantic methods.

SmokeSensor

SmokeSensor(name: str = 'Smoke Sensor')

Bases: Sensor[SmokeSensorProperties, TStorage, str], Generic[TStorage]

Smoke detector sensor.

setDetected

setDetected(value: bool) -> None

Report smoke detection state.

Parameters:

Name Type Description Default
value bool

True when smoke is currently detected.

required
Example
smoke.setDetected(True)

updateValue async

updateValue(property: str, value: Any) -> None

Read-only sensor: external writes are ignored.

AudioInputSpec

Bases: TypedDict

Expected audio input format for an audio detector model.

AudioModelSpec

Bases: TypedDict

Model spec for audio detectors.

ModelSpec

Bases: TypedDict

Model spec for detectors with fixed output labels (face, classifier, license plate).

Declares the input shape the backend should produce and the trigger labels that should activate this detector.

ObjectModelSpec

Bases: TypedDict

Model spec for object detectors.

Only declares input dimensions — the output label set is dynamic and comes from the model itself.

VideoInputSpec

Bases: TypedDict

Expected video input dimensions and pixel format for a detector model.

SwitchControl

SwitchControl(name: str = 'Switch')

Bases: Sensor[SwitchControlProperties, TStorage, str], Generic[TStorage]

Generic on/off switch control. Override setOn() / setOff() to drive hardware and call await super().setOn() / await super().setOff() after success to sync the SDK state. For hardware-pushed updates, call the super methods from your event handler — that bypasses any plugin override and only syncs state.

setOn async

setOn() -> None

Turn the switch on. Override to drive hardware and call await super().setOn() after success to sync the SDK state.

Example
await sw.setOn()

setOff async

setOff() -> None

Turn the switch off. Override to drive hardware and call await super().setOff() after success to sync the SDK state.

Example
await sw.setOff()

updateValue async

updateValue(property: str, value: Any) -> None

Routes generic property writes to semantic methods.

TemperatureInfo

TemperatureInfo(name: str = 'Temperature')

Bases: Sensor[TemperatureInfoProperties, TStorage, str], Generic[TStorage]

Temperature info sensor. Reports current temperature in degrees Celsius.

setCurrent

setCurrent(value: float) -> None

Report a new temperature reading. Clamped to [-270, 100] degrees Celsius.

updateValue async

updateValue(property: str, value: Any) -> None

Read-only sensor: external writes are ignored.