diff --git a/homeassistant/components/airzone_cloud/__init__.py b/homeassistant/components/airzone_cloud/__init__.py index cdc0f30a533..732f159c381 100644 --- a/homeassistant/components/airzone_cloud/__init__.py +++ b/homeassistant/components/airzone_cloud/__init__.py @@ -12,7 +12,10 @@ from homeassistant.helpers import aiohttp_client 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 00000000000..1bd42118835 --- /dev/null +++ b/homeassistant/components/airzone_cloud/binary_sensor.py @@ -0,0 +1,108 @@ +"""Support for the Airzone Cloud binary sensors.""" +from __future__ import annotations + +from dataclasses import dataclass +from typing import Any, Final + +from aioairzone_cloud.const import 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, + ), +) + + +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_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.""" + + _attr_has_entity_name = True + + 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_unique_id = f"{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 00000000000..b2c9ee173b7 --- /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