Migrate unifiprotect to use has_entity_name (#119759)

This commit is contained in:
J. Nick Koston 2024-06-16 09:00:14 -05:00 committed by GitHub
parent b20160a465
commit 59ca5b04fa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 198 additions and 270 deletions

View file

@ -63,13 +63,13 @@ MOUNT_DEVICE_CLASS_MAP = {
CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
ProtectBinaryEntityDescription(
key="dark",
name="Is Dark",
name="Is dark",
icon="mdi:brightness-6",
ufp_value="is_dark",
),
ProtectBinaryEntityDescription(
key="ssh",
name="SSH Enabled",
name="SSH enabled",
icon="mdi:lock",
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
@ -78,7 +78,7 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="status_light",
name="Status Light On",
name="Status light on",
icon="mdi:led-on",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_required_field="feature_flags.has_led_status",
@ -87,7 +87,7 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="hdr_mode",
name="HDR Mode",
name="HDR mode",
icon="mdi:brightness-7",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_required_field="feature_flags.has_hdr",
@ -105,7 +105,7 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="system_sounds",
name="System Sounds",
name="System sounds",
icon="mdi:speaker",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_required_field="has_speaker",
@ -115,7 +115,7 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="osd_name",
name="Overlay: Show Name",
name="Overlay: show name",
icon="mdi:fullscreen",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_value="osd_settings.is_name_enabled",
@ -123,7 +123,7 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="osd_date",
name="Overlay: Show Date",
name="Overlay: show date",
icon="mdi:fullscreen",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_value="osd_settings.is_date_enabled",
@ -131,7 +131,7 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="osd_logo",
name="Overlay: Show Logo",
name="Overlay: show logo",
icon="mdi:fullscreen",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_value="osd_settings.is_logo_enabled",
@ -139,7 +139,7 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="osd_bitrate",
name="Overlay: Show Bitrate",
name="Overlay: show bitrate",
icon="mdi:fullscreen",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_value="osd_settings.is_debug_enabled",
@ -147,14 +147,14 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="motion_enabled",
name="Detections: Motion",
name="Detections: motion",
icon="mdi:run-fast",
ufp_value="recording_settings.enable_motion_detection",
ufp_perm=PermRequired.NO_WRITE,
),
ProtectBinaryEntityDescription(
key="smart_person",
name="Detections: Person",
name="Detections: person",
icon="mdi:walk",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_required_field="can_detect_person",
@ -163,7 +163,7 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="smart_vehicle",
name="Detections: Vehicle",
name="Detections: vehicle",
icon="mdi:car",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_required_field="can_detect_vehicle",
@ -172,7 +172,7 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="smart_animal",
name="Detections: Animal",
name="Detections: animal",
icon="mdi:paw",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_required_field="can_detect_animal",
@ -181,7 +181,7 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="smart_package",
name="Detections: Package",
name="Detections: package",
icon="mdi:package-variant-closed",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_required_field="can_detect_package",
@ -190,7 +190,7 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="smart_licenseplate",
name="Detections: License Plate",
name="Detections: license plate",
icon="mdi:car",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_required_field="can_detect_license_plate",
@ -199,7 +199,7 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="smart_smoke",
name="Detections: Smoke",
name="Detections: smoke",
icon="mdi:fire",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_required_field="can_detect_smoke",
@ -217,7 +217,7 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="smart_siren",
name="Detections: Siren",
name="Detections: siren",
icon="mdi:alarm-bell",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_required_field="can_detect_siren",
@ -226,7 +226,7 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="smart_baby_cry",
name="Detections: Baby Cry",
name="Detections: baby cry",
icon="mdi:cradle",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_required_field="can_detect_baby_cry",
@ -235,7 +235,7 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="smart_speak",
name="Detections: Speaking",
name="Detections: speaking",
icon="mdi:account-voice",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_required_field="can_detect_speaking",
@ -244,7 +244,7 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="smart_bark",
name="Detections: Barking",
name="Detections: barking",
icon="mdi:dog",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_required_field="can_detect_bark",
@ -253,7 +253,7 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="smart_car_alarm",
name="Detections: Car Alarm",
name="Detections: car alarm",
icon="mdi:car",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_required_field="can_detect_car_alarm",
@ -262,7 +262,7 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="smart_car_horn",
name="Detections: Car Horn",
name="Detections: car horn",
icon="mdi:bugle",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_required_field="can_detect_car_horn",
@ -271,7 +271,7 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="smart_glass_break",
name="Detections: Glass Break",
name="Detections: glass break",
icon="mdi:glass-fragile",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_required_field="can_detect_glass_break",
@ -280,7 +280,7 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="track_person",
name="Tracking: Person",
name="Tracking: person",
icon="mdi:walk",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_required_field="is_ptz",
@ -292,19 +292,19 @@ CAMERA_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
LIGHT_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
ProtectBinaryEntityDescription(
key="dark",
name="Is Dark",
name="Is dark",
icon="mdi:brightness-6",
ufp_value="is_dark",
),
ProtectBinaryEntityDescription(
key="motion",
name="Motion Detected",
name="Motion detected",
device_class=BinarySensorDeviceClass.MOTION,
ufp_value="is_pir_motion_detected",
),
ProtectBinaryEntityDescription(
key="light",
name="Flood Light",
name="Flood light",
icon="mdi:spotlight-beam",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_value="is_light_on",
@ -312,7 +312,7 @@ LIGHT_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="ssh",
name="SSH Enabled",
name="SSH enabled",
icon="mdi:lock",
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
@ -321,7 +321,7 @@ LIGHT_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="status_light",
name="Status Light On",
name="Status light on",
icon="mdi:led-on",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_value="light_device_settings.is_indicator_enabled",
@ -358,20 +358,20 @@ SENSE_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="motion",
name="Motion Detected",
name="Motion detected",
device_class=BinarySensorDeviceClass.MOTION,
ufp_value="is_motion_detected",
ufp_enabled="is_motion_sensor_enabled",
),
ProtectBinaryEntityDescription(
key="tampering",
name="Tampering Detected",
name="Tampering detected",
device_class=BinarySensorDeviceClass.TAMPER,
ufp_value="is_tampering_detected",
),
ProtectBinaryEntityDescription(
key="status_light",
name="Status Light On",
name="Status light on",
icon="mdi:led-on",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_value="led_settings.is_enabled",
@ -379,7 +379,7 @@ SENSE_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="motion_enabled",
name="Motion Detection",
name="Motion detection",
icon="mdi:walk",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_value="motion_settings.is_enabled",
@ -387,7 +387,7 @@ SENSE_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="temperature",
name="Temperature Sensor",
name="Temperature sensor",
icon="mdi:thermometer",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_value="temperature_settings.is_enabled",
@ -395,7 +395,7 @@ SENSE_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="humidity",
name="Humidity Sensor",
name="Humidity sensor",
icon="mdi:water-percent",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_value="humidity_settings.is_enabled",
@ -403,7 +403,7 @@ SENSE_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="light",
name="Light Sensor",
name="Light sensor",
icon="mdi:brightness-5",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_value="light_settings.is_enabled",
@ -411,7 +411,7 @@ SENSE_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="alarm",
name="Alarm Sound Detection",
name="Alarm sound detection",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_value="alarm_settings.is_enabled",
ufp_perm=PermRequired.NO_WRITE,
@ -438,7 +438,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
),
ProtectBinaryEventEntityDescription(
key="smart_obj_any",
name="Object Detected",
name="Object detected",
icon="mdi:eye",
ufp_value="is_smart_currently_detected",
ufp_required_field="feature_flags.has_smart_detect",
@ -446,7 +446,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
),
ProtectBinaryEventEntityDescription(
key="smart_obj_person",
name="Person Detected",
name="Person detected",
icon="mdi:walk",
ufp_value="is_person_currently_detected",
ufp_required_field="can_detect_person",
@ -455,7 +455,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
),
ProtectBinaryEventEntityDescription(
key="smart_obj_vehicle",
name="Vehicle Detected",
name="Vehicle detected",
icon="mdi:car",
ufp_value="is_vehicle_currently_detected",
ufp_required_field="can_detect_vehicle",
@ -464,7 +464,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
),
ProtectBinaryEventEntityDescription(
key="smart_obj_animal",
name="Animal Detected",
name="Animal detected",
icon="mdi:paw",
ufp_value="is_animal_currently_detected",
ufp_required_field="can_detect_animal",
@ -473,7 +473,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
),
ProtectBinaryEventEntityDescription(
key="smart_obj_package",
name="Package Detected",
name="Package detected",
icon="mdi:package-variant-closed",
ufp_value="is_package_currently_detected",
entity_registry_enabled_default=False,
@ -483,7 +483,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
),
ProtectBinaryEventEntityDescription(
key="smart_audio_any",
name="Audio Object Detected",
name="Audio object detected",
icon="mdi:eye",
ufp_value="is_audio_currently_detected",
ufp_required_field="feature_flags.has_smart_detect",
@ -491,7 +491,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
),
ProtectBinaryEventEntityDescription(
key="smart_audio_smoke",
name="Smoke Alarm Detected",
name="Smoke alarm detected",
icon="mdi:fire",
ufp_value="is_smoke_currently_detected",
ufp_required_field="can_detect_smoke",
@ -500,7 +500,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
),
ProtectBinaryEventEntityDescription(
key="smart_audio_cmonx",
name="CO Alarm Detected",
name="CO alarm detected",
icon="mdi:molecule-co",
ufp_value="is_cmonx_currently_detected",
ufp_required_field="can_detect_co",
@ -509,7 +509,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
),
ProtectBinaryEventEntityDescription(
key="smart_audio_siren",
name="Siren Detected",
name="Siren detected",
icon="mdi:alarm-bell",
ufp_value="is_siren_currently_detected",
ufp_required_field="can_detect_siren",
@ -518,7 +518,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
),
ProtectBinaryEventEntityDescription(
key="smart_audio_baby_cry",
name="Baby Cry Detected",
name="Baby cry detected",
icon="mdi:cradle",
ufp_value="is_baby_cry_currently_detected",
ufp_required_field="can_detect_baby_cry",
@ -527,7 +527,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
),
ProtectBinaryEventEntityDescription(
key="smart_audio_speak",
name="Speaking Detected",
name="Speaking detected",
icon="mdi:account-voice",
ufp_value="is_speaking_currently_detected",
ufp_required_field="can_detect_speaking",
@ -536,7 +536,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
),
ProtectBinaryEventEntityDescription(
key="smart_audio_bark",
name="Barking Detected",
name="Barking detected",
icon="mdi:dog",
ufp_value="is_bark_currently_detected",
ufp_required_field="can_detect_bark",
@ -545,7 +545,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
),
ProtectBinaryEventEntityDescription(
key="smart_audio_car_alarm",
name="Car Alarm Detected",
name="Car alarm detected",
icon="mdi:car",
ufp_value="is_car_alarm_currently_detected",
ufp_required_field="can_detect_car_alarm",
@ -554,7 +554,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
),
ProtectBinaryEventEntityDescription(
key="smart_audio_car_horn",
name="Car Horn Detected",
name="Car horn detected",
icon="mdi:bugle",
ufp_value="is_car_horn_currently_detected",
ufp_required_field="can_detect_car_horn",
@ -563,7 +563,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
),
ProtectBinaryEventEntityDescription(
key="smart_audio_glass_break",
name="Glass Break Detected",
name="Glass break detected",
icon="mdi:glass-fragile",
ufp_value="last_glass_break_detect",
ufp_required_field="can_detect_glass_break",
@ -582,7 +582,7 @@ DOORLOCK_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
),
ProtectBinaryEntityDescription(
key="status_light",
name="Status Light On",
name="Status light on",
icon="mdi:led-on",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_value="led_settings.is_enabled",
@ -593,7 +593,7 @@ DOORLOCK_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
VIEWER_SENSORS: tuple[ProtectBinaryEntityDescription, ...] = (
ProtectBinaryEntityDescription(
key="ssh",
name="SSH Enabled",
name="SSH enabled",
icon="mdi:lock",
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,

View file

@ -21,7 +21,7 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DEVICES_THAT_ADOPT, DISPATCH_ADD, DOMAIN
from .data import ProtectData, UFPConfigEntry
from .data import UFPConfigEntry
from .entity import ProtectDeviceEntity, async_all_device_entities
from .models import PermRequired, ProtectEntityDescription, ProtectSetableKeysMixin, T
from .utils import async_dispatch_id as _ufpd
@ -47,14 +47,14 @@ ALL_DEVICE_BUTTONS: tuple[ProtectButtonEntityDescription, ...] = (
key="reboot",
entity_registry_enabled_default=False,
device_class=ButtonDeviceClass.RESTART,
name="Reboot Device",
name="Reboot device",
ufp_press="reboot",
ufp_perm=PermRequired.WRITE,
),
ProtectButtonEntityDescription(
key="unadopt",
entity_registry_enabled_default=False,
name="Unadopt Device",
name="Unadopt device",
icon="mdi:delete",
ufp_press="unadopt",
ufp_perm=PermRequired.DELETE,
@ -63,7 +63,7 @@ ALL_DEVICE_BUTTONS: tuple[ProtectButtonEntityDescription, ...] = (
ADOPT_BUTTON = ProtectButtonEntityDescription[ProtectAdoptableDeviceModel](
key=KEY_ADOPT,
name="Adopt Device",
name="Adopt device",
icon="mdi:plus-circle",
ufp_press="adopt",
)
@ -71,7 +71,7 @@ ADOPT_BUTTON = ProtectButtonEntityDescription[ProtectAdoptableDeviceModel](
SENSOR_BUTTONS: tuple[ProtectButtonEntityDescription, ...] = (
ProtectButtonEntityDescription(
key="clear_tamper",
name="Clear Tamper",
name="Clear tamper",
icon="mdi:notification-clear-all",
ufp_press="clear_tamper",
ufp_perm=PermRequired.WRITE,
@ -81,14 +81,14 @@ SENSOR_BUTTONS: tuple[ProtectButtonEntityDescription, ...] = (
CHIME_BUTTONS: tuple[ProtectButtonEntityDescription, ...] = (
ProtectButtonEntityDescription(
key="play",
name="Play Chime",
name="Play chime",
device_class=DEVICE_CLASS_CHIME_BUTTON,
icon="mdi:play",
ufp_press="play",
),
ProtectButtonEntityDescription(
key="play_buzzer",
name="Play Buzzer",
name="Play buzzer",
icon="mdi:play",
ufp_press="play_buzzer",
),
@ -173,16 +173,6 @@ class ProtectButton(ProtectDeviceEntity, ButtonEntity):
entity_description: ProtectButtonEntityDescription
def __init__(
self,
data: ProtectData,
device: ProtectAdoptableDeviceModel,
description: ProtectButtonEntityDescription,
) -> None:
"""Initialize an UniFi camera."""
super().__init__(data, device, description)
self._attr_name = f"{self.device.display_name} {self.entity_description.name}"
@callback
def _async_update_device_from_protect(self, device: ProtectModelWithId) -> None:
super()._async_update_device_from_protect(device)

View file

@ -191,10 +191,10 @@ class ProtectCamera(ProtectDeviceEntity, Camera):
camera_name = get_camera_base_name(channel)
if self._secure:
self._attr_unique_id = f"{device.mac}_{channel.id}"
self._attr_name = f"{device.display_name} {camera_name}"
self._attr_name = camera_name
else:
self._attr_unique_id = f"{device.mac}_{channel.id}_insecure"
self._attr_name = f"{device.display_name} {camera_name} (Insecure)"
self._attr_name = f"{camera_name} (insecure)"
# only the default (first) channel is enabled by default
self._attr_entity_registry_enabled_default = is_default and secure

View file

@ -21,7 +21,6 @@ from homeassistant.core import callback
import homeassistant.helpers.device_registry as dr
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity import Entity, EntityDescription
from homeassistant.helpers.typing import UNDEFINED
from .const import (
ATTR_EVENT_ID,
@ -165,6 +164,8 @@ class BaseProtectEntity(Entity):
_attr_should_poll = False
_attr_attribution = DEFAULT_ATTRIBUTION
_state_attrs: tuple[str, ...] = ("_attr_available",)
_attr_has_entity_name = True
_async_get_ufp_enabled: Callable[[ProtectAdoptableDeviceModel], bool] | None = None
def __init__(
self,
@ -174,24 +175,15 @@ class BaseProtectEntity(Entity):
) -> None:
"""Initialize the entity."""
super().__init__()
self.data: ProtectData = data
self.data = data
self.device = device
self._async_get_ufp_enabled: (
Callable[[ProtectAdoptableDeviceModel], bool] | None
) = None
if description is None:
self._attr_unique_id = f"{self.device.mac}"
self._attr_name = f"{self.device.display_name}"
self._attr_unique_id = self.device.mac
self._attr_name = None
else:
self.entity_description = description
self._attr_unique_id = f"{self.device.mac}_{description.key}"
name = (
description.name
if description.name and description.name is not UNDEFINED
else ""
)
self._attr_name = f"{self.device.display_name} {name.title()}"
if isinstance(description, ProtectEntityDescription):
self._async_get_ufp_enabled = description.get_ufp_enabled

View file

@ -17,7 +17,7 @@ from homeassistant.components.lock import LockEntity, LockEntityDescription
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .data import ProtectData, UFPConfigEntry
from .data import UFPConfigEntry
from .entity import ProtectDeviceEntity
_LOGGER = logging.getLogger(__name__)
@ -39,7 +39,9 @@ async def async_setup_entry(
data.async_subscribe_adopt(_add_new_device)
async_add_entities(
ProtectLock(data, cast(Doorlock, device))
ProtectLock(
data, cast(Doorlock, device), LockEntityDescription(key="lock", name="Lock")
)
for device in data.get_by_types({ModelType.DOORLOCK})
)
@ -57,20 +59,6 @@ class ProtectLock(ProtectDeviceEntity, LockEntity):
"_attr_is_jammed",
)
def __init__(
self,
data: ProtectData,
doorlock: Doorlock,
) -> None:
"""Initialize an UniFi lock."""
super().__init__(
data,
doorlock,
LockEntityDescription(key="lock"),
)
self._attr_name = f"{self.device.display_name} Lock"
@callback
def _async_update_device_from_protect(self, device: ProtectModelWithId) -> None:
super()._async_update_device_from_protect(device)

View file

@ -28,11 +28,15 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .data import ProtectData, UFPConfigEntry
from .data import UFPConfigEntry
from .entity import ProtectDeviceEntity
_LOGGER = logging.getLogger(__name__)
_SPEAKER_DESCRIPTION = MediaPlayerEntityDescription(
key="speaker", name="Speaker", device_class=MediaPlayerDeviceClass.SPEAKER
)
async def async_setup_entry(
hass: HomeAssistant,
@ -51,7 +55,7 @@ async def async_setup_entry(
data.async_subscribe_adopt(_add_new_device)
async_add_entities(
ProtectMediaPlayer(data, device)
ProtectMediaPlayer(data, device, _SPEAKER_DESCRIPTION)
for device in data.get_cameras()
if device.has_speaker or device.has_removable_speaker
)
@ -69,25 +73,9 @@ class ProtectMediaPlayer(ProtectDeviceEntity, MediaPlayerEntity):
| MediaPlayerEntityFeature.STOP
| MediaPlayerEntityFeature.BROWSE_MEDIA
)
_attr_media_content_type = MediaType.MUSIC
_state_attrs = ("_attr_available", "_attr_state", "_attr_volume_level")
def __init__(
self,
data: ProtectData,
camera: Camera,
) -> None:
"""Initialize an UniFi speaker."""
super().__init__(
data,
camera,
MediaPlayerEntityDescription(
key="speaker", device_class=MediaPlayerDeviceClass.SPEAKER
),
)
self._attr_name = f"{self.device.display_name} Speaker"
self._attr_media_content_type = MediaType.MUSIC
@callback
def _async_update_device_from_protect(self, device: ProtectModelWithId) -> None:
super()._async_update_device_from_protect(device)

View file

@ -59,7 +59,7 @@ def _get_chime_duration(obj: Camera) -> int:
CAMERA_NUMBERS: tuple[ProtectNumberEntityDescription, ...] = (
ProtectNumberEntityDescription(
key="wdr_value",
name="Wide Dynamic Range",
name="Wide dynamic range",
icon="mdi:state-machine",
entity_category=EntityCategory.CONFIG,
ufp_min=0,
@ -72,7 +72,7 @@ CAMERA_NUMBERS: tuple[ProtectNumberEntityDescription, ...] = (
),
ProtectNumberEntityDescription(
key="mic_level",
name="Microphone Level",
name="Microphone level",
icon="mdi:microphone",
entity_category=EntityCategory.CONFIG,
native_unit_of_measurement=PERCENTAGE,
@ -87,7 +87,7 @@ CAMERA_NUMBERS: tuple[ProtectNumberEntityDescription, ...] = (
),
ProtectNumberEntityDescription(
key="zoom_position",
name="Zoom Level",
name="Zoom level",
icon="mdi:magnify-plus-outline",
entity_category=EntityCategory.CONFIG,
native_unit_of_measurement=PERCENTAGE,
@ -101,7 +101,7 @@ CAMERA_NUMBERS: tuple[ProtectNumberEntityDescription, ...] = (
),
ProtectNumberEntityDescription(
key="chime_duration",
name="Chime Duration",
name="Chime duration",
icon="mdi:bell",
entity_category=EntityCategory.CONFIG,
native_unit_of_measurement=UnitOfTime.SECONDS,
@ -116,7 +116,7 @@ CAMERA_NUMBERS: tuple[ProtectNumberEntityDescription, ...] = (
),
ProtectNumberEntityDescription(
key="icr_lux",
name="Infrared Custom Lux Trigger",
name="Infrared custom lux trigger",
icon="mdi:white-balance-sunny",
entity_category=EntityCategory.CONFIG,
ufp_min=1,
@ -133,7 +133,7 @@ CAMERA_NUMBERS: tuple[ProtectNumberEntityDescription, ...] = (
LIGHT_NUMBERS: tuple[ProtectNumberEntityDescription, ...] = (
ProtectNumberEntityDescription(
key="sensitivity",
name="Motion Sensitivity",
name="Motion sensitivity",
icon="mdi:walk",
entity_category=EntityCategory.CONFIG,
native_unit_of_measurement=PERCENTAGE,
@ -147,7 +147,7 @@ LIGHT_NUMBERS: tuple[ProtectNumberEntityDescription, ...] = (
),
ProtectNumberEntityDescription[Light](
key="duration",
name="Auto-shutoff Duration",
name="Auto-shutoff duration",
icon="mdi:camera-timer",
entity_category=EntityCategory.CONFIG,
native_unit_of_measurement=UnitOfTime.SECONDS,
@ -164,7 +164,7 @@ LIGHT_NUMBERS: tuple[ProtectNumberEntityDescription, ...] = (
SENSE_NUMBERS: tuple[ProtectNumberEntityDescription, ...] = (
ProtectNumberEntityDescription(
key="sensitivity",
name="Motion Sensitivity",
name="Motion sensitivity",
icon="mdi:walk",
entity_category=EntityCategory.CONFIG,
native_unit_of_measurement=PERCENTAGE,
@ -181,7 +181,7 @@ SENSE_NUMBERS: tuple[ProtectNumberEntityDescription, ...] = (
DOORLOCK_NUMBERS: tuple[ProtectNumberEntityDescription, ...] = (
ProtectNumberEntityDescription[Doorlock](
key="auto_lock_time",
name="Auto-lock Timeout",
name="Auto-lock timeout",
icon="mdi:walk",
entity_category=EntityCategory.CONFIG,
native_unit_of_measurement=UnitOfTime.SECONDS,

View file

@ -188,7 +188,7 @@ async def _set_liveview(obj: Viewer, liveview_id: str) -> None:
CAMERA_SELECTS: tuple[ProtectSelectEntityDescription, ...] = (
ProtectSelectEntityDescription(
key="recording_mode",
name="Recording Mode",
name="Recording mode",
icon="mdi:video-outline",
entity_category=EntityCategory.CONFIG,
ufp_options=DEVICE_RECORDING_MODES,
@ -199,7 +199,7 @@ CAMERA_SELECTS: tuple[ProtectSelectEntityDescription, ...] = (
),
ProtectSelectEntityDescription(
key="infrared",
name="Infrared Mode",
name="Infrared mode",
icon="mdi:circle-opacity",
entity_category=EntityCategory.CONFIG,
ufp_required_field="feature_flags.has_led_ir",
@ -211,7 +211,7 @@ CAMERA_SELECTS: tuple[ProtectSelectEntityDescription, ...] = (
),
ProtectSelectEntityDescription[Camera](
key="doorbell_text",
name="Doorbell Text",
name="Doorbell text",
icon="mdi:card-text",
entity_category=EntityCategory.CONFIG,
device_class=DEVICE_CLASS_LCD_MESSAGE,
@ -223,7 +223,7 @@ CAMERA_SELECTS: tuple[ProtectSelectEntityDescription, ...] = (
),
ProtectSelectEntityDescription(
key="chime_type",
name="Chime Type",
name="Chime type",
icon="mdi:bell",
entity_category=EntityCategory.CONFIG,
ufp_required_field="feature_flags.has_chime",
@ -235,7 +235,7 @@ CAMERA_SELECTS: tuple[ProtectSelectEntityDescription, ...] = (
),
ProtectSelectEntityDescription(
key="hdr_mode",
name="HDR Mode",
name="HDR mode",
icon="mdi:brightness-7",
entity_category=EntityCategory.CONFIG,
ufp_required_field="feature_flags.has_hdr",
@ -249,7 +249,7 @@ CAMERA_SELECTS: tuple[ProtectSelectEntityDescription, ...] = (
LIGHT_SELECTS: tuple[ProtectSelectEntityDescription, ...] = (
ProtectSelectEntityDescription[Light](
key=_KEY_LIGHT_MOTION,
name="Light Mode",
name="Light mode",
icon="mdi:spotlight",
entity_category=EntityCategory.CONFIG,
ufp_options=MOTION_MODE_TO_LIGHT_MODE,
@ -259,7 +259,7 @@ LIGHT_SELECTS: tuple[ProtectSelectEntityDescription, ...] = (
),
ProtectSelectEntityDescription[Light](
key="paired_camera",
name="Paired Camera",
name="Paired camera",
icon="mdi:cctv",
entity_category=EntityCategory.CONFIG,
ufp_value="camera_id",
@ -272,7 +272,7 @@ LIGHT_SELECTS: tuple[ProtectSelectEntityDescription, ...] = (
SENSE_SELECTS: tuple[ProtectSelectEntityDescription, ...] = (
ProtectSelectEntityDescription(
key="mount_type",
name="Mount Type",
name="Mount type",
icon="mdi:screwdriver",
entity_category=EntityCategory.CONFIG,
ufp_options=MOUNT_TYPES,
@ -283,7 +283,7 @@ SENSE_SELECTS: tuple[ProtectSelectEntityDescription, ...] = (
),
ProtectSelectEntityDescription[Sensor](
key="paired_camera",
name="Paired Camera",
name="Paired camera",
icon="mdi:cctv",
entity_category=EntityCategory.CONFIG,
ufp_value="camera_id",
@ -296,7 +296,7 @@ SENSE_SELECTS: tuple[ProtectSelectEntityDescription, ...] = (
DOORLOCK_SELECTS: tuple[ProtectSelectEntityDescription, ...] = (
ProtectSelectEntityDescription[Doorlock](
key="paired_camera",
name="Paired Camera",
name="Paired camera",
icon="mdi:cctv",
entity_category=EntityCategory.CONFIG,
ufp_value="camera_id",
@ -369,7 +369,6 @@ class ProtectSelects(ProtectDeviceEntity, SelectEntity):
"""Initialize the unifi protect select entity."""
self._async_set_options(data, description)
super().__init__(data, device, description)
self._attr_name = f"{self.device.display_name} {self.entity_description.name}"
@callback
def _async_update_device_from_protect(self, device: ProtectModelWithId) -> None:

View file

@ -123,7 +123,7 @@ ALL_DEVICES_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="ble_signal",
name="Bluetooth Signal Strength",
name="Bluetooth signal strength",
native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
device_class=SensorDeviceClass.SIGNAL_STRENGTH,
entity_category=EntityCategory.DIAGNOSTIC,
@ -134,7 +134,7 @@ ALL_DEVICES_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="phy_rate",
name="Link Speed",
name="Link speed",
device_class=SensorDeviceClass.DATA_RATE,
native_unit_of_measurement=UnitOfDataRate.MEGABITS_PER_SECOND,
entity_category=EntityCategory.DIAGNOSTIC,
@ -145,7 +145,7 @@ ALL_DEVICES_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="wifi_signal",
name="WiFi Signal Strength",
name="WiFi signal strength",
native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
device_class=SensorDeviceClass.SIGNAL_STRENGTH,
entity_registry_enabled_default=False,
@ -159,7 +159,7 @@ ALL_DEVICES_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
CAMERA_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
ProtectSensorEntityDescription(
key="oldest_recording",
name="Oldest Recording",
name="Oldest recording",
device_class=SensorDeviceClass.TIMESTAMP,
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
@ -167,7 +167,7 @@ CAMERA_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="storage_used",
name="Storage Used",
name="Storage used",
native_unit_of_measurement=UnitOfInformation.BYTES,
device_class=SensorDeviceClass.DATA_SIZE,
entity_category=EntityCategory.DIAGNOSTIC,
@ -176,7 +176,7 @@ CAMERA_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="write_rate",
name="Disk Write Rate",
name="Disk write rate",
device_class=SensorDeviceClass.DATA_RATE,
native_unit_of_measurement=UnitOfDataRate.BYTES_PER_SECOND,
entity_category=EntityCategory.DIAGNOSTIC,
@ -199,7 +199,7 @@ CAMERA_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="doorbell_last_trip_time",
name="Last Doorbell Ring",
name="Last doorbell ring",
device_class=SensorDeviceClass.TIMESTAMP,
icon="mdi:doorbell-video",
ufp_required_field="feature_flags.is_doorbell",
@ -208,7 +208,7 @@ CAMERA_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="lens_type",
name="Lens Type",
name="Lens type",
entity_category=EntityCategory.DIAGNOSTIC,
icon="mdi:camera-iris",
ufp_required_field="has_removable_lens",
@ -216,7 +216,7 @@ CAMERA_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="mic_level",
name="Microphone Level",
name="Microphone level",
icon="mdi:microphone",
native_unit_of_measurement=PERCENTAGE,
entity_category=EntityCategory.DIAGNOSTIC,
@ -227,7 +227,7 @@ CAMERA_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="recording_mode",
name="Recording Mode",
name="Recording mode",
icon="mdi:video-outline",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_value="recording_settings.mode",
@ -235,7 +235,7 @@ CAMERA_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="infrared",
name="Infrared Mode",
name="Infrared mode",
icon="mdi:circle-opacity",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_required_field="feature_flags.has_led_ir",
@ -244,7 +244,7 @@ CAMERA_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="doorbell_text",
name="Doorbell Text",
name="Doorbell text",
icon="mdi:card-text",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_required_field="feature_flags.has_lcd_screen",
@ -253,7 +253,7 @@ CAMERA_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="chime_type",
name="Chime Type",
name="Chime type",
icon="mdi:bell",
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
@ -265,7 +265,7 @@ CAMERA_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
CAMERA_DISABLED_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
ProtectSensorEntityDescription(
key="stats_rx",
name="Received Data",
name="Received data",
native_unit_of_measurement=UnitOfInformation.BYTES,
device_class=SensorDeviceClass.DATA_SIZE,
entity_registry_enabled_default=False,
@ -275,7 +275,7 @@ CAMERA_DISABLED_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="stats_tx",
name="Transferred Data",
name="Transferred data",
native_unit_of_measurement=UnitOfInformation.BYTES,
device_class=SensorDeviceClass.DATA_SIZE,
entity_registry_enabled_default=False,
@ -288,7 +288,7 @@ CAMERA_DISABLED_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
SENSE_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
ProtectSensorEntityDescription(
key="battery_level",
name="Battery Level",
name="Battery level",
native_unit_of_measurement=PERCENTAGE,
device_class=SensorDeviceClass.BATTERY,
entity_category=EntityCategory.DIAGNOSTIC,
@ -297,7 +297,7 @@ SENSE_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="light_level",
name="Light Level",
name="Light level",
native_unit_of_measurement=LIGHT_LUX,
device_class=SensorDeviceClass.ILLUMINANCE,
state_class=SensorStateClass.MEASUREMENT,
@ -306,7 +306,7 @@ SENSE_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="humidity_level",
name="Humidity Level",
name="Humidity level",
native_unit_of_measurement=PERCENTAGE,
device_class=SensorDeviceClass.HUMIDITY,
state_class=SensorStateClass.MEASUREMENT,
@ -324,34 +324,34 @@ SENSE_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription[Sensor](
key="alarm_sound",
name="Alarm Sound Detected",
name="Alarm sound detected",
ufp_value_fn=_get_alarm_sound,
ufp_enabled="is_alarm_sensor_enabled",
),
ProtectSensorEntityDescription(
key="door_last_trip_time",
name="Last Open",
name="Last open",
device_class=SensorDeviceClass.TIMESTAMP,
ufp_value="open_status_changed_at",
entity_registry_enabled_default=False,
),
ProtectSensorEntityDescription(
key="motion_last_trip_time",
name="Last Motion Detected",
name="Last motion detected",
device_class=SensorDeviceClass.TIMESTAMP,
ufp_value="motion_detected_at",
entity_registry_enabled_default=False,
),
ProtectSensorEntityDescription(
key="tampering_last_trip_time",
name="Last Tampering Detected",
name="Last tampering detected",
device_class=SensorDeviceClass.TIMESTAMP,
ufp_value="tampering_detected_at",
entity_registry_enabled_default=False,
),
ProtectSensorEntityDescription(
key="sensitivity",
name="Motion Sensitivity",
name="Motion sensitivity",
icon="mdi:walk",
native_unit_of_measurement=PERCENTAGE,
entity_category=EntityCategory.DIAGNOSTIC,
@ -360,7 +360,7 @@ SENSE_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="mount_type",
name="Mount Type",
name="Mount type",
icon="mdi:screwdriver",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_value="mount_type",
@ -368,7 +368,7 @@ SENSE_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="paired_camera",
name="Paired Camera",
name="Paired camera",
icon="mdi:cctv",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_value="camera.display_name",
@ -379,7 +379,7 @@ SENSE_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
DOORLOCK_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
ProtectSensorEntityDescription(
key="battery_level",
name="Battery Level",
name="Battery level",
native_unit_of_measurement=PERCENTAGE,
device_class=SensorDeviceClass.BATTERY,
entity_category=EntityCategory.DIAGNOSTIC,
@ -388,7 +388,7 @@ DOORLOCK_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="paired_camera",
name="Paired Camera",
name="Paired camera",
icon="mdi:cctv",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_value="camera.display_name",
@ -407,7 +407,7 @@ NVR_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="storage_utilization",
name="Storage Utilization",
name="Storage utilization",
native_unit_of_measurement=PERCENTAGE,
icon="mdi:harddisk",
entity_category=EntityCategory.DIAGNOSTIC,
@ -417,7 +417,7 @@ NVR_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="record_rotating",
name="Type: Timelapse Video",
name="Type: timelapse video",
native_unit_of_measurement=PERCENTAGE,
icon="mdi:server",
entity_category=EntityCategory.DIAGNOSTIC,
@ -427,7 +427,7 @@ NVR_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="record_timelapse",
name="Type: Continuous Video",
name="Type: continuous video",
native_unit_of_measurement=PERCENTAGE,
icon="mdi:server",
entity_category=EntityCategory.DIAGNOSTIC,
@ -437,7 +437,7 @@ NVR_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="record_detections",
name="Type: Detections Video",
name="Type: detections video",
native_unit_of_measurement=PERCENTAGE,
icon="mdi:server",
entity_category=EntityCategory.DIAGNOSTIC,
@ -447,7 +447,7 @@ NVR_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="resolution_HD",
name="Resolution: HD Video",
name="Resolution: HD video",
native_unit_of_measurement=PERCENTAGE,
icon="mdi:cctv",
entity_category=EntityCategory.DIAGNOSTIC,
@ -457,7 +457,7 @@ NVR_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="resolution_4K",
name="Resolution: 4K Video",
name="Resolution: 4K video",
native_unit_of_measurement=PERCENTAGE,
icon="mdi:cctv",
entity_category=EntityCategory.DIAGNOSTIC,
@ -467,7 +467,7 @@ NVR_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="resolution_free",
name="Resolution: Free Space",
name="Resolution: free space",
native_unit_of_measurement=PERCENTAGE,
icon="mdi:cctv",
entity_category=EntityCategory.DIAGNOSTIC,
@ -477,7 +477,7 @@ NVR_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription[NVR](
key="record_capacity",
name="Recording Capacity",
name="Recording capacity",
native_unit_of_measurement=UnitOfTime.SECONDS,
icon="mdi:record-rec",
entity_category=EntityCategory.DIAGNOSTIC,
@ -489,7 +489,7 @@ NVR_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
NVR_DISABLED_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
ProtectSensorEntityDescription(
key="cpu_utilization",
name="CPU Utilization",
name="CPU utilization",
native_unit_of_measurement=PERCENTAGE,
icon="mdi:speedometer",
entity_registry_enabled_default=False,
@ -499,7 +499,7 @@ NVR_DISABLED_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="cpu_temperature",
name="CPU Temperature",
name="CPU temperature",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE,
entity_registry_enabled_default=False,
@ -509,7 +509,7 @@ NVR_DISABLED_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription[NVR](
key="memory_utilization",
name="Memory Utilization",
name="Memory utilization",
native_unit_of_measurement=PERCENTAGE,
icon="mdi:memory",
entity_registry_enabled_default=False,
@ -523,7 +523,7 @@ NVR_DISABLED_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
LICENSE_PLATE_EVENT_SENSORS: tuple[ProtectSensorEventEntityDescription, ...] = (
ProtectSensorEventEntityDescription(
key="smart_obj_licenseplate",
name="License Plate Detected",
name="License plate detected",
icon="mdi:car",
translation_key="license_plate",
ufp_value="is_license_plate_currently_detected",
@ -536,14 +536,14 @@ LICENSE_PLATE_EVENT_SENSORS: tuple[ProtectSensorEventEntityDescription, ...] = (
LIGHT_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
ProtectSensorEntityDescription(
key="motion_last_trip_time",
name="Last Motion Detected",
name="Last motion detected",
device_class=SensorDeviceClass.TIMESTAMP,
ufp_value="last_motion",
entity_registry_enabled_default=False,
),
ProtectSensorEntityDescription(
key="sensitivity",
name="Motion Sensitivity",
name="Motion sensitivity",
icon="mdi:walk",
native_unit_of_measurement=PERCENTAGE,
entity_category=EntityCategory.DIAGNOSTIC,
@ -552,7 +552,7 @@ LIGHT_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription[Light](
key="light_motion",
name="Light Mode",
name="Light mode",
icon="mdi:spotlight",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_value_fn=async_get_light_motion_current,
@ -560,7 +560,7 @@ LIGHT_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
),
ProtectSensorEntityDescription(
key="paired_camera",
name="Paired Camera",
name="Paired camera",
icon="mdi:cctv",
entity_category=EntityCategory.DIAGNOSTIC,
ufp_value="camera.display_name",
@ -571,7 +571,7 @@ LIGHT_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
MOTION_TRIP_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
ProtectSensorEntityDescription(
key="motion_last_trip_time",
name="Last Motion Detected",
name="Last motion detected",
device_class=SensorDeviceClass.TIMESTAMP,
ufp_value="last_motion",
entity_registry_enabled_default=False,
@ -581,7 +581,7 @@ MOTION_TRIP_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
CHIME_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
ProtectSensorEntityDescription(
key="last_ring",
name="Last Ring",
name="Last ring",
device_class=SensorDeviceClass.TIMESTAMP,
icon="mdi:bell",
ufp_value="last_ring",

View file

@ -4,11 +4,11 @@ from __future__ import annotations
from collections.abc import Sequence
from dataclasses import dataclass
from functools import partial
import logging
from typing import Any
from uiprotect.data import (
NVR,
Camera,
ModelType,
ProtectAdoptableDeviceModel,
@ -54,7 +54,7 @@ async def _set_highfps(obj: Camera, value: bool) -> None:
CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
ProtectSwitchEntityDescription(
key="ssh",
name="SSH Enabled",
name="SSH enabled",
icon="mdi:lock",
entity_registry_enabled_default=False,
entity_category=EntityCategory.CONFIG,
@ -64,7 +64,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="status_light",
name="Status Light On",
name="Status light on",
icon="mdi:led-on",
entity_category=EntityCategory.CONFIG,
ufp_required_field="feature_flags.has_led_status",
@ -74,7 +74,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="hdr_mode",
name="HDR Mode",
name="HDR mode",
icon="mdi:brightness-7",
entity_category=EntityCategory.CONFIG,
entity_registry_enabled_default=False,
@ -95,7 +95,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="system_sounds",
name="System Sounds",
name="System sounds",
icon="mdi:speaker",
entity_category=EntityCategory.CONFIG,
ufp_required_field="has_speaker",
@ -106,7 +106,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="osd_name",
name="Overlay: Show Name",
name="Overlay: show name",
icon="mdi:fullscreen",
entity_category=EntityCategory.CONFIG,
ufp_value="osd_settings.is_name_enabled",
@ -115,7 +115,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="osd_date",
name="Overlay: Show Date",
name="Overlay: show date",
icon="mdi:fullscreen",
entity_category=EntityCategory.CONFIG,
ufp_value="osd_settings.is_date_enabled",
@ -124,7 +124,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="osd_logo",
name="Overlay: Show Logo",
name="Overlay: show logo",
icon="mdi:fullscreen",
entity_category=EntityCategory.CONFIG,
ufp_value="osd_settings.is_logo_enabled",
@ -133,7 +133,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="osd_bitrate",
name="Overlay: Show Nerd Mode",
name="Overlay: show nerd mode",
icon="mdi:fullscreen",
entity_category=EntityCategory.CONFIG,
ufp_value="osd_settings.is_debug_enabled",
@ -142,7 +142,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="color_night_vision",
name="Color Night Vision",
name="Color night vision",
icon="mdi:light-flood-down",
entity_category=EntityCategory.CONFIG,
ufp_required_field="has_color_night_vision",
@ -152,7 +152,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="motion",
name="Detections: Motion",
name="Detections: motion",
icon="mdi:run-fast",
entity_category=EntityCategory.CONFIG,
ufp_value="recording_settings.enable_motion_detection",
@ -162,7 +162,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="smart_person",
name="Detections: Person",
name="Detections: person",
icon="mdi:walk",
entity_category=EntityCategory.CONFIG,
ufp_required_field="can_detect_person",
@ -173,7 +173,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="smart_vehicle",
name="Detections: Vehicle",
name="Detections: vehicle",
icon="mdi:car",
entity_category=EntityCategory.CONFIG,
ufp_required_field="can_detect_vehicle",
@ -184,7 +184,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="smart_animal",
name="Detections: Animal",
name="Detections: animal",
icon="mdi:paw",
entity_category=EntityCategory.CONFIG,
ufp_required_field="can_detect_animal",
@ -195,7 +195,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="smart_package",
name="Detections: Package",
name="Detections: package",
icon="mdi:package-variant-closed",
entity_category=EntityCategory.CONFIG,
ufp_required_field="can_detect_package",
@ -206,7 +206,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="smart_licenseplate",
name="Detections: License Plate",
name="Detections: license plate",
icon="mdi:car",
entity_category=EntityCategory.CONFIG,
ufp_required_field="can_detect_license_plate",
@ -217,7 +217,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="smart_smoke",
name="Detections: Smoke",
name="Detections: smoke",
icon="mdi:fire",
entity_category=EntityCategory.CONFIG,
ufp_required_field="can_detect_smoke",
@ -239,7 +239,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="smart_siren",
name="Detections: Siren",
name="Detections: siren",
icon="mdi:alarm-bell",
entity_category=EntityCategory.CONFIG,
ufp_required_field="can_detect_siren",
@ -250,7 +250,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="smart_baby_cry",
name="Detections: Baby Cry",
name="Detections: baby cry",
icon="mdi:cradle",
entity_category=EntityCategory.CONFIG,
ufp_required_field="can_detect_baby_cry",
@ -261,7 +261,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="smart_speak",
name="Detections: Speaking",
name="Detections: speaking",
icon="mdi:account-voice",
entity_category=EntityCategory.CONFIG,
ufp_required_field="can_detect_speaking",
@ -272,7 +272,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="smart_bark",
name="Detections: Barking",
name="Detections: barking",
icon="mdi:dog",
entity_category=EntityCategory.CONFIG,
ufp_required_field="can_detect_bark",
@ -283,7 +283,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="smart_car_alarm",
name="Detections: Car Alarm",
name="Detections: car alarm",
icon="mdi:car",
entity_category=EntityCategory.CONFIG,
ufp_required_field="can_detect_car_alarm",
@ -294,7 +294,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="smart_car_horn",
name="Detections: Car Horn",
name="Detections: car horn",
icon="mdi:bugle",
entity_category=EntityCategory.CONFIG,
ufp_required_field="can_detect_car_horn",
@ -305,7 +305,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="smart_glass_break",
name="Detections: Glass Break",
name="Detections: glass break",
icon="mdi:glass-fragile",
entity_category=EntityCategory.CONFIG,
ufp_required_field="can_detect_glass_break",
@ -316,7 +316,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="track_person",
name="Tracking: Person",
name="Tracking: person",
icon="mdi:walk",
entity_category=EntityCategory.CONFIG,
ufp_required_field="is_ptz",
@ -328,7 +328,7 @@ CAMERA_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
PRIVACY_MODE_SWITCH = ProtectSwitchEntityDescription[Camera](
key="privacy_mode",
name="Privacy Mode",
name="Privacy mode",
icon="mdi:eye-settings",
entity_category=EntityCategory.CONFIG,
ufp_required_field="feature_flags.has_privacy_mask",
@ -339,7 +339,7 @@ PRIVACY_MODE_SWITCH = ProtectSwitchEntityDescription[Camera](
SENSE_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
ProtectSwitchEntityDescription(
key="status_light",
name="Status Light On",
name="Status light on",
icon="mdi:led-on",
entity_category=EntityCategory.CONFIG,
ufp_value="led_settings.is_enabled",
@ -348,7 +348,7 @@ SENSE_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="motion",
name="Motion Detection",
name="Motion detection",
icon="mdi:walk",
entity_category=EntityCategory.CONFIG,
ufp_value="motion_settings.is_enabled",
@ -357,7 +357,7 @@ SENSE_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="temperature",
name="Temperature Sensor",
name="Temperature sensor",
icon="mdi:thermometer",
entity_category=EntityCategory.CONFIG,
ufp_value="temperature_settings.is_enabled",
@ -366,7 +366,7 @@ SENSE_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="humidity",
name="Humidity Sensor",
name="Humidity sensor",
icon="mdi:water-percent",
entity_category=EntityCategory.CONFIG,
ufp_value="humidity_settings.is_enabled",
@ -375,7 +375,7 @@ SENSE_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="light",
name="Light Sensor",
name="Light sensor",
icon="mdi:brightness-5",
entity_category=EntityCategory.CONFIG,
ufp_value="light_settings.is_enabled",
@ -384,7 +384,7 @@ SENSE_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="alarm",
name="Alarm Sound Detection",
name="Alarm sound detection",
entity_category=EntityCategory.CONFIG,
ufp_value="alarm_settings.is_enabled",
ufp_set_method="set_alarm_status",
@ -396,7 +396,7 @@ SENSE_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
LIGHT_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
ProtectSwitchEntityDescription(
key="ssh",
name="SSH Enabled",
name="SSH enabled",
icon="mdi:lock",
entity_registry_enabled_default=False,
entity_category=EntityCategory.CONFIG,
@ -406,7 +406,7 @@ LIGHT_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="status_light",
name="Status Light On",
name="Status light on",
icon="mdi:led-on",
entity_category=EntityCategory.CONFIG,
ufp_value="light_device_settings.is_indicator_enabled",
@ -418,7 +418,7 @@ LIGHT_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
DOORLOCK_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
ProtectSwitchEntityDescription(
key="status_light",
name="Status Light On",
name="Status light on",
icon="mdi:led-on",
entity_category=EntityCategory.CONFIG,
ufp_value="led_settings.is_enabled",
@ -430,7 +430,7 @@ DOORLOCK_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
VIEWER_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
ProtectSwitchEntityDescription(
key="ssh",
name="SSH Enabled",
name="SSH enabled",
icon="mdi:lock",
entity_registry_enabled_default=False,
entity_category=EntityCategory.CONFIG,
@ -443,7 +443,7 @@ VIEWER_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
NVR_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
ProtectSwitchEntityDescription(
key="analytics_enabled",
name="Analytics Enabled",
name="Analytics enabled",
icon="mdi:google-analytics",
entity_category=EntityCategory.CONFIG,
ufp_value="is_analytics_enabled",
@ -451,7 +451,7 @@ NVR_SWITCHES: tuple[ProtectSwitchEntityDescription, ...] = (
),
ProtectSwitchEntityDescription(
key="insights_enabled",
name="Insights Enabled",
name="Insights enabled",
icon="mdi:magnify",
entity_category=EntityCategory.CONFIG,
ufp_value="is_insights_enabled",
@ -467,7 +467,7 @@ _MODEL_DESCRIPTIONS: dict[ModelType, Sequence[ProtectEntityDescription]] = {
ModelType.VIEWPORT: VIEWER_SWITCHES,
}
_PRIVACY_MODEL_DESCRIPTIONS: dict[ModelType, Sequence[ProtectEntityDescription]] = {
_PRIVACY_DESCRIPTIONS: dict[ModelType, Sequence[ProtectEntityDescription]] = {
ModelType.CAMERA: [PRIVACY_MODE_SWITCH]
}
@ -478,16 +478,6 @@ class ProtectSwitch(ProtectDeviceEntity, SwitchEntity):
entity_description: ProtectSwitchEntityDescription
_state_attrs = ("_attr_available", "_attr_is_on")
def __init__(
self,
data: ProtectData,
device: ProtectAdoptableDeviceModel,
description: ProtectSwitchEntityDescription,
) -> None:
"""Initialize an UniFi Protect Switch."""
super().__init__(data, device, description)
self._attr_name = f"{self.device.display_name} {self.entity_description.name}"
def _async_update_device_from_protect(self, device: ProtectModelWithId) -> None:
super()._async_update_device_from_protect(device)
self._attr_is_on = self.entity_description.get_ufp_value(self.device) is True
@ -507,16 +497,6 @@ class ProtectNVRSwitch(ProtectNVREntity, SwitchEntity):
entity_description: ProtectSwitchEntityDescription
_state_attrs = ("_attr_available", "_attr_is_on")
def __init__(
self,
data: ProtectData,
device: NVR,
description: ProtectSwitchEntityDescription,
) -> None:
"""Initialize an UniFi Protect Switch."""
super().__init__(data, device, description)
self._attr_name = f"{self.device.display_name} {self.entity_description.name}"
def _async_update_device_from_protect(self, device: ProtectModelWithId) -> None:
super()._async_update_device_from_protect(device)
self._attr_is_on = self.entity_description.get_ufp_value(self.device) is True
@ -598,12 +578,6 @@ class ProtectPrivacyModeSwitch(RestoreEntity, ProtectSwitch):
self._update_previous_attr()
MODEL_DESCRIPTIONS_WITH_CLASS = (
(_MODEL_DESCRIPTIONS, ProtectSwitch),
(_PRIVACY_MODEL_DESCRIPTIONS, ProtectPrivacyModeSwitch),
)
async def async_setup_entry(
hass: HomeAssistant,
entry: UFPConfigEntry,
@ -614,20 +588,17 @@ async def async_setup_entry(
@callback
def _add_new_device(device: ProtectAdoptableDeviceModel) -> None:
_make_entities = partial(async_all_device_entities, data, ufp_device=device)
entities: list[BaseProtectEntity] = []
for model_descriptions, klass in MODEL_DESCRIPTIONS_WITH_CLASS:
entities += async_all_device_entities(
data, klass, model_descriptions=model_descriptions, ufp_device=device
)
entities += _make_entities(ProtectSwitch, _MODEL_DESCRIPTIONS)
entities += _make_entities(ProtectPrivacyModeSwitch, _PRIVACY_DESCRIPTIONS)
async_add_entities(entities)
_make_entities = partial(async_all_device_entities, data)
data.async_subscribe_adopt(_add_new_device)
entities: list[BaseProtectEntity] = []
for model_descriptions, klass in MODEL_DESCRIPTIONS_WITH_CLASS:
entities += async_all_device_entities(
data, klass, model_descriptions=model_descriptions
)
entities += _make_entities(ProtectSwitch, _MODEL_DESCRIPTIONS)
entities += _make_entities(ProtectPrivacyModeSwitch, _PRIVACY_DESCRIPTIONS)
bootstrap = data.api.bootstrap
nvr = bootstrap.nvr
if nvr.can_write(bootstrap.auth_user) and nvr.is_insights_enabled is not None:

View file

@ -157,6 +157,6 @@ def get_camera_base_name(channel: CameraChannel) -> str:
camera_name = channel.name
if channel.name != "Package Camera":
camera_name = f"{channel.name} Resolution Channel"
camera_name = f"{channel.name} resolution channel"
return camera_name

View file

@ -35,20 +35,20 @@ CAMERA_SWITCHES_BASIC = [
for d in CAMERA_SWITCHES
if (
not d.name.startswith("Detections:")
and d.name != "SSH Enabled"
and d.name != "Color Night Vision"
and d.name != "Tracking: Person"
and d.name != "HDR Mode"
and d.name != "SSH enabled"
and d.name != "Color night vision"
and d.name != "Tracking: person"
and d.name != "HDR mode"
)
or d.name == "Detections: Motion"
or d.name == "Detections: Person"
or d.name == "Detections: Vehicle"
or d.name == "Detections: Animal"
or d.name == "Detections: motion"
or d.name == "Detections: person"
or d.name == "Detections: vehicle"
or d.name == "Detections: animal"
]
CAMERA_SWITCHES_NO_EXTRA = [
d
for d in CAMERA_SWITCHES_BASIC
if d.name not in ("High FPS", "Privacy Mode", "HDR Mode")
if d.name not in ("High FPS", "Privacy mode", "HDR mode")
]