Split and refactor AirzoneEntity (#70421)

This commit is contained in:
Álvaro Fernández Rojas 2022-04-23 07:20:14 +02:00 committed by GitHub
parent 5ffaa70bb6
commit 6dc44863c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 67 additions and 47 deletions

View File

@ -30,6 +30,14 @@ PLATFORMS: list[Platform] = [Platform.BINARY_SENSOR, Platform.CLIMATE, Platform.
class AirzoneEntity(CoordinatorEntity[AirzoneUpdateCoordinator]): class AirzoneEntity(CoordinatorEntity[AirzoneUpdateCoordinator]):
"""Define an Airzone entity.""" """Define an Airzone entity."""
def get_airzone_value(self, key) -> Any:
"""Return Airzone entity value by key."""
raise NotImplementedError()
class AirzoneZoneEntity(AirzoneEntity):
"""Define an Airzone Zone entity."""
def __init__( def __init__(
self, self,
coordinator: AirzoneUpdateCoordinator, coordinator: AirzoneUpdateCoordinator,
@ -47,12 +55,12 @@ class AirzoneEntity(CoordinatorEntity[AirzoneUpdateCoordinator]):
self._attr_device_info: DeviceInfo = { self._attr_device_info: DeviceInfo = {
"identifiers": {(DOMAIN, f"{entry.entry_id}_{system_zone_id}")}, "identifiers": {(DOMAIN, f"{entry.entry_id}_{system_zone_id}")},
"manufacturer": MANUFACTURER, "manufacturer": MANUFACTURER,
"model": self.get_zone_value(AZD_THERMOSTAT_MODEL), "model": self.get_airzone_value(AZD_THERMOSTAT_MODEL),
"name": f"Airzone [{system_zone_id}] {zone_data[AZD_NAME]}", "name": f"Airzone [{system_zone_id}] {zone_data[AZD_NAME]}",
"sw_version": self.get_zone_value(AZD_THERMOSTAT_FW), "sw_version": self.get_airzone_value(AZD_THERMOSTAT_FW),
} }
def get_zone_value(self, key): def get_airzone_value(self, key) -> Any:
"""Return zone value by key.""" """Return zone value by key."""
value = None value = None
if self.system_zone_id in self.coordinator.data[AZD_ZONES]: if self.system_zone_id in self.coordinator.data[AZD_ZONES]:

View File

@ -24,7 +24,7 @@ from homeassistant.core import HomeAssistant
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
from . import AirzoneEntity from . import AirzoneEntity, AirzoneZoneEntity
from .const import DOMAIN from .const import DOMAIN
from .coordinator import AirzoneUpdateCoordinator from .coordinator import AirzoneUpdateCoordinator
@ -36,7 +36,7 @@ class AirzoneBinarySensorEntityDescription(BinarySensorEntityDescription):
attributes: dict[str, str] | None = None attributes: dict[str, str] | None = None
BINARY_SENSOR_TYPES: Final[tuple[AirzoneBinarySensorEntityDescription, ...]] = ( ZONE_BINARY_SENSOR_TYPES: Final[tuple[AirzoneBinarySensorEntityDescription, ...]] = (
AirzoneBinarySensorEntityDescription( AirzoneBinarySensorEntityDescription(
device_class=BinarySensorDeviceClass.RUNNING, device_class=BinarySensorDeviceClass.RUNNING,
key=AZD_AIR_DEMAND, key=AZD_AIR_DEMAND,
@ -65,12 +65,12 @@ async def async_setup_entry(
"""Add Airzone binary sensors from a config_entry.""" """Add Airzone binary sensors from a config_entry."""
coordinator = hass.data[DOMAIN][entry.entry_id] coordinator = hass.data[DOMAIN][entry.entry_id]
binary_sensors = [] binary_sensors: list[AirzoneBinarySensor] = []
for system_zone_id, zone_data in coordinator.data[AZD_ZONES].items(): for system_zone_id, zone_data in coordinator.data[AZD_ZONES].items():
for description in BINARY_SENSOR_TYPES: for description in ZONE_BINARY_SENSOR_TYPES:
if description.key in zone_data: if description.key in zone_data:
binary_sensors.append( binary_sensors.append(
AirzoneBinarySensor( AirzoneZoneBinarySensor(
coordinator, coordinator,
description, description,
entry, entry,
@ -83,7 +83,28 @@ async def async_setup_entry(
class AirzoneBinarySensor(AirzoneEntity, BinarySensorEntity): class AirzoneBinarySensor(AirzoneEntity, BinarySensorEntity):
"""Define an Airzone sensor.""" """Define an Airzone binary sensor."""
entity_description: AirzoneBinarySensorEntityDescription
@property
def extra_state_attributes(self) -> Mapping[str, Any] | None:
"""Return state attributes."""
if not self.entity_description.attributes:
return None
return {
key: self.get_airzone_value(val)
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 AirzoneZoneBinarySensor(AirzoneZoneEntity, AirzoneBinarySensor):
"""Define an Airzone Zone binary sensor."""
def __init__( def __init__(
self, self,
@ -97,17 +118,4 @@ class AirzoneBinarySensor(AirzoneEntity, BinarySensorEntity):
super().__init__(coordinator, entry, system_zone_id, zone_data) super().__init__(coordinator, entry, system_zone_id, zone_data)
self._attr_name = f"{zone_data[AZD_NAME]} {description.name}" self._attr_name = f"{zone_data[AZD_NAME]} {description.name}"
self._attr_unique_id = f"{entry.entry_id}_{system_zone_id}_{description.key}" self._attr_unique_id = f"{entry.entry_id}_{system_zone_id}_{description.key}"
self.attributes = description.attributes
self.entity_description = description 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

@ -49,7 +49,7 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirzoneEntity from . import AirzoneZoneEntity
from .const import API_TEMPERATURE_STEP, DOMAIN, TEMP_UNIT_LIB_TO_HASS from .const import API_TEMPERATURE_STEP, DOMAIN, TEMP_UNIT_LIB_TO_HASS
from .coordinator import AirzoneUpdateCoordinator from .coordinator import AirzoneUpdateCoordinator
@ -97,7 +97,7 @@ async def async_setup_entry(
) )
class AirzoneClimate(AirzoneEntity, ClimateEntity): class AirzoneClimate(AirzoneZoneEntity, ClimateEntity):
"""Define an Airzone sensor.""" """Define an Airzone sensor."""
def __init__( def __init__(
@ -113,13 +113,13 @@ class AirzoneClimate(AirzoneEntity, ClimateEntity):
self._attr_unique_id = f"{entry.entry_id}_{system_zone_id}" self._attr_unique_id = f"{entry.entry_id}_{system_zone_id}"
self._attr_supported_features = ClimateEntityFeature.TARGET_TEMPERATURE self._attr_supported_features = ClimateEntityFeature.TARGET_TEMPERATURE
self._attr_target_temperature_step = API_TEMPERATURE_STEP self._attr_target_temperature_step = API_TEMPERATURE_STEP
self._attr_max_temp = self.get_zone_value(AZD_TEMP_MAX) self._attr_max_temp = self.get_airzone_value(AZD_TEMP_MAX)
self._attr_min_temp = self.get_zone_value(AZD_TEMP_MIN) self._attr_min_temp = self.get_airzone_value(AZD_TEMP_MIN)
self._attr_temperature_unit = TEMP_UNIT_LIB_TO_HASS[ self._attr_temperature_unit = TEMP_UNIT_LIB_TO_HASS[
self.get_zone_value(AZD_TEMP_UNIT) self.get_airzone_value(AZD_TEMP_UNIT)
] ]
self._attr_hvac_modes = [ self._attr_hvac_modes = [
HVAC_MODE_LIB_TO_HASS[mode] for mode in self.get_zone_value(AZD_MODES) HVAC_MODE_LIB_TO_HASS[mode] for mode in self.get_airzone_value(AZD_MODES)
] ]
self._async_update_attrs() self._async_update_attrs()
@ -161,8 +161,8 @@ class AirzoneClimate(AirzoneEntity, ClimateEntity):
params[API_ON] = 0 params[API_ON] = 0
else: else:
mode = HVAC_MODE_HASS_TO_LIB[hvac_mode] mode = HVAC_MODE_HASS_TO_LIB[hvac_mode]
if mode != self.get_zone_value(AZD_MODE): if mode != self.get_airzone_value(AZD_MODE):
if self.get_zone_value(AZD_MASTER): if self.get_airzone_value(AZD_MASTER):
params[API_MODE] = mode params[API_MODE] = mode
else: else:
raise HomeAssistantError( raise HomeAssistantError(
@ -187,16 +187,16 @@ class AirzoneClimate(AirzoneEntity, ClimateEntity):
@callback @callback
def _async_update_attrs(self) -> None: def _async_update_attrs(self) -> None:
"""Update climate attributes.""" """Update climate attributes."""
self._attr_current_temperature = self.get_zone_value(AZD_TEMP) self._attr_current_temperature = self.get_airzone_value(AZD_TEMP)
self._attr_current_humidity = self.get_zone_value(AZD_HUMIDITY) self._attr_current_humidity = self.get_airzone_value(AZD_HUMIDITY)
if self.get_zone_value(AZD_ON): if self.get_airzone_value(AZD_ON):
mode = self.get_zone_value(AZD_MODE) mode = self.get_airzone_value(AZD_MODE)
self._attr_hvac_mode = HVAC_MODE_LIB_TO_HASS[mode] self._attr_hvac_mode = HVAC_MODE_LIB_TO_HASS[mode]
if self.get_zone_value(AZD_DEMAND): if self.get_airzone_value(AZD_DEMAND):
self._attr_hvac_action = HVAC_ACTION_LIB_TO_HASS[mode] self._attr_hvac_action = HVAC_ACTION_LIB_TO_HASS[mode]
else: else:
self._attr_hvac_action = CURRENT_HVAC_IDLE self._attr_hvac_action = CURRENT_HVAC_IDLE
else: else:
self._attr_hvac_action = CURRENT_HVAC_OFF self._attr_hvac_action = CURRENT_HVAC_OFF
self._attr_hvac_mode = HVAC_MODE_OFF self._attr_hvac_mode = HVAC_MODE_OFF
self._attr_target_temperature = self.get_zone_value(AZD_TEMP_SET) self._attr_target_temperature = self.get_airzone_value(AZD_TEMP_SET)

View File

@ -16,11 +16,11 @@ from homeassistant.const import PERCENTAGE, TEMP_CELSIUS
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirzoneEntity from . import AirzoneEntity, AirzoneZoneEntity
from .const import DOMAIN, TEMP_UNIT_LIB_TO_HASS from .const import DOMAIN, TEMP_UNIT_LIB_TO_HASS
from .coordinator import AirzoneUpdateCoordinator from .coordinator import AirzoneUpdateCoordinator
SENSOR_TYPES: Final[tuple[SensorEntityDescription, ...]] = ( ZONE_SENSOR_TYPES: Final[tuple[SensorEntityDescription, ...]] = (
SensorEntityDescription( SensorEntityDescription(
device_class=SensorDeviceClass.TEMPERATURE, device_class=SensorDeviceClass.TEMPERATURE,
key=AZD_TEMP, key=AZD_TEMP,
@ -44,12 +44,12 @@ async def async_setup_entry(
"""Add Airzone sensors from a config_entry.""" """Add Airzone sensors from a config_entry."""
coordinator = hass.data[DOMAIN][entry.entry_id] coordinator = hass.data[DOMAIN][entry.entry_id]
sensors = [] sensors: list[AirzoneSensor] = []
for system_zone_id, zone_data in coordinator.data[AZD_ZONES].items(): for system_zone_id, zone_data in coordinator.data[AZD_ZONES].items():
for description in SENSOR_TYPES: for description in ZONE_SENSOR_TYPES:
if description.key in zone_data: if description.key in zone_data:
sensors.append( sensors.append(
AirzoneSensor( AirzoneZoneSensor(
coordinator, coordinator,
description, description,
entry, entry,
@ -64,6 +64,15 @@ async def async_setup_entry(
class AirzoneSensor(AirzoneEntity, SensorEntity): class AirzoneSensor(AirzoneEntity, SensorEntity):
"""Define an Airzone sensor.""" """Define an Airzone sensor."""
@property
def native_value(self):
"""Return the state."""
return self.get_airzone_value(self.entity_description.key)
class AirzoneZoneSensor(AirzoneZoneEntity, AirzoneSensor):
"""Define an Airzone Zone sensor."""
def __init__( def __init__(
self, self,
coordinator: AirzoneUpdateCoordinator, coordinator: AirzoneUpdateCoordinator,
@ -80,10 +89,5 @@ class AirzoneSensor(AirzoneEntity, SensorEntity):
if description.key == AZD_TEMP: if description.key == AZD_TEMP:
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_zone_value(AZD_TEMP_UNIT) self.get_airzone_value(AZD_TEMP_UNIT)
) )
@property
def native_value(self):
"""Return the state."""
return self.get_zone_value(self.entity_description.key)