From a84adc79e26d75f3cffffba1dd21e8a601b08fae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Fri, 26 May 2023 10:01:34 +0200 Subject: [PATCH 1/9] airzone_cloud: add Binary Sensors support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- .../components/airzone_cloud/__init__.py | 5 +- .../components/airzone_cloud/binary_sensor.py | 115 ++++++++++++++++++ .../airzone_cloud/test_binary_sensor.py | 21 ++++ 3 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 homeassistant/components/airzone_cloud/binary_sensor.py create mode 100644 tests/components/airzone_cloud/test_binary_sensor.py diff --git a/homeassistant/components/airzone_cloud/__init__.py b/homeassistant/components/airzone_cloud/__init__.py index cdc0f30a533744..732f159c38178f 100644 --- a/homeassistant/components/airzone_cloud/__init__.py +++ b/homeassistant/components/airzone_cloud/__init__.py @@ -12,7 +12,10 @@ from .const import DOMAIN from .coordinator import AirzoneUpdateCoordinator -PLATFORMS: list[Platform] = [Platform.SENSOR] +PLATFORMS: list[Platform] = [ + Platform.BINARY_SENSOR, + Platform.SENSOR, +] async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: diff --git a/homeassistant/components/airzone_cloud/binary_sensor.py b/homeassistant/components/airzone_cloud/binary_sensor.py new file mode 100644 index 00000000000000..1d385701271fcb --- /dev/null +++ b/homeassistant/components/airzone_cloud/binary_sensor.py @@ -0,0 +1,115 @@ +"""Support for the Airzone sensors.""" +from __future__ import annotations + +from dataclasses import dataclass +from typing import Any, Final + +from aioairzone_cloud.const import ( + AZD_CONNECTED, + AZD_NAME, + AZD_PROBLEMS, + AZD_WARNINGS, + AZD_ZONES, +) + +from homeassistant.components.binary_sensor import ( + BinarySensorDeviceClass, + BinarySensorEntity, + BinarySensorEntityDescription, +) +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import EntityCategory +from homeassistant.core import HomeAssistant, callback +from homeassistant.helpers.entity_platform import AddEntitiesCallback + +from .const import DOMAIN +from .coordinator import AirzoneUpdateCoordinator +from .entity import AirzoneEntity, AirzoneZoneEntity + + +@dataclass +class AirzoneBinarySensorEntityDescription(BinarySensorEntityDescription): + """A class that describes Airzone Cloud binary sensor entities.""" + + attributes: dict[str, str] | None = None + + +ZONE_BINARY_SENSOR_TYPES: Final[tuple[AirzoneBinarySensorEntityDescription, ...]] = ( + AirzoneBinarySensorEntityDescription( + attributes={ + "warnings": AZD_WARNINGS, + }, + device_class=BinarySensorDeviceClass.PROBLEM, + entity_category=EntityCategory.DIAGNOSTIC, + key=AZD_PROBLEMS, + name="Problem", + ), +) + + +async def async_setup_entry( + hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback +) -> None: + """Add Airzone Cloud binary sensors from a config_entry.""" + coordinator: AirzoneUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] + + binary_sensors: list[AirzoneBinarySensor] = [] + + 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: + binary_sensors.append( + AirzoneZoneBinarySensor( + coordinator, + description, + entry, + zone_id, + zone_data, + ) + ) + + async_add_entities(binary_sensors) + + +class AirzoneBinarySensor(AirzoneEntity, BinarySensorEntity): + """Define an Airzone Cloud binary sensor.""" + + entity_description: AirzoneBinarySensorEntityDescription + + @callback + def _handle_coordinator_update(self) -> None: + """Update attributes when the coordinator updates.""" + self._async_update_attrs() + super()._handle_coordinator_update() + + @callback + def _async_update_attrs(self) -> None: + """Update binary sensor attributes.""" + self._attr_available = self.get_airzone_value(AZD_CONNECTED) + self._attr_is_on = self.get_airzone_value(self.entity_description.key) + if self.entity_description.attributes: + self._attr_extra_state_attributes = { + key: self.get_airzone_value(val) + for key, val in self.entity_description.attributes.items() + } + + +class AirzoneZoneBinarySensor(AirzoneZoneEntity, AirzoneBinarySensor): + """Define an Airzone Cloud Zone binary sensor.""" + + def __init__( + self, + coordinator: AirzoneUpdateCoordinator, + description: AirzoneBinarySensorEntityDescription, + entry: ConfigEntry, + zone_id: str, + zone_data: dict[str, Any], + ) -> None: + """Initialize.""" + super().__init__(coordinator, entry, zone_id, zone_data) + + self._attr_name = f"{zone_data[AZD_NAME]} {description.name}" + self._attr_unique_id = f"{self.unique_id}_{zone_id}_{description.key}" + self.entity_description = description + + self._async_update_attrs() diff --git a/tests/components/airzone_cloud/test_binary_sensor.py b/tests/components/airzone_cloud/test_binary_sensor.py new file mode 100644 index 00000000000000..b2c9ee173b77e5 --- /dev/null +++ b/tests/components/airzone_cloud/test_binary_sensor.py @@ -0,0 +1,21 @@ +"""The binary sensor tests for the Airzone Cloud platform.""" + +from homeassistant.const import STATE_OFF +from homeassistant.core import HomeAssistant + +from .util import async_init_integration + + +async def test_airzone_create_binary_sensors(hass: HomeAssistant) -> None: + """Test creation of binary sensors.""" + + await async_init_integration(hass) + + # Zones + state = hass.states.get("binary_sensor.dormitorio_problem") + assert state.state == STATE_OFF + assert state.attributes.get("warnings") is None + + state = hass.states.get("binary_sensor.salon_problem") + assert state.state == STATE_OFF + assert state.attributes.get("warnings") is None From a63e4b00fbe606530918f2fdf0081e324f0c7e75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Fri, 26 May 2023 10:06:40 +0200 Subject: [PATCH 2/9] airzone_cloud: binary_sensor: fix copy&paste MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- homeassistant/components/airzone_cloud/binary_sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/airzone_cloud/binary_sensor.py b/homeassistant/components/airzone_cloud/binary_sensor.py index 1d385701271fcb..d8881cafbccf42 100644 --- a/homeassistant/components/airzone_cloud/binary_sensor.py +++ b/homeassistant/components/airzone_cloud/binary_sensor.py @@ -1,4 +1,4 @@ -"""Support for the Airzone sensors.""" +"""Support for the Airzone Cloud binary sensors.""" from __future__ import annotations from dataclasses import dataclass From afb8f032701291e45ed83fa02e5a5603afd6c9ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Mon, 29 May 2023 11:11:47 +0200 Subject: [PATCH 3/9] airzone_cloud: remote available attribute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is not working as expected and will require minor library changes. Signed-off-by: Álvaro Fernández Rojas --- homeassistant/components/airzone_cloud/binary_sensor.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/homeassistant/components/airzone_cloud/binary_sensor.py b/homeassistant/components/airzone_cloud/binary_sensor.py index d8881cafbccf42..ee1df31c9bc95f 100644 --- a/homeassistant/components/airzone_cloud/binary_sensor.py +++ b/homeassistant/components/airzone_cloud/binary_sensor.py @@ -4,13 +4,7 @@ from dataclasses import dataclass from typing import Any, Final -from aioairzone_cloud.const import ( - AZD_CONNECTED, - AZD_NAME, - AZD_PROBLEMS, - AZD_WARNINGS, - AZD_ZONES, -) +from aioairzone_cloud.const import AZD_NAME, AZD_PROBLEMS, AZD_WARNINGS, AZD_ZONES from homeassistant.components.binary_sensor import ( BinarySensorDeviceClass, @@ -85,7 +79,6 @@ def _handle_coordinator_update(self) -> None: @callback def _async_update_attrs(self) -> None: """Update binary sensor attributes.""" - self._attr_available = self.get_airzone_value(AZD_CONNECTED) self._attr_is_on = self.get_airzone_value(self.entity_description.key) if self.entity_description.attributes: self._attr_extra_state_attributes = { From 3266777bc5f56147358f1329db7f0774733b5952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Tue, 30 May 2023 07:36:08 +0200 Subject: [PATCH 4/9] airzone_cloud: binary_sensor: remove unique_id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- homeassistant/components/airzone_cloud/binary_sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/airzone_cloud/binary_sensor.py b/homeassistant/components/airzone_cloud/binary_sensor.py index ee1df31c9bc95f..45bb33999d0da0 100644 --- a/homeassistant/components/airzone_cloud/binary_sensor.py +++ b/homeassistant/components/airzone_cloud/binary_sensor.py @@ -102,7 +102,7 @@ def __init__( super().__init__(coordinator, entry, zone_id, zone_data) self._attr_name = f"{zone_data[AZD_NAME]} {description.name}" - self._attr_unique_id = f"{self.unique_id}_{zone_id}_{description.key}" + self._attr_unique_id = f"{zone_id}_{description.key}" self.entity_description = description self._async_update_attrs() From 704e92223db009d58c44bd70b40b39d2712dcf3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Wed, 21 Jun 2023 08:47:38 +0200 Subject: [PATCH 5/9] airzone_cloud: binary_sensors: remove name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- homeassistant/components/airzone_cloud/binary_sensor.py | 1 - 1 file changed, 1 deletion(-) diff --git a/homeassistant/components/airzone_cloud/binary_sensor.py b/homeassistant/components/airzone_cloud/binary_sensor.py index 45bb33999d0da0..fc427483c41a25 100644 --- a/homeassistant/components/airzone_cloud/binary_sensor.py +++ b/homeassistant/components/airzone_cloud/binary_sensor.py @@ -36,7 +36,6 @@ class AirzoneBinarySensorEntityDescription(BinarySensorEntityDescription): device_class=BinarySensorDeviceClass.PROBLEM, entity_category=EntityCategory.DIAGNOSTIC, key=AZD_PROBLEMS, - name="Problem", ), ) From 7b6adc0e091dba657d175f72bc2a0c1af983dea4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Wed, 21 Jun 2023 17:16:10 +0200 Subject: [PATCH 6/9] airzone_cloud: use entity_name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- homeassistant/components/airzone_cloud/binary_sensor.py | 5 +++-- homeassistant/components/airzone_cloud/strings.json | 7 +++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/airzone_cloud/binary_sensor.py b/homeassistant/components/airzone_cloud/binary_sensor.py index fc427483c41a25..b7c5414a0fd3b1 100644 --- a/homeassistant/components/airzone_cloud/binary_sensor.py +++ b/homeassistant/components/airzone_cloud/binary_sensor.py @@ -4,7 +4,7 @@ from dataclasses import dataclass from typing import Any, Final -from aioairzone_cloud.const import AZD_NAME, AZD_PROBLEMS, AZD_WARNINGS, AZD_ZONES +from aioairzone_cloud.const import AZD_PROBLEMS, AZD_WARNINGS, AZD_ZONES from homeassistant.components.binary_sensor import ( BinarySensorDeviceClass, @@ -35,7 +35,9 @@ class AirzoneBinarySensorEntityDescription(BinarySensorEntityDescription): }, device_class=BinarySensorDeviceClass.PROBLEM, entity_category=EntityCategory.DIAGNOSTIC, + has_entity_name=True, key=AZD_PROBLEMS, + name="Problem", ), ) @@ -100,7 +102,6 @@ def __init__( """Initialize.""" super().__init__(coordinator, entry, zone_id, zone_data) - self._attr_name = f"{zone_data[AZD_NAME]} {description.name}" self._attr_unique_id = f"{zone_id}_{description.key}" self.entity_description = description diff --git a/homeassistant/components/airzone_cloud/strings.json b/homeassistant/components/airzone_cloud/strings.json index 12f155b4486835..af327f02d6995b 100644 --- a/homeassistant/components/airzone_cloud/strings.json +++ b/homeassistant/components/airzone_cloud/strings.json @@ -15,5 +15,12 @@ } } } + }, + "entity": { + "binary_sensor": { + "problem": { + "name": "[%key:component::binary_sensor::entity_component::problem::name%]" + } + } } } From db68d059c48f4944158b471f3037b15a105ef4ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Thu, 22 Jun 2023 23:16:49 +0200 Subject: [PATCH 7/9] airzone_cloud: binary_sensor: add name=None MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- homeassistant/components/airzone_cloud/binary_sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/airzone_cloud/binary_sensor.py b/homeassistant/components/airzone_cloud/binary_sensor.py index b7c5414a0fd3b1..b64c5688e75c95 100644 --- a/homeassistant/components/airzone_cloud/binary_sensor.py +++ b/homeassistant/components/airzone_cloud/binary_sensor.py @@ -37,7 +37,7 @@ class AirzoneBinarySensorEntityDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, has_entity_name=True, key=AZD_PROBLEMS, - name="Problem", + name=None, ), ) From 73ed255ffff436e8e3543c3c2cd1583a60d95cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Fri, 23 Jun 2023 13:03:12 +0200 Subject: [PATCH 8/9] airzone_cloud: binary_sensor: fix device class name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- homeassistant/components/airzone_cloud/binary_sensor.py | 3 +-- homeassistant/components/airzone_cloud/strings.json | 7 ------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/homeassistant/components/airzone_cloud/binary_sensor.py b/homeassistant/components/airzone_cloud/binary_sensor.py index b64c5688e75c95..14bad18e16711d 100644 --- a/homeassistant/components/airzone_cloud/binary_sensor.py +++ b/homeassistant/components/airzone_cloud/binary_sensor.py @@ -35,9 +35,7 @@ class AirzoneBinarySensorEntityDescription(BinarySensorEntityDescription): }, device_class=BinarySensorDeviceClass.PROBLEM, entity_category=EntityCategory.DIAGNOSTIC, - has_entity_name=True, key=AZD_PROBLEMS, - name=None, ), ) @@ -102,6 +100,7 @@ def __init__( """Initialize.""" super().__init__(coordinator, entry, zone_id, zone_data) + self._attr_has_entity_name = True self._attr_unique_id = f"{zone_id}_{description.key}" self.entity_description = description diff --git a/homeassistant/components/airzone_cloud/strings.json b/homeassistant/components/airzone_cloud/strings.json index af327f02d6995b..12f155b4486835 100644 --- a/homeassistant/components/airzone_cloud/strings.json +++ b/homeassistant/components/airzone_cloud/strings.json @@ -15,12 +15,5 @@ } } } - }, - "entity": { - "binary_sensor": { - "problem": { - "name": "[%key:component::binary_sensor::entity_component::problem::name%]" - } - } } } From 164dd699273692ea23353ea8ef5f46a76c519394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Fri, 23 Jun 2023 16:07:44 +0200 Subject: [PATCH 9/9] Update homeassistant/components/airzone_cloud/binary_sensor.py Co-authored-by: G Johansson --- homeassistant/components/airzone_cloud/binary_sensor.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/airzone_cloud/binary_sensor.py b/homeassistant/components/airzone_cloud/binary_sensor.py index 14bad18e16711d..1bd421188351ba 100644 --- a/homeassistant/components/airzone_cloud/binary_sensor.py +++ b/homeassistant/components/airzone_cloud/binary_sensor.py @@ -89,6 +89,8 @@ def _async_update_attrs(self) -> None: class AirzoneZoneBinarySensor(AirzoneZoneEntity, AirzoneBinarySensor): """Define an Airzone Cloud Zone binary sensor.""" + _attr_has_entity_name = True + def __init__( self, coordinator: AirzoneUpdateCoordinator, @@ -100,7 +102,6 @@ def __init__( """Initialize.""" super().__init__(coordinator, entry, zone_id, zone_data) - self._attr_has_entity_name = True self._attr_unique_id = f"{zone_id}_{description.key}" self.entity_description = description