diff --git a/homeassistant/components/unifiprotect/binary_sensor.py b/homeassistant/components/unifiprotect/binary_sensor.py index 5aff0b732df..e156a60c787 100644 --- a/homeassistant/components/unifiprotect/binary_sensor.py +++ b/homeassistant/components/unifiprotect/binary_sensor.py @@ -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 diff --git a/homeassistant/components/unifiprotect/models.py b/homeassistant/components/unifiprotect/models.py index 7f5612a72a8..08f5c2075e6 100644 --- a/homeassistant/components/unifiprotect/models.py +++ b/homeassistant/components/unifiprotect/models.py @@ -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) diff --git a/homeassistant/components/unifiprotect/sensor.py b/homeassistant/components/unifiprotect/sensor.py index 3b9dfbd1f83..212c0d5245b 100644 --- a/homeassistant/components/unifiprotect/sensor.py +++ b/homeassistant/components/unifiprotect/sensor.py @@ -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" ) diff --git a/homeassistant/components/unifiprotect/switch.py b/homeassistant/components/unifiprotect/switch.py index 324fe56cea2..f3224e086a5 100644 --- a/homeassistant/components/unifiprotect/switch.py +++ b/homeassistant/components/unifiprotect/switch.py @@ -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, ), ) diff --git a/tests/components/unifiprotect/test_switch.py b/tests/components/unifiprotect/test_switch.py index 17db53d05ec..70a21a324d0 100644 --- a/tests/components/unifiprotect/test_switch.py +++ b/tests/components/unifiprotect/test_switch.py @@ -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")