From af915f1425802d01c10c7681ac71d7086c7f1a63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Tue, 22 Aug 2023 22:41:03 +0200 Subject: [PATCH] Add Airzone Cloud System binary sensors (#95121) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * airzone_cloud: add System binary sensors Signed-off-by: Álvaro Fernández Rojas * airzone-cloud: add error example Signed-off-by: Álvaro Fernández Rojas --------- Signed-off-by: Álvaro Fernández Rojas --- .../components/airzone_cloud/binary_sensor.py | 55 ++++++++++++++++++- .../components/airzone_cloud/entity.py | 30 ++++++++++ .../airzone_cloud/test_binary_sensor.py | 12 ++++ tests/components/airzone_cloud/util.py | 7 ++- 4 files changed, 102 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/airzone_cloud/binary_sensor.py b/homeassistant/components/airzone_cloud/binary_sensor.py index 765eec2d288..a364ad0d753 100644 --- a/homeassistant/components/airzone_cloud/binary_sensor.py +++ b/homeassistant/components/airzone_cloud/binary_sensor.py @@ -9,6 +9,7 @@ from aioairzone_cloud.const import ( AZD_AIDOOS, AZD_ERRORS, AZD_PROBLEMS, + AZD_SYSTEMS, AZD_WARNINGS, AZD_ZONES, ) @@ -25,7 +26,12 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import DOMAIN from .coordinator import AirzoneUpdateCoordinator -from .entity import AirzoneAidooEntity, AirzoneEntity, AirzoneZoneEntity +from .entity import ( + AirzoneAidooEntity, + AirzoneEntity, + AirzoneSystemEntity, + AirzoneZoneEntity, +) @dataclass @@ -51,6 +57,20 @@ AIDOO_BINARY_SENSOR_TYPES: Final[tuple[AirzoneBinarySensorEntityDescription, ... ), ) + +SYSTEM_BINARY_SENSOR_TYPES: Final[tuple[AirzoneBinarySensorEntityDescription, ...]] = ( + AirzoneBinarySensorEntityDescription( + attributes={ + "errors": AZD_ERRORS, + "warnings": AZD_WARNINGS, + }, + device_class=BinarySensorDeviceClass.PROBLEM, + entity_category=EntityCategory.DIAGNOSTIC, + key=AZD_PROBLEMS, + ), +) + + ZONE_BINARY_SENSOR_TYPES: Final[tuple[AirzoneBinarySensorEntityDescription, ...]] = ( AirzoneBinarySensorEntityDescription( device_class=BinarySensorDeviceClass.RUNNING, @@ -87,6 +107,18 @@ async def async_setup_entry( ) ) + for system_id, system_data in coordinator.data.get(AZD_SYSTEMS, {}).items(): + for description in SYSTEM_BINARY_SENSOR_TYPES: + if description.key in system_data: + binary_sensors.append( + AirzoneSystemBinarySensor( + coordinator, + description, + system_id, + system_data, + ) + ) + for zone_id, zone_data in coordinator.data.get(AZD_ZONES, {}).items(): for description in ZONE_BINARY_SENSOR_TYPES: if description.key in zone_data: @@ -145,6 +177,27 @@ class AirzoneAidooBinarySensor(AirzoneAidooEntity, AirzoneBinarySensor): self._async_update_attrs() +class AirzoneSystemBinarySensor(AirzoneSystemEntity, AirzoneBinarySensor): + """Define an Airzone Cloud System binary sensor.""" + + _attr_has_entity_name = True + + def __init__( + self, + coordinator: AirzoneUpdateCoordinator, + description: AirzoneBinarySensorEntityDescription, + system_id: str, + system_data: dict[str, Any], + ) -> None: + """Initialize.""" + super().__init__(coordinator, system_id, system_data) + + self._attr_unique_id = f"{system_id}_{description.key}" + self.entity_description = description + + self._async_update_attrs() + + class AirzoneZoneBinarySensor(AirzoneZoneEntity, AirzoneBinarySensor): """Define an Airzone Cloud Zone binary sensor.""" diff --git a/homeassistant/components/airzone_cloud/entity.py b/homeassistant/components/airzone_cloud/entity.py index 32c41b8f1cd..090e81e4170 100644 --- a/homeassistant/components/airzone_cloud/entity.py +++ b/homeassistant/components/airzone_cloud/entity.py @@ -10,6 +10,7 @@ from aioairzone_cloud.const import ( AZD_FIRMWARE, AZD_NAME, AZD_SYSTEM_ID, + AZD_SYSTEMS, AZD_WEBSERVER, AZD_WEBSERVERS, AZD_ZONES, @@ -65,6 +66,35 @@ class AirzoneAidooEntity(AirzoneEntity): return value +class AirzoneSystemEntity(AirzoneEntity): + """Define an Airzone Cloud System entity.""" + + def __init__( + self, + coordinator: AirzoneUpdateCoordinator, + system_id: str, + system_data: dict[str, Any], + ) -> None: + """Initialize.""" + super().__init__(coordinator) + + self.system_id = system_id + + self._attr_device_info = DeviceInfo( + identifiers={(DOMAIN, system_id)}, + manufacturer=MANUFACTURER, + name=system_data[AZD_NAME], + via_device=(DOMAIN, system_data[AZD_WEBSERVER]), + ) + + def get_airzone_value(self, key: str) -> Any: + """Return system value by key.""" + value = None + if system := self.coordinator.data[AZD_SYSTEMS].get(self.system_id): + value = system.get(key) + return value + + class AirzoneWebServerEntity(AirzoneEntity): """Define an Airzone Cloud WebServer entity.""" diff --git a/tests/components/airzone_cloud/test_binary_sensor.py b/tests/components/airzone_cloud/test_binary_sensor.py index 14f7a078156..a1b5d5319c0 100644 --- a/tests/components/airzone_cloud/test_binary_sensor.py +++ b/tests/components/airzone_cloud/test_binary_sensor.py @@ -1,5 +1,7 @@ """The binary sensor tests for the Airzone Cloud platform.""" +from aioairzone_cloud.const import API_OLD_ID + from homeassistant.const import STATE_OFF, STATE_ON from homeassistant.core import HomeAssistant @@ -20,6 +22,16 @@ async def test_airzone_create_binary_sensors(hass: HomeAssistant) -> None: state = hass.states.get("binary_sensor.bron_running") assert state.state == STATE_OFF + # Systems + state = hass.states.get("binary_sensor.system_1_problem") + assert state.state == STATE_ON + assert state.attributes.get("errors") == [ + { + API_OLD_ID: "error-id", + }, + ] + assert state.attributes.get("warnings") is None + # Zones state = hass.states.get("binary_sensor.dormitorio_problem") assert state.state == STATE_OFF diff --git a/tests/components/airzone_cloud/util.py b/tests/components/airzone_cloud/util.py index 21459be60e4..8fd7da06853 100644 --- a/tests/components/airzone_cloud/util.py +++ b/tests/components/airzone_cloud/util.py @@ -25,6 +25,7 @@ from aioairzone_cloud.const import ( API_LOCAL_TEMP, API_META, API_NAME, + API_OLD_ID, API_STAT_AP_MAC, API_STAT_CHANNEL, API_STAT_QUALITY, @@ -175,7 +176,11 @@ def mock_get_device_status(device: Device) -> dict[str, Any]: } if device.get_id() == "system1": return { - API_ERRORS: [], + API_ERRORS: [ + { + API_OLD_ID: "error-id", + }, + ], API_IS_CONNECTED: True, API_WS_CONNECTED: True, API_WARNINGS: [],