From 09ae8b9f52cadb1fca68056ca368a61d1bc331a1 Mon Sep 17 00:00:00 2001 From: Joost Lekkerkerker Date: Mon, 22 Apr 2024 10:41:26 +0200 Subject: [PATCH] Introduce base location entity for totalconnect (#115938) * Introduce base location entity for totalconnect * Update homeassistant/components/totalconnect/entity.py Co-authored-by: TheJulianJES --------- Co-authored-by: TheJulianJES --- .../totalconnect/alarm_control_panel.py | 58 +++++++------------ .../components/totalconnect/binary_sensor.py | 9 ++- .../components/totalconnect/entity.py | 20 +++++++ 3 files changed, 45 insertions(+), 42 deletions(-) diff --git a/homeassistant/components/totalconnect/alarm_control_panel.py b/homeassistant/components/totalconnect/alarm_control_panel.py index fcafd47037d..9b2abedbf52 100644 --- a/homeassistant/components/totalconnect/alarm_control_panel.py +++ b/homeassistant/components/totalconnect/alarm_control_panel.py @@ -4,9 +4,12 @@ from __future__ import annotations from total_connect_client import ArmingHelper from total_connect_client.exceptions import BadResultCodeError, UsercodeInvalid +from total_connect_client.location import TotalConnectLocation -import homeassistant.components.alarm_control_panel as alarm -from homeassistant.components.alarm_control_panel import AlarmControlPanelEntityFeature +from homeassistant.components.alarm_control_panel import ( + AlarmControlPanelEntity, + AlarmControlPanelEntityFeature, +) from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( STATE_ALARM_ARMED_AWAY, @@ -21,12 +24,11 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import entity_platform -from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback from . import TotalConnectDataUpdateCoordinator from .const import DOMAIN -from .entity import TotalConnectEntity +from .entity import TotalConnectLocationEntity SERVICE_ALARM_ARM_AWAY_INSTANT = "arm_away_instant" SERVICE_ALARM_ARM_HOME_INSTANT = "arm_home_instant" @@ -40,14 +42,12 @@ async def async_setup_entry( coordinator: TotalConnectDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] - for location_id, location in coordinator.client.locations.items(): - location_name = location.location_name + for location in coordinator.client.locations.values(): alarms.extend( TotalConnectAlarm( - coordinator=coordinator, - name=location_name, - location_id=location_id, - partition_id=partition_id, + coordinator, + location, + partition_id, ) for partition_id in location.partitions ) @@ -70,8 +70,8 @@ async def async_setup_entry( ) -class TotalConnectAlarm(TotalConnectEntity, alarm.AlarmControlPanelEntity): - """Represent an TotalConnect status.""" +class TotalConnectAlarm(TotalConnectLocationEntity, AlarmControlPanelEntity): + """Represent a TotalConnect alarm panel.""" _attr_supported_features = ( AlarmControlPanelEntityFeature.ARM_HOME @@ -82,19 +82,13 @@ class TotalConnectAlarm(TotalConnectEntity, alarm.AlarmControlPanelEntity): def __init__( self, coordinator: TotalConnectDataUpdateCoordinator, - name, - location_id, - partition_id, + location: TotalConnectLocation, + partition_id: int, ) -> None: """Initialize the TotalConnect status.""" - super().__init__(coordinator) - self._location_id = location_id - self._location = coordinator.client.locations[location_id] + super().__init__(coordinator, location) self._partition_id = partition_id self._partition = self._location.partitions[partition_id] - self._device = self._location.devices[self._location.security_device_id] - self._state: str | None = None - self._attr_extra_state_attributes = {} """ Set unique_id to location_id for partition 1 to avoid breaking change @@ -102,27 +96,18 @@ class TotalConnectAlarm(TotalConnectEntity, alarm.AlarmControlPanelEntity): Add _# for partition 2 and beyond. """ if partition_id == 1: - self._attr_name = name - self._attr_unique_id = f"{location_id}" + self._attr_name = self.device.name + self._attr_unique_id = str(location.location_id) else: - self._attr_name = f"{name} partition {partition_id}" - self._attr_unique_id = f"{location_id}_{partition_id}" - - @property - def device_info(self) -> DeviceInfo: - """Return device info.""" - return DeviceInfo( - identifiers={(DOMAIN, self._device.serial_number)}, - name=self._device.name, - serial_number=self._device.serial_number, - ) + self._attr_name = f"{self.device.name} partition {partition_id}" + self._attr_unique_id = f"{location.location_id}_{partition_id}" @property def state(self) -> str | None: """Return the state of the device.""" attr = { "location_name": self.name, - "location_id": self._location_id, + "location_id": self._location.location_id, "partition": self._partition_id, "ac_loss": self._location.ac_loss, "low_battery": self._location.low_battery, @@ -156,10 +141,9 @@ class TotalConnectAlarm(TotalConnectEntity, alarm.AlarmControlPanelEntity): state = STATE_ALARM_TRIGGERED attr["triggered_source"] = "Carbon Monoxide" - self._state = state self._attr_extra_state_attributes = attr - return self._state + return state async def async_alarm_disarm(self, code: str | None = None) -> None: """Send disarm command.""" diff --git a/homeassistant/components/totalconnect/binary_sensor.py b/homeassistant/components/totalconnect/binary_sensor.py index 18340d5d6d3..9ff25e07d03 100644 --- a/homeassistant/components/totalconnect/binary_sensor.py +++ b/homeassistant/components/totalconnect/binary_sensor.py @@ -19,7 +19,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from . import TotalConnectDataUpdateCoordinator from .const import DOMAIN -from .entity import TotalConnectEntity, TotalConnectZoneEntity +from .entity import TotalConnectLocationEntity, TotalConnectZoneEntity LOW_BATTERY = "low_battery" TAMPER = "tamper" @@ -181,7 +181,7 @@ class TotalConnectZoneBinarySensor(TotalConnectZoneEntity, BinarySensorEntity): return super().device_class -class TotalConnectAlarmBinarySensor(TotalConnectEntity, BinarySensorEntity): +class TotalConnectAlarmBinarySensor(TotalConnectLocationEntity, BinarySensorEntity): """Represent a TotalConnect alarm device binary sensors.""" entity_description: TotalConnectAlarmBinarySensorEntityDescription @@ -193,10 +193,9 @@ class TotalConnectAlarmBinarySensor(TotalConnectEntity, BinarySensorEntity): location: TotalConnectLocation, ) -> None: """Initialize the TotalConnect alarm device binary sensor.""" - super().__init__(coordinator) + super().__init__(coordinator, location) self.entity_description = entity_description - self._location = location - self._attr_name = f"{location.location_name}{entity_description.name}" + self._attr_name = f"{self.device.name}{entity_description.name}" self._attr_unique_id = f"{location.location_id}_{entity_description.key}" self._attr_extra_state_attributes = { "location_id": location.location_id, diff --git a/homeassistant/components/totalconnect/entity.py b/homeassistant/components/totalconnect/entity.py index e7ab4b3575c..deef0c5aa2a 100644 --- a/homeassistant/components/totalconnect/entity.py +++ b/homeassistant/components/totalconnect/entity.py @@ -1,5 +1,6 @@ """Base class for TotalConnect entities.""" +from total_connect_client.location import TotalConnectLocation from total_connect_client.zone import TotalConnectZone from homeassistant.helpers.device_registry import DeviceInfo @@ -12,6 +13,25 @@ class TotalConnectEntity(CoordinatorEntity[TotalConnectDataUpdateCoordinator]): """Represent a TotalConnect entity.""" +class TotalConnectLocationEntity(TotalConnectEntity): + """Represent a TotalConnect location.""" + + def __init__( + self, + coordinator: TotalConnectDataUpdateCoordinator, + location: TotalConnectLocation, + ) -> None: + """Initialize the TotalConnect location.""" + super().__init__(coordinator) + self._location = location + self.device = location.devices[location.security_device_id] + self._attr_device_info = DeviceInfo( + identifiers={(DOMAIN, self.device.serial_number)}, + name=self.device.name, + serial_number=self.device.serial_number, + ) + + class TotalConnectZoneEntity(TotalConnectEntity): """Represent a TotalConnect zone."""