Rework events for UniFi Protect (#107771)

pull/107773/head
Christopher Bailey 2024-01-11 00:02:16 -05:00 committed by GitHub
parent ec8a33b52d
commit 99e25d94c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 52 additions and 67 deletions

View File

@ -174,15 +174,6 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
ufp_value="is_vehicle_detection_on",
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(
key="smart_package",
name="Detections: Package",
@ -203,13 +194,22 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="smart_smoke",
name="Detections: Smoke/CO",
name="Detections: Smoke",
icon="mdi:fire",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_required_field="can_detect_smoke",
ufp_value="is_smoke_detection_on",
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, ...] = (
@ -350,7 +350,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
key="motion",
name="Motion",
device_class=BinarySensorDeviceClass.MOTION,
ufp_value="is_motion_detected",
ufp_value="is_motion_currently_detected",
ufp_enabled="is_motion_detection_on",
ufp_event_obj="last_motion_event",
),
@ -358,7 +358,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
key="smart_obj_any",
name="Object Detected",
icon="mdi:eye",
ufp_value="is_smart_detected",
ufp_value="is_smart_currently_detected",
ufp_required_field="feature_flags.has_smart_detect",
ufp_event_obj="last_smart_detect_event",
),
@ -366,7 +366,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
key="smart_obj_person",
name="Person Detected",
icon="mdi:walk",
ufp_value="is_smart_detected",
ufp_value="is_person_currently_detected",
ufp_required_field="can_detect_person",
ufp_enabled="is_person_detection_on",
ufp_event_obj="last_person_detect_event",
@ -375,25 +375,16 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
key="smart_obj_vehicle",
name="Vehicle Detected",
icon="mdi:car",
ufp_value="is_smart_detected",
ufp_value="is_vehicle_currently_detected",
ufp_required_field="can_detect_vehicle",
ufp_enabled="is_vehicle_detection_on",
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(
key="smart_obj_package",
name="Package Detected",
icon="mdi:package-variant-closed",
ufp_value="is_smart_detected",
ufp_value="is_package_currently_detected",
ufp_required_field="can_detect_package",
ufp_enabled="is_package_detection_on",
ufp_event_obj="last_package_detect_event",
@ -402,7 +393,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
key="smart_audio_any",
name="Audio Object Detected",
icon="mdi:eye",
ufp_value="is_smart_detected",
ufp_value="is_audio_currently_detected",
ufp_required_field="feature_flags.has_smart_detect",
ufp_event_obj="last_smart_audio_detect_event",
),
@ -410,7 +401,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
key="smart_audio_smoke",
name="Smoke Alarm Detected",
icon="mdi:fire",
ufp_value="is_smart_detected",
ufp_value="is_smoke_currently_detected",
ufp_required_field="can_detect_smoke",
ufp_enabled="is_smoke_detection_on",
ufp_event_obj="last_smoke_detect_event",
@ -418,10 +409,10 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
ProtectBinaryEventEntityDescription(
key="smart_audio_cmonx",
name="CO Alarm Detected",
icon="mdi:fire",
ufp_value="is_smart_detected",
ufp_required_field="can_detect_smoke",
ufp_enabled="is_smoke_detection_on",
icon="mdi:molecule-co",
ufp_value="is_cmonx_currently_detected",
ufp_required_field="can_detect_co",
ufp_enabled="is_co_detection_on",
ufp_event_obj="last_cmonx_detect_event",
),
)
@ -647,7 +638,7 @@ class ProtectEventBinarySensor(EventEntityMixin, BinarySensorEntity):
@callback
def _async_update_device_from_protect(self, device: ProtectModelWithId) -> None:
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
if not is_on:
self._event = None

View File

@ -10,7 +10,6 @@ from typing import TYPE_CHECKING, Any, Generic, TypeVar, cast
from pyunifiprotect.data import NVR, Event, ProtectAdoptableDeviceModel
from homeassistant.helpers.entity import EntityDescription
from homeassistant.util import dt as dt_util
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 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."""
if event is None:
return False
now = dt_util.utcnow()
value = now > event.start
if value and event.end is not None and now > event.end:
value = False
return value
return event is not None and self.get_ufp_value(obj)
@dataclass(frozen=True)

View File

@ -527,7 +527,7 @@ EVENT_SENSORS: tuple[ProtectSensorEventEntityDescription, ...] = (
name="License Plate Detected",
icon="mdi:car",
translation_key="license_plate",
ufp_value="is_smart_detected",
ufp_value="is_license_plate_currently_detected",
ufp_required_field="can_detect_license_plate",
ufp_event_obj="last_license_plate_detect_event",
),
@ -756,7 +756,7 @@ class ProtectEventSensor(EventEntityMixin, SensorEntity):
EventEntityMixin._async_update_device_from_protect(self, device)
event = self._event
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 = (
entity_description.ufp_event_obj == "last_license_plate_detect_event"
)

View File

@ -135,6 +135,16 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
ufp_set_method="set_osd_bitrate",
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(
key="motion",
name="Detections: Motion",
@ -167,17 +177,6 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
ufp_set_method="set_vehicle_detection",
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(
key="smart_package",
name="Detections: Package",
@ -202,7 +201,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="smart_smoke",
name="Detections: Smoke/CO",
name="Detections: Smoke",
icon="mdi:fire",
entity_category=EntityCategory.CONFIG,
ufp_required_field="can_detect_smoke",
@ -212,13 +211,14 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
ufp_perm=PermRequired.WRITE,
),
ProtectSwitchEntityDescription(
key="color_night_vision",
name="Color Night Vision",
icon="mdi:light-flood-down",
key="smart_cmonx",
name="Detections: CO",
icon="mdi:molecule-co",
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_required_field="can_detect_co",
ufp_value="is_co_detection_on",
ufp_enabled="is_recording_enabled",
ufp_set_method="set_cmonx_detection",
ufp_perm=PermRequired.WRITE,
),
)

View File

@ -33,12 +33,14 @@ from .utils import (
CAMERA_SWITCHES_BASIC = [
d
for d in CAMERA_SWITCHES
if d.name != "Detections: Face"
and d.name != "Detections: Package"
and d.name != "Detections: License Plate"
and d.name != "Detections: Smoke/CO"
and d.name != "SSH Enabled"
and d.name != "Color Night Vision"
if (
not d.name.startswith("Detections:")
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 = [
d for d in CAMERA_SWITCHES_BASIC if d.name not in ("High FPS", "Privacy Mode")