Add Airzone to strict typing (#71604)

This commit is contained in:
Álvaro Fernández Rojas 2022-05-09 19:56:59 +02:00 committed by GitHub
parent 75ce66e8bd
commit b9b83c05e9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 40 additions and 28 deletions

View file

@ -43,6 +43,7 @@ homeassistant.components.aftership.*
homeassistant.components.air_quality.* homeassistant.components.air_quality.*
homeassistant.components.airly.* homeassistant.components.airly.*
homeassistant.components.airvisual.* homeassistant.components.airvisual.*
homeassistant.components.airzone.*
homeassistant.components.aladdin_connect.* homeassistant.components.aladdin_connect.*
homeassistant.components.alarm_control_panel.* homeassistant.components.alarm_control_panel.*
homeassistant.components.amazon_polly.* homeassistant.components.amazon_polly.*

View file

@ -1,7 +1,6 @@
"""Support for the Airzone sensors.""" """Support for the Airzone sensors."""
from __future__ import annotations from __future__ import annotations
from collections.abc import Mapping
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any, Final from typing import Any, Final
@ -22,7 +21,7 @@ from homeassistant.components.binary_sensor import (
BinarySensorEntityDescription, BinarySensorEntityDescription,
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity import EntityCategory from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
@ -120,20 +119,15 @@ class AirzoneBinarySensor(AirzoneEntity, BinarySensorEntity):
entity_description: AirzoneBinarySensorEntityDescription entity_description: AirzoneBinarySensorEntityDescription
@property @callback
def extra_state_attributes(self) -> Mapping[str, Any] | None: def _async_update_attrs(self) -> None:
"""Return state attributes.""" """Update binary sensor attributes."""
if not self.entity_description.attributes: self._attr_is_on = self.get_airzone_value(self.entity_description.key)
return None if self.entity_description.attributes:
return { self._attr_extra_state_attributes = {
key: self.get_airzone_value(val) key: self.get_airzone_value(val)
for key, val in self.entity_description.attributes.items() for key, val in self.entity_description.attributes.items()
} }
@property
def is_on(self) -> bool | None:
"""Return true if the binary sensor is on."""
return self.get_airzone_value(self.entity_description.key)
class AirzoneSystemBinarySensor(AirzoneSystemEntity, AirzoneBinarySensor): class AirzoneSystemBinarySensor(AirzoneSystemEntity, AirzoneBinarySensor):
@ -152,6 +146,7 @@ class AirzoneSystemBinarySensor(AirzoneSystemEntity, AirzoneBinarySensor):
self._attr_name = f"System {system_id} {description.name}" self._attr_name = f"System {system_id} {description.name}"
self._attr_unique_id = f"{self._attr_unique_id}_{system_id}_{description.key}" self._attr_unique_id = f"{self._attr_unique_id}_{system_id}_{description.key}"
self.entity_description = description self.entity_description = description
self._async_update_attrs()
class AirzoneZoneBinarySensor(AirzoneZoneEntity, AirzoneBinarySensor): class AirzoneZoneBinarySensor(AirzoneZoneEntity, AirzoneBinarySensor):
@ -173,3 +168,4 @@ class AirzoneZoneBinarySensor(AirzoneZoneEntity, AirzoneBinarySensor):
f"{self._attr_unique_id}_{system_zone_id}_{description.key}" f"{self._attr_unique_id}_{system_zone_id}_{description.key}"
) )
self.entity_description = description self.entity_description = description
self._async_update_attrs()

View file

@ -162,7 +162,7 @@ class AirzoneClimate(AirzoneZoneEntity, ClimateEntity):
params[API_ON] = 1 params[API_ON] = 1
await self._async_update_hvac_params(params) await self._async_update_hvac_params(params)
async def async_set_temperature(self, **kwargs) -> None: async def async_set_temperature(self, **kwargs: dict[str, Any]) -> None:
"""Set new target temperature.""" """Set new target temperature."""
params = { params = {
API_SET_POINT: kwargs.get(ATTR_TEMPERATURE), API_SET_POINT: kwargs.get(ATTR_TEMPERATURE),

View file

@ -3,6 +3,7 @@ from __future__ import annotations
from datetime import timedelta from datetime import timedelta
import logging import logging
from typing import Any, cast
from aioairzone.exceptions import AirzoneError from aioairzone.exceptions import AirzoneError
from aioairzone.localapi import AirzoneLocalApi from aioairzone.localapi import AirzoneLocalApi
@ -18,7 +19,7 @@ SCAN_INTERVAL = timedelta(seconds=60)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
class AirzoneUpdateCoordinator(DataUpdateCoordinator): class AirzoneUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
"""Class to manage fetching data from the Airzone device.""" """Class to manage fetching data from the Airzone device."""
def __init__(self, hass: HomeAssistant, airzone: AirzoneLocalApi) -> None: def __init__(self, hass: HomeAssistant, airzone: AirzoneLocalApi) -> None:
@ -30,13 +31,14 @@ class AirzoneUpdateCoordinator(DataUpdateCoordinator):
_LOGGER, _LOGGER,
name=DOMAIN, name=DOMAIN,
update_interval=SCAN_INTERVAL, update_interval=SCAN_INTERVAL,
update_method=self._async_update,
) )
async def _async_update_data(self): async def _async_update(self) -> dict[str, Any]:
"""Update data via library.""" """Update data via library."""
async with async_timeout.timeout(AIOAIRZONE_DEVICE_TIMEOUT_SEC): async with async_timeout.timeout(AIOAIRZONE_DEVICE_TIMEOUT_SEC):
try: try:
await self.airzone.update() await self.airzone.update()
except AirzoneError as error: except AirzoneError as error:
raise UpdateFailed(error) from error raise UpdateFailed(error) from error
return self.airzone.data() return cast(dict[str, Any], self.airzone.data())

View file

@ -27,7 +27,7 @@ from .coordinator import AirzoneUpdateCoordinator
class AirzoneEntity(CoordinatorEntity[AirzoneUpdateCoordinator]): class AirzoneEntity(CoordinatorEntity[AirzoneUpdateCoordinator]):
"""Define an Airzone entity.""" """Define an Airzone entity."""
def get_airzone_value(self, key) -> Any: def get_airzone_value(self, key: str) -> Any:
"""Return Airzone entity value by key.""" """Return Airzone entity value by key."""
raise NotImplementedError() raise NotImplementedError()
@ -58,7 +58,7 @@ class AirzoneSystemEntity(AirzoneEntity):
entry.entry_id if entry.unique_id is None else entry.unique_id entry.entry_id if entry.unique_id is None else entry.unique_id
) )
def get_airzone_value(self, key) -> Any: def get_airzone_value(self, key: str) -> Any:
"""Return system value by key.""" """Return system value by key."""
value = None value = None
if system := self.coordinator.data[AZD_SYSTEMS].get(self.system_id): if system := self.coordinator.data[AZD_SYSTEMS].get(self.system_id):
@ -96,7 +96,7 @@ class AirzoneZoneEntity(AirzoneEntity):
entry.entry_id if entry.unique_id is None else entry.unique_id entry.entry_id if entry.unique_id is None else entry.unique_id
) )
def get_airzone_value(self, key) -> Any: def get_airzone_value(self, key: str) -> Any:
"""Return zone value by key.""" """Return zone value by key."""
value = None value = None
if zone := self.coordinator.data[AZD_ZONES].get(self.system_zone_id): if zone := self.coordinator.data[AZD_ZONES].get(self.system_zone_id):

View file

@ -13,7 +13,7 @@ from homeassistant.components.sensor import (
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import PERCENTAGE, TEMP_CELSIUS from homeassistant.const import PERCENTAGE, TEMP_CELSIUS
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN, TEMP_UNIT_LIB_TO_HASS from .const import DOMAIN, TEMP_UNIT_LIB_TO_HASS
@ -64,10 +64,10 @@ async def async_setup_entry(
class AirzoneSensor(AirzoneEntity, SensorEntity): class AirzoneSensor(AirzoneEntity, SensorEntity):
"""Define an Airzone sensor.""" """Define an Airzone sensor."""
@property @callback
def native_value(self): def _async_update_attrs(self) -> None:
"""Return the state.""" """Update sensor attributes."""
return self.get_airzone_value(self.entity_description.key) self._attr_native_value = self.get_airzone_value(self.entity_description.key)
class AirzoneZoneSensor(AirzoneZoneEntity, AirzoneSensor): class AirzoneZoneSensor(AirzoneZoneEntity, AirzoneSensor):
@ -94,3 +94,5 @@ class AirzoneZoneSensor(AirzoneZoneEntity, AirzoneSensor):
self._attr_native_unit_of_measurement = TEMP_UNIT_LIB_TO_HASS.get( self._attr_native_unit_of_measurement = TEMP_UNIT_LIB_TO_HASS.get(
self.get_airzone_value(AZD_TEMP_UNIT) self.get_airzone_value(AZD_TEMP_UNIT)
) )
self._async_update_attrs()

View file

@ -236,6 +236,17 @@ no_implicit_optional = true
warn_return_any = true warn_return_any = true
warn_unreachable = true warn_unreachable = true
[mypy-homeassistant.components.airzone.*]
check_untyped_defs = true
disallow_incomplete_defs = true
disallow_subclassing_any = true
disallow_untyped_calls = true
disallow_untyped_decorators = true
disallow_untyped_defs = true
no_implicit_optional = true
warn_return_any = true
warn_unreachable = true
[mypy-homeassistant.components.aladdin_connect.*] [mypy-homeassistant.components.aladdin_connect.*]
check_untyped_defs = true check_untyped_defs = true
disallow_incomplete_defs = true disallow_incomplete_defs = true