Add Airzone binary sensor platform (#68140)

Co-authored-by: J. Nick Koston <nick@koston.org>
pull/68663/head^2
Álvaro Fernández Rojas 2022-03-27 22:39:46 +02:00 committed by GitHub
parent cc75cebfc5
commit 42a5e2d4fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 171 additions and 1 deletions

View File

@ -17,7 +17,7 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN, MANUFACTURER
from .coordinator import AirzoneUpdateCoordinator
PLATFORMS: list[Platform] = [Platform.CLIMATE, Platform.SENSOR]
PLATFORMS: list[Platform] = [Platform.BINARY_SENSOR, Platform.CLIMATE, Platform.SENSOR]
class AirzoneEntity(CoordinatorEntity[AirzoneUpdateCoordinator]):

View File

@ -0,0 +1,114 @@
"""Support for the Airzone sensors."""
from __future__ import annotations
from collections.abc import Mapping
from dataclasses import dataclass
from typing import Any, Final
from aioairzone.const import (
AZD_AIR_DEMAND,
AZD_ERRORS,
AZD_FLOOR_DEMAND,
AZD_NAME,
AZD_PROBLEMS,
AZD_ZONES,
)
from homeassistant.components.binary_sensor import (
DEVICE_CLASS_PROBLEM,
DEVICE_CLASS_RUNNING,
BinarySensorEntity,
BinarySensorEntityDescription,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirzoneEntity
from .const import DOMAIN
from .coordinator import AirzoneUpdateCoordinator
@dataclass
class AirzoneBinarySensorEntityDescription(BinarySensorEntityDescription):
"""A class that describes airzone binary sensor entities."""
attributes: dict[str, str] | None = None
BINARY_SENSOR_TYPES: Final[tuple[AirzoneBinarySensorEntityDescription, ...]] = (
AirzoneBinarySensorEntityDescription(
device_class=DEVICE_CLASS_RUNNING,
key=AZD_AIR_DEMAND,
name="Air Demand",
),
AirzoneBinarySensorEntityDescription(
device_class=DEVICE_CLASS_RUNNING,
key=AZD_FLOOR_DEMAND,
name="Floor Demand",
),
AirzoneBinarySensorEntityDescription(
attributes={
"errors": AZD_ERRORS,
},
device_class=DEVICE_CLASS_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 binary sensors from a config_entry."""
coordinator = hass.data[DOMAIN][entry.entry_id]
binary_sensors = []
for system_zone_id, zone_data in coordinator.data[AZD_ZONES].items():
for description in BINARY_SENSOR_TYPES:
if description.key in zone_data:
binary_sensors.append(
AirzoneBinarySensor(
coordinator,
description,
entry,
system_zone_id,
zone_data,
)
)
async_add_entities(binary_sensors)
class AirzoneBinarySensor(AirzoneEntity, BinarySensorEntity):
"""Define an Airzone sensor."""
def __init__(
self,
coordinator: AirzoneUpdateCoordinator,
description: AirzoneBinarySensorEntityDescription,
entry: ConfigEntry,
system_zone_id: str,
zone_data: dict[str, Any],
) -> None:
"""Initialize."""
super().__init__(coordinator, entry, system_zone_id, zone_data)
self._attr_name = f"{zone_data[AZD_NAME]} {description.name}"
self._attr_unique_id = f"{entry.entry_id}_{system_zone_id}_{description.key}"
self.attributes = description.attributes
self.entity_description = description
@property
def extra_state_attributes(self) -> Mapping[str, Any] | None:
"""Return state attributes."""
if not self.attributes:
return None
return {key: self.get_zone_value(val) for key, val in self.attributes.items()}
@property
def is_on(self) -> bool | None:
"""Return true if the binary sensor is on."""
return self.get_zone_value(self.entity_description.key)

View File

@ -0,0 +1,56 @@
"""The sensor tests for the Airzone platform."""
from homeassistant.const import STATE_OFF, STATE_ON
from .util import async_init_integration
async def test_airzone_create_binary_sensors(hass):
"""Test creation of binary sensors."""
await async_init_integration(hass)
state = hass.states.get("binary_sensor.despacho_air_demand")
assert state.state == STATE_OFF
state = hass.states.get("binary_sensor.despacho_floor_demand")
assert state.state == STATE_OFF
state = hass.states.get("binary_sensor.despacho_problem")
assert state.state == STATE_OFF
state = hass.states.get("binary_sensor.dorm_1_air_demand")
assert state.state == STATE_OFF
state = hass.states.get("binary_sensor.dorm_1_floor_demand")
assert state.state == STATE_OFF
state = hass.states.get("binary_sensor.dorm_1_problem")
assert state.state == STATE_OFF
state = hass.states.get("binary_sensor.dorm_2_air_demand")
assert state.state == STATE_OFF
state = hass.states.get("binary_sensor.dorm_2_floor_demand")
assert state.state == STATE_OFF
state = hass.states.get("binary_sensor.dorm_2_problem")
assert state.state == STATE_OFF
state = hass.states.get("binary_sensor.dorm_ppal_air_demand")
assert state.state == STATE_ON
state = hass.states.get("binary_sensor.dorm_ppal_floor_demand")
assert state.state == STATE_OFF
state = hass.states.get("binary_sensor.dorm_ppal_problem")
assert state.state == STATE_OFF
state = hass.states.get("binary_sensor.salon_air_demand")
assert state.state == STATE_OFF
state = hass.states.get("binary_sensor.salon_floor_demand")
assert state.state == STATE_OFF
state = hass.states.get("binary_sensor.salon_problem")
assert state.state == STATE_OFF