Rework events for UniFi Protect (#107771)
parent
ec8a33b52d
commit
99e25d94c0
|
@ -174,15 +174,6 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
|
||||||
ufp_value="is_vehicle_detection_on",
|
ufp_value="is_vehicle_detection_on",
|
||||||
ufp_perm=PermRequired.NO_WRITE,
|
ufp_perm=PermRequired.NO_WRITE,
|
||||||
),
|
),
|
||||||
ProtectBinaryEntityDescription(
|
|
||||||
key="smart_face",
|
|
||||||
name="Detections: Face",
|
|
||||||
icon="mdi:mdi-face",
|
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
|
||||||
ufp_required_field="can_detect_face",
|
|
||||||
ufp_value="is_face_detection_on",
|
|
||||||
ufp_perm=PermRequired.NO_WRITE,
|
|
||||||
),
|
|
||||||
ProtectBinaryEntityDescription(
|
ProtectBinaryEntityDescription(
|
||||||
key="smart_package",
|
key="smart_package",
|
||||||
name="Detections: Package",
|
name="Detections: Package",
|
||||||
|
@ -203,13 +194,22 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
|
||||||
),
|
),
|
||||||
ProtectBinaryEntityDescription(
|
ProtectBinaryEntityDescription(
|
||||||
key="smart_smoke",
|
key="smart_smoke",
|
||||||
name="Detections: Smoke/CO",
|
name="Detections: Smoke",
|
||||||
icon="mdi:fire",
|
icon="mdi:fire",
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
ufp_required_field="can_detect_smoke",
|
ufp_required_field="can_detect_smoke",
|
||||||
ufp_value="is_smoke_detection_on",
|
ufp_value="is_smoke_detection_on",
|
||||||
ufp_perm=PermRequired.NO_WRITE,
|
ufp_perm=PermRequired.NO_WRITE,
|
||||||
),
|
),
|
||||||
|
ProtectBinaryEntityDescription(
|
||||||
|
key="smart_cmonx",
|
||||||
|
name="Detections: CO",
|
||||||
|
icon="mdi:molecule-co",
|
||||||
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
|
ufp_required_field="can_detect_co",
|
||||||
|
ufp_value="is_co_detection_on",
|
||||||
|
ufp_perm=PermRequired.NO_WRITE,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
LIGHT_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
|
LIGHT_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
|
||||||
|
@ -350,7 +350,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
|
||||||
key="motion",
|
key="motion",
|
||||||
name="Motion",
|
name="Motion",
|
||||||
device_class=BinarySensorDeviceClass.MOTION,
|
device_class=BinarySensorDeviceClass.MOTION,
|
||||||
ufp_value="is_motion_detected",
|
ufp_value="is_motion_currently_detected",
|
||||||
ufp_enabled="is_motion_detection_on",
|
ufp_enabled="is_motion_detection_on",
|
||||||
ufp_event_obj="last_motion_event",
|
ufp_event_obj="last_motion_event",
|
||||||
),
|
),
|
||||||
|
@ -358,7 +358,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
|
||||||
key="smart_obj_any",
|
key="smart_obj_any",
|
||||||
name="Object Detected",
|
name="Object Detected",
|
||||||
icon="mdi:eye",
|
icon="mdi:eye",
|
||||||
ufp_value="is_smart_detected",
|
ufp_value="is_smart_currently_detected",
|
||||||
ufp_required_field="feature_flags.has_smart_detect",
|
ufp_required_field="feature_flags.has_smart_detect",
|
||||||
ufp_event_obj="last_smart_detect_event",
|
ufp_event_obj="last_smart_detect_event",
|
||||||
),
|
),
|
||||||
|
@ -366,7 +366,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
|
||||||
key="smart_obj_person",
|
key="smart_obj_person",
|
||||||
name="Person Detected",
|
name="Person Detected",
|
||||||
icon="mdi:walk",
|
icon="mdi:walk",
|
||||||
ufp_value="is_smart_detected",
|
ufp_value="is_person_currently_detected",
|
||||||
ufp_required_field="can_detect_person",
|
ufp_required_field="can_detect_person",
|
||||||
ufp_enabled="is_person_detection_on",
|
ufp_enabled="is_person_detection_on",
|
||||||
ufp_event_obj="last_person_detect_event",
|
ufp_event_obj="last_person_detect_event",
|
||||||
|
@ -375,25 +375,16 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
|
||||||
key="smart_obj_vehicle",
|
key="smart_obj_vehicle",
|
||||||
name="Vehicle Detected",
|
name="Vehicle Detected",
|
||||||
icon="mdi:car",
|
icon="mdi:car",
|
||||||
ufp_value="is_smart_detected",
|
ufp_value="is_vehicle_currently_detected",
|
||||||
ufp_required_field="can_detect_vehicle",
|
ufp_required_field="can_detect_vehicle",
|
||||||
ufp_enabled="is_vehicle_detection_on",
|
ufp_enabled="is_vehicle_detection_on",
|
||||||
ufp_event_obj="last_vehicle_detect_event",
|
ufp_event_obj="last_vehicle_detect_event",
|
||||||
),
|
),
|
||||||
ProtectBinaryEventEntityDescription(
|
|
||||||
key="smart_obj_face",
|
|
||||||
name="Face Detected",
|
|
||||||
icon="mdi:mdi-face",
|
|
||||||
ufp_value="is_smart_detected",
|
|
||||||
ufp_required_field="can_detect_face",
|
|
||||||
ufp_enabled="is_face_detection_on",
|
|
||||||
ufp_event_obj="last_face_detect_event",
|
|
||||||
),
|
|
||||||
ProtectBinaryEventEntityDescription(
|
ProtectBinaryEventEntityDescription(
|
||||||
key="smart_obj_package",
|
key="smart_obj_package",
|
||||||
name="Package Detected",
|
name="Package Detected",
|
||||||
icon="mdi:package-variant-closed",
|
icon="mdi:package-variant-closed",
|
||||||
ufp_value="is_smart_detected",
|
ufp_value="is_package_currently_detected",
|
||||||
ufp_required_field="can_detect_package",
|
ufp_required_field="can_detect_package",
|
||||||
ufp_enabled="is_package_detection_on",
|
ufp_enabled="is_package_detection_on",
|
||||||
ufp_event_obj="last_package_detect_event",
|
ufp_event_obj="last_package_detect_event",
|
||||||
|
@ -402,7 +393,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
|
||||||
key="smart_audio_any",
|
key="smart_audio_any",
|
||||||
name="Audio Object Detected",
|
name="Audio Object Detected",
|
||||||
icon="mdi:eye",
|
icon="mdi:eye",
|
||||||
ufp_value="is_smart_detected",
|
ufp_value="is_audio_currently_detected",
|
||||||
ufp_required_field="feature_flags.has_smart_detect",
|
ufp_required_field="feature_flags.has_smart_detect",
|
||||||
ufp_event_obj="last_smart_audio_detect_event",
|
ufp_event_obj="last_smart_audio_detect_event",
|
||||||
),
|
),
|
||||||
|
@ -410,7 +401,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
|
||||||
key="smart_audio_smoke",
|
key="smart_audio_smoke",
|
||||||
name="Smoke Alarm Detected",
|
name="Smoke Alarm Detected",
|
||||||
icon="mdi:fire",
|
icon="mdi:fire",
|
||||||
ufp_value="is_smart_detected",
|
ufp_value="is_smoke_currently_detected",
|
||||||
ufp_required_field="can_detect_smoke",
|
ufp_required_field="can_detect_smoke",
|
||||||
ufp_enabled="is_smoke_detection_on",
|
ufp_enabled="is_smoke_detection_on",
|
||||||
ufp_event_obj="last_smoke_detect_event",
|
ufp_event_obj="last_smoke_detect_event",
|
||||||
|
@ -418,10 +409,10 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
|
||||||
ProtectBinaryEventEntityDescription(
|
ProtectBinaryEventEntityDescription(
|
||||||
key="smart_audio_cmonx",
|
key="smart_audio_cmonx",
|
||||||
name="CO Alarm Detected",
|
name="CO Alarm Detected",
|
||||||
icon="mdi:fire",
|
icon="mdi:molecule-co",
|
||||||
ufp_value="is_smart_detected",
|
ufp_value="is_cmonx_currently_detected",
|
||||||
ufp_required_field="can_detect_smoke",
|
ufp_required_field="can_detect_co",
|
||||||
ufp_enabled="is_smoke_detection_on",
|
ufp_enabled="is_co_detection_on",
|
||||||
ufp_event_obj="last_cmonx_detect_event",
|
ufp_event_obj="last_cmonx_detect_event",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -647,7 +638,7 @@ class ProtectEventBinarySensor(EventEntityMixin, BinarySensorEntity):
|
||||||
@callback
|
@callback
|
||||||
def _async_update_device_from_protect(self, device: ProtectModelWithId) -> None:
|
def _async_update_device_from_protect(self, device: ProtectModelWithId) -> None:
|
||||||
super()._async_update_device_from_protect(device)
|
super()._async_update_device_from_protect(device)
|
||||||
is_on = self.entity_description.get_is_on(self._event)
|
is_on = self.entity_description.get_is_on(self.device, self._event)
|
||||||
self._attr_is_on: bool | None = is_on
|
self._attr_is_on: bool | None = is_on
|
||||||
if not is_on:
|
if not is_on:
|
||||||
self._event = None
|
self._event = None
|
||||||
|
|
|
@ -10,7 +10,6 @@ from typing import TYPE_CHECKING, Any, Generic, TypeVar, cast
|
||||||
from pyunifiprotect.data import NVR, Event, ProtectAdoptableDeviceModel
|
from pyunifiprotect.data import NVR, Event, ProtectAdoptableDeviceModel
|
||||||
|
|
||||||
from homeassistant.helpers.entity import EntityDescription
|
from homeassistant.helpers.entity import EntityDescription
|
||||||
from homeassistant.util import dt as dt_util
|
|
||||||
|
|
||||||
from .utils import get_nested_attr
|
from .utils import get_nested_attr
|
||||||
|
|
||||||
|
@ -114,17 +113,10 @@ class ProtectEventMixin(ProtectRequiredKeysMixin[T]):
|
||||||
return cast(Event, getattr(obj, self.ufp_event_obj, None))
|
return cast(Event, getattr(obj, self.ufp_event_obj, None))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_is_on(self, event: Event | None) -> bool:
|
def get_is_on(self, obj: T, event: Event | None) -> bool:
|
||||||
"""Return value if event is active."""
|
"""Return value if event is active."""
|
||||||
if event is None:
|
|
||||||
return False
|
|
||||||
|
|
||||||
now = dt_util.utcnow()
|
return event is not None and self.get_ufp_value(obj)
|
||||||
value = now > event.start
|
|
||||||
if value and event.end is not None and now > event.end:
|
|
||||||
value = False
|
|
||||||
|
|
||||||
return value
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
|
|
|
@ -527,7 +527,7 @@ EVENT_SENSORS: tuple[ProtectSensorEventEntityDescription, ...] = (
|
||||||
name="License Plate Detected",
|
name="License Plate Detected",
|
||||||
icon="mdi:car",
|
icon="mdi:car",
|
||||||
translation_key="license_plate",
|
translation_key="license_plate",
|
||||||
ufp_value="is_smart_detected",
|
ufp_value="is_license_plate_currently_detected",
|
||||||
ufp_required_field="can_detect_license_plate",
|
ufp_required_field="can_detect_license_plate",
|
||||||
ufp_event_obj="last_license_plate_detect_event",
|
ufp_event_obj="last_license_plate_detect_event",
|
||||||
),
|
),
|
||||||
|
@ -756,7 +756,7 @@ class ProtectEventSensor(EventEntityMixin, SensorEntity):
|
||||||
EventEntityMixin._async_update_device_from_protect(self, device)
|
EventEntityMixin._async_update_device_from_protect(self, device)
|
||||||
event = self._event
|
event = self._event
|
||||||
entity_description = self.entity_description
|
entity_description = self.entity_description
|
||||||
is_on = entity_description.get_is_on(event)
|
is_on = entity_description.get_is_on(self.device, self._event)
|
||||||
is_license_plate = (
|
is_license_plate = (
|
||||||
entity_description.ufp_event_obj == "last_license_plate_detect_event"
|
entity_description.ufp_event_obj == "last_license_plate_detect_event"
|
||||||
)
|
)
|
||||||
|
|
|
@ -135,6 +135,16 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
|
||||||
ufp_set_method="set_osd_bitrate",
|
ufp_set_method="set_osd_bitrate",
|
||||||
ufp_perm=PermRequired.WRITE,
|
ufp_perm=PermRequired.WRITE,
|
||||||
),
|
),
|
||||||
|
ProtectSwitchEntityDescription(
|
||||||
|
key="color_night_vision",
|
||||||
|
name="Color Night Vision",
|
||||||
|
icon="mdi:light-flood-down",
|
||||||
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
ufp_required_field="has_color_night_vision",
|
||||||
|
ufp_value="isp_settings.is_color_night_vision_enabled",
|
||||||
|
ufp_set_method="set_color_night_vision",
|
||||||
|
ufp_perm=PermRequired.WRITE,
|
||||||
|
),
|
||||||
ProtectSwitchEntityDescription(
|
ProtectSwitchEntityDescription(
|
||||||
key="motion",
|
key="motion",
|
||||||
name="Detections: Motion",
|
name="Detections: Motion",
|
||||||
|
@ -167,17 +177,6 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
|
||||||
ufp_set_method="set_vehicle_detection",
|
ufp_set_method="set_vehicle_detection",
|
||||||
ufp_perm=PermRequired.WRITE,
|
ufp_perm=PermRequired.WRITE,
|
||||||
),
|
),
|
||||||
ProtectSwitchEntityDescription(
|
|
||||||
key="smart_face",
|
|
||||||
name="Detections: Face",
|
|
||||||
icon="mdi:human-greeting",
|
|
||||||
entity_category=EntityCategory.CONFIG,
|
|
||||||
ufp_required_field="can_detect_face",
|
|
||||||
ufp_value="is_face_detection_on",
|
|
||||||
ufp_enabled="is_recording_enabled",
|
|
||||||
ufp_set_method="set_face_detection",
|
|
||||||
ufp_perm=PermRequired.WRITE,
|
|
||||||
),
|
|
||||||
ProtectSwitchEntityDescription(
|
ProtectSwitchEntityDescription(
|
||||||
key="smart_package",
|
key="smart_package",
|
||||||
name="Detections: Package",
|
name="Detections: Package",
|
||||||
|
@ -202,7 +201,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
|
||||||
),
|
),
|
||||||
ProtectSwitchEntityDescription(
|
ProtectSwitchEntityDescription(
|
||||||
key="smart_smoke",
|
key="smart_smoke",
|
||||||
name="Detections: Smoke/CO",
|
name="Detections: Smoke",
|
||||||
icon="mdi:fire",
|
icon="mdi:fire",
|
||||||
entity_category=EntityCategory.CONFIG,
|
entity_category=EntityCategory.CONFIG,
|
||||||
ufp_required_field="can_detect_smoke",
|
ufp_required_field="can_detect_smoke",
|
||||||
|
@ -212,13 +211,14 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
|
||||||
ufp_perm=PermRequired.WRITE,
|
ufp_perm=PermRequired.WRITE,
|
||||||
),
|
),
|
||||||
ProtectSwitchEntityDescription(
|
ProtectSwitchEntityDescription(
|
||||||
key="color_night_vision",
|
key="smart_cmonx",
|
||||||
name="Color Night Vision",
|
name="Detections: CO",
|
||||||
icon="mdi:light-flood-down",
|
icon="mdi:molecule-co",
|
||||||
entity_category=EntityCategory.CONFIG,
|
entity_category=EntityCategory.CONFIG,
|
||||||
ufp_required_field="has_color_night_vision",
|
ufp_required_field="can_detect_co",
|
||||||
ufp_value="isp_settings.is_color_night_vision_enabled",
|
ufp_value="is_co_detection_on",
|
||||||
ufp_set_method="set_color_night_vision",
|
ufp_enabled="is_recording_enabled",
|
||||||
|
ufp_set_method="set_cmonx_detection",
|
||||||
ufp_perm=PermRequired.WRITE,
|
ufp_perm=PermRequired.WRITE,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
@ -33,12 +33,14 @@ from .utils import (
|
||||||
CAMERA_SWITCHES_BASIC = [
|
CAMERA_SWITCHES_BASIC = [
|
||||||
d
|
d
|
||||||
for d in CAMERA_SWITCHES
|
for d in CAMERA_SWITCHES
|
||||||
if d.name != "Detections: Face"
|
if (
|
||||||
and d.name != "Detections: Package"
|
not d.name.startswith("Detections:")
|
||||||
and d.name != "Detections: License Plate"
|
and d.name != "SSH Enabled"
|
||||||
and d.name != "Detections: Smoke/CO"
|
and d.name != "Color Night Vision"
|
||||||
and d.name != "SSH Enabled"
|
)
|
||||||
and d.name != "Color Night Vision"
|
or d.name == "Detections: Motion"
|
||||||
|
or d.name == "Detections: Person"
|
||||||
|
or d.name == "Detections: Vehicle"
|
||||||
]
|
]
|
||||||
CAMERA_SWITCHES_NO_EXTRA = [
|
CAMERA_SWITCHES_NO_EXTRA = [
|
||||||
d for d in CAMERA_SWITCHES_BASIC if d.name not in ("High FPS", "Privacy Mode")
|
d for d in CAMERA_SWITCHES_BASIC if d.name not in ("High FPS", "Privacy Mode")
|
||||||
|
|
Loading…
Reference in New Issue