diff --git a/homeassistant/components/advantage_air/__init__.py b/homeassistant/components/advantage_air/__init__.py index 3e07a8fbcef..8620a228edf 100644 --- a/homeassistant/components/advantage_air/__init__.py +++ b/homeassistant/components/advantage_air/__init__.py @@ -7,6 +7,7 @@ from advantage_air import ApiError, advantage_air from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_IP_ADDRESS, CONF_PORT, Platform from homeassistant.core import HomeAssistant +from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -60,7 +61,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: if await func(param): await coordinator.async_refresh() except ApiError as err: - _LOGGER.warning(err) + raise HomeAssistantError(err) from err return error_handle @@ -69,8 +70,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: hass.data.setdefault(DOMAIN, {}) hass.data[DOMAIN][entry.entry_id] = { "coordinator": coordinator, - "async_change": error_handle_factory(api.aircon.async_set), - "async_set_light": error_handle_factory(api.lights.async_set), + "aircon": error_handle_factory(api.aircon.async_set), + "lights": error_handle_factory(api.lights.async_set), } await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) diff --git a/homeassistant/components/advantage_air/binary_sensor.py b/homeassistant/components/advantage_air/binary_sensor.py index c0934239fe7..f3e021855fa 100644 --- a/homeassistant/components/advantage_air/binary_sensor.py +++ b/homeassistant/components/advantage_air/binary_sensor.py @@ -1,6 +1,8 @@ """Binary Sensor platform for Advantage Air integration.""" from __future__ import annotations +from typing import Any + from homeassistant.components.binary_sensor import ( BinarySensorDeviceClass, BinarySensorEntity, @@ -26,15 +28,16 @@ async def async_setup_entry( instance = hass.data[ADVANTAGE_AIR_DOMAIN][config_entry.entry_id] entities: list[BinarySensorEntity] = [] - for ac_key, ac_device in instance["coordinator"].data["aircons"].items(): - entities.append(AdvantageAirFilter(instance, ac_key)) - for zone_key, zone in ac_device["zones"].items(): - # Only add motion sensor when motion is enabled - if zone["motionConfig"] >= 2: - entities.append(AdvantageAirZoneMotion(instance, ac_key, zone_key)) - # Only add MyZone if it is available - if zone["type"] != 0: - entities.append(AdvantageAirZoneMyZone(instance, ac_key, zone_key)) + if aircons := instance["coordinator"].data.get("aircons"): + for ac_key, ac_device in aircons.items(): + entities.append(AdvantageAirFilter(instance, ac_key)) + for zone_key, zone in ac_device["zones"].items(): + # Only add motion sensor when motion is enabled + if zone["motionConfig"] >= 2: + entities.append(AdvantageAirZoneMotion(instance, ac_key, zone_key)) + # Only add MyZone if it is available + if zone["type"] != 0: + entities.append(AdvantageAirZoneMyZone(instance, ac_key, zone_key)) async_add_entities(entities) @@ -45,13 +48,13 @@ class AdvantageAirFilter(AdvantageAirAcEntity, BinarySensorEntity): _attr_entity_category = EntityCategory.DIAGNOSTIC _attr_name = "Filter" - def __init__(self, instance, ac_key): + def __init__(self, instance: dict[str, Any], ac_key: str) -> None: """Initialize an Advantage Air Filter sensor.""" super().__init__(instance, ac_key) self._attr_unique_id += "-filter" @property - def is_on(self): + def is_on(self) -> bool: """Return if filter needs cleaning.""" return self._ac["filterCleanStatus"] @@ -61,14 +64,14 @@ class AdvantageAirZoneMotion(AdvantageAirZoneEntity, BinarySensorEntity): _attr_device_class = BinarySensorDeviceClass.MOTION - def __init__(self, instance, ac_key, zone_key): + def __init__(self, instance: dict[str, Any], ac_key: str, zone_key: str) -> None: """Initialize an Advantage Air Zone Motion sensor.""" super().__init__(instance, ac_key, zone_key) self._attr_name = f'{self._zone["name"]} motion' self._attr_unique_id += "-motion" @property - def is_on(self): + def is_on(self) -> bool: """Return if motion is detect.""" return self._zone["motion"] == 20 @@ -79,13 +82,13 @@ class AdvantageAirZoneMyZone(AdvantageAirZoneEntity, BinarySensorEntity): _attr_entity_registry_enabled_default = False _attr_entity_category = EntityCategory.DIAGNOSTIC - def __init__(self, instance, ac_key, zone_key): + def __init__(self, instance: dict[str, Any], ac_key: str, zone_key: str) -> None: """Initialize an Advantage Air Zone MyZone sensor.""" super().__init__(instance, ac_key, zone_key) self._attr_name = f'{self._zone["name"]} myZone' self._attr_unique_id += "-myzone" @property - def is_on(self): + def is_on(self) -> bool: """Return if this zone is the myZone.""" return self._zone["number"] == self._ac["myZone"] diff --git a/homeassistant/components/advantage_air/climate.py b/homeassistant/components/advantage_air/climate.py index 1925b519a38..fdba46cde76 100644 --- a/homeassistant/components/advantage_air/climate.py +++ b/homeassistant/components/advantage_air/climate.py @@ -70,12 +70,13 @@ async def async_setup_entry( instance = hass.data[ADVANTAGE_AIR_DOMAIN][config_entry.entry_id] entities: list[ClimateEntity] = [] - for ac_key, ac_device in instance["coordinator"].data["aircons"].items(): - entities.append(AdvantageAirAC(instance, ac_key)) - for zone_key, zone in ac_device["zones"].items(): - # Only add zone climate control when zone is in temperature control - if zone["type"] != 0: - entities.append(AdvantageAirZone(instance, ac_key, zone_key)) + if aircons := instance["coordinator"].data.get("aircons"): + for ac_key, ac_device in aircons.items(): + entities.append(AdvantageAirAC(instance, ac_key)) + for zone_key, zone in ac_device["zones"].items(): + # Only add zone climate control when zone is in temperature control + if zone["type"] != 0: + entities.append(AdvantageAirZone(instance, ac_key, zone_key)) async_add_entities(entities) @@ -92,37 +93,37 @@ class AdvantageAirAC(AdvantageAirAcEntity, ClimateEntity): ClimateEntityFeature.TARGET_TEMPERATURE | ClimateEntityFeature.FAN_MODE ) - def __init__(self, instance, ac_key): + def __init__(self, instance: dict[str, Any], ac_key: str) -> None: """Initialize an AdvantageAir AC unit.""" super().__init__(instance, ac_key) if self._ac.get("myAutoModeEnabled"): self._attr_hvac_modes = AC_HVAC_MODES + [HVACMode.AUTO] @property - def target_temperature(self): + def target_temperature(self) -> float: """Return the current target temperature.""" return self._ac["setTemp"] @property - def hvac_mode(self): + def hvac_mode(self) -> HVACMode | None: """Return the current HVAC modes.""" if self._ac["state"] == ADVANTAGE_AIR_STATE_ON: return ADVANTAGE_AIR_HVAC_MODES.get(self._ac["mode"]) return HVACMode.OFF @property - def fan_mode(self): + def fan_mode(self) -> str | None: """Return the current fan modes.""" return ADVANTAGE_AIR_FAN_MODES.get(self._ac["fan"]) async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None: """Set the HVAC Mode and State.""" if hvac_mode == HVACMode.OFF: - await self.async_change( + await self.aircon( {self.ac_key: {"info": {"state": ADVANTAGE_AIR_STATE_OFF}}} ) else: - await self.async_change( + await self.aircon( { self.ac_key: { "info": { @@ -135,14 +136,14 @@ class AdvantageAirAC(AdvantageAirAcEntity, ClimateEntity): async def async_set_fan_mode(self, fan_mode: str) -> None: """Set the Fan Mode.""" - await self.async_change( + await self.aircon( {self.ac_key: {"info": {"fan": HASS_FAN_MODES.get(fan_mode)}}} ) async def async_set_temperature(self, **kwargs: Any) -> None: """Set the Temperature.""" temp = kwargs.get(ATTR_TEMPERATURE) - await self.async_change({self.ac_key: {"info": {"setTemp": temp}}}) + await self.aircon({self.ac_key: {"info": {"setTemp": temp}}}) class AdvantageAirZone(AdvantageAirZoneEntity, ClimateEntity): @@ -155,7 +156,7 @@ class AdvantageAirZone(AdvantageAirZoneEntity, ClimateEntity): _attr_hvac_modes = ZONE_HVAC_MODES _attr_supported_features = ClimateEntityFeature.TARGET_TEMPERATURE - def __init__(self, instance, ac_key, zone_key): + def __init__(self, instance: dict[str, Any], ac_key: str, zone_key: str) -> None: """Initialize an AdvantageAir Zone control.""" super().__init__(instance, ac_key, zone_key) self._attr_name = self._zone["name"] @@ -164,26 +165,26 @@ class AdvantageAirZone(AdvantageAirZoneEntity, ClimateEntity): ) @property - def hvac_mode(self): + def hvac_mode(self) -> HVACMode: """Return the current state as HVAC mode.""" if self._zone["state"] == ADVANTAGE_AIR_STATE_OPEN: return HVACMode.HEAT_COOL return HVACMode.OFF @property - def current_temperature(self): + def current_temperature(self) -> float: """Return the current temperature.""" return self._zone["measuredTemp"] @property - def target_temperature(self): + def target_temperature(self) -> float: """Return the target temperature.""" return self._zone["setTemp"] async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None: """Set the HVAC Mode and State.""" if hvac_mode == HVACMode.OFF: - await self.async_change( + await self.aircon( { self.ac_key: { "zones": {self.zone_key: {"state": ADVANTAGE_AIR_STATE_CLOSE}} @@ -191,7 +192,7 @@ class AdvantageAirZone(AdvantageAirZoneEntity, ClimateEntity): } ) else: - await self.async_change( + await self.aircon( { self.ac_key: { "zones": {self.zone_key: {"state": ADVANTAGE_AIR_STATE_OPEN}} @@ -202,6 +203,4 @@ class AdvantageAirZone(AdvantageAirZoneEntity, ClimateEntity): async def async_set_temperature(self, **kwargs: Any) -> None: """Set the Temperature.""" temp = kwargs.get(ATTR_TEMPERATURE) - await self.async_change( - {self.ac_key: {"zones": {self.zone_key: {"setTemp": temp}}}} - ) + await self.aircon({self.ac_key: {"zones": {self.zone_key: {"setTemp": temp}}}}) diff --git a/homeassistant/components/advantage_air/config_flow.py b/homeassistant/components/advantage_air/config_flow.py index b13ab1e9b21..7b5acab55f0 100644 --- a/homeassistant/components/advantage_air/config_flow.py +++ b/homeassistant/components/advantage_air/config_flow.py @@ -1,9 +1,14 @@ """Config Flow for Advantage Air integration.""" +from __future__ import annotations + +from typing import Any + from advantage_air import ApiError, advantage_air import voluptuous as vol from homeassistant import config_entries from homeassistant.const import CONF_IP_ADDRESS, CONF_PORT +from homeassistant.data_entry_flow import FlowResult from homeassistant.helpers.aiohttp_client import async_get_clientsession from .const import ADVANTAGE_AIR_RETRY, DOMAIN @@ -25,7 +30,9 @@ class AdvantageAirConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): DOMAIN = DOMAIN - async def async_step_user(self, user_input=None): + async def async_step_user( + self, user_input: dict[str, Any] | None = None + ) -> FlowResult: """Get configuration from the user.""" errors = {} if user_input: diff --git a/homeassistant/components/advantage_air/cover.py b/homeassistant/components/advantage_air/cover.py index 4b3f371f52e..8d05f7e2e63 100644 --- a/homeassistant/components/advantage_air/cover.py +++ b/homeassistant/components/advantage_air/cover.py @@ -30,12 +30,13 @@ async def async_setup_entry( instance = hass.data[ADVANTAGE_AIR_DOMAIN][config_entry.entry_id] - entities = [] - for ac_key, ac_device in instance["coordinator"].data["aircons"].items(): - for zone_key, zone in ac_device["zones"].items(): - # Only add zone vent controls when zone in vent control mode. - if zone["type"] == 0: - entities.append(AdvantageAirZoneVent(instance, ac_key, zone_key)) + entities: list[CoverEntity] = [] + if aircons := instance["coordinator"].data.get("aircons"): + for ac_key, ac_device in aircons.items(): + for zone_key, zone in ac_device["zones"].items(): + # Only add zone vent controls when zone in vent control mode. + if zone["type"] == 0: + entities.append(AdvantageAirZoneVent(instance, ac_key, zone_key)) async_add_entities(entities) @@ -49,7 +50,7 @@ class AdvantageAirZoneVent(AdvantageAirZoneEntity, CoverEntity): | CoverEntityFeature.SET_POSITION ) - def __init__(self, instance, ac_key, zone_key): + def __init__(self, instance: dict[str, Any], ac_key: str, zone_key: str) -> None: """Initialize an Advantage Air Zone Vent.""" super().__init__(instance, ac_key, zone_key) self._attr_name = self._zone["name"] @@ -68,7 +69,7 @@ class AdvantageAirZoneVent(AdvantageAirZoneEntity, CoverEntity): async def async_open_cover(self, **kwargs: Any) -> None: """Fully open zone vent.""" - await self.async_change( + await self.aircon( { self.ac_key: { "zones": { @@ -80,7 +81,7 @@ class AdvantageAirZoneVent(AdvantageAirZoneEntity, CoverEntity): async def async_close_cover(self, **kwargs: Any) -> None: """Fully close zone vent.""" - await self.async_change( + await self.aircon( { self.ac_key: { "zones": {self.zone_key: {"state": ADVANTAGE_AIR_STATE_CLOSE}} @@ -92,7 +93,7 @@ class AdvantageAirZoneVent(AdvantageAirZoneEntity, CoverEntity): """Change vent position.""" position = round(kwargs[ATTR_POSITION] / 5) * 5 if position == 0: - await self.async_change( + await self.aircon( { self.ac_key: { "zones": {self.zone_key: {"state": ADVANTAGE_AIR_STATE_CLOSE}} @@ -100,7 +101,7 @@ class AdvantageAirZoneVent(AdvantageAirZoneEntity, CoverEntity): } ) else: - await self.async_change( + await self.aircon( { self.ac_key: { "zones": { diff --git a/homeassistant/components/advantage_air/entity.py b/homeassistant/components/advantage_air/entity.py index 375bfa255c4..aaaa4ff5813 100644 --- a/homeassistant/components/advantage_air/entity.py +++ b/homeassistant/components/advantage_air/entity.py @@ -1,5 +1,7 @@ """Advantage Air parent entity class.""" +from typing import Any + from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -11,20 +13,20 @@ class AdvantageAirEntity(CoordinatorEntity): _attr_has_entity_name = True - def __init__(self, instance): + def __init__(self, instance: dict[str, Any]) -> None: """Initialize common aspects of an Advantage Air entity.""" super().__init__(instance["coordinator"]) - self._attr_unique_id = self.coordinator.data["system"]["rid"] + self._attr_unique_id: str = self.coordinator.data["system"]["rid"] class AdvantageAirAcEntity(AdvantageAirEntity): """Parent class for Advantage Air AC Entities.""" - def __init__(self, instance, ac_key): + def __init__(self, instance: dict[str, Any], ac_key: str) -> None: """Initialize common aspects of an Advantage Air ac entity.""" super().__init__(instance) - self.async_change = instance["async_change"] - self.ac_key = ac_key + self.aircon = instance["aircon"] + self.ac_key: str = ac_key self._attr_unique_id += f"-{ac_key}" self._attr_device_info = DeviceInfo( @@ -36,19 +38,19 @@ class AdvantageAirAcEntity(AdvantageAirEntity): ) @property - def _ac(self): + def _ac(self) -> dict[str, Any]: return self.coordinator.data["aircons"][self.ac_key]["info"] class AdvantageAirZoneEntity(AdvantageAirAcEntity): """Parent class for Advantage Air Zone Entities.""" - def __init__(self, instance, ac_key, zone_key): + def __init__(self, instance: dict[str, Any], ac_key: str, zone_key: str) -> None: """Initialize common aspects of an Advantage Air zone entity.""" super().__init__(instance, ac_key) - self.zone_key = zone_key + self.zone_key: str = zone_key self._attr_unique_id += f"-{zone_key}" @property - def _zone(self): + def _zone(self) -> dict[str, Any]: return self.coordinator.data["aircons"][self.ac_key]["zones"][self.zone_key] diff --git a/homeassistant/components/advantage_air/light.py b/homeassistant/components/advantage_air/light.py index b1c8495edf8..f0ae669acde 100644 --- a/homeassistant/components/advantage_air/light.py +++ b/homeassistant/components/advantage_air/light.py @@ -24,9 +24,9 @@ async def async_setup_entry( instance = hass.data[ADVANTAGE_AIR_DOMAIN][config_entry.entry_id] - entities = [] - if "myLights" in instance["coordinator"].data: - for light in instance["coordinator"].data["myLights"]["lights"].values(): + entities: list[LightEntity] = [] + if my_lights := instance["coordinator"].data.get("myLights"): + for light in my_lights["lights"].values(): if light.get("relay"): entities.append(AdvantageAirLight(instance, light)) else: @@ -39,11 +39,11 @@ class AdvantageAirLight(AdvantageAirEntity, LightEntity): _attr_supported_color_modes = {ColorMode.ONOFF} - def __init__(self, instance, light): + def __init__(self, instance: dict[str, Any], light: dict[str, Any]) -> None: """Initialize an Advantage Air Light.""" super().__init__(instance) - self.async_set_light = instance["async_set_light"] - self._id = light["id"] + self.lights = instance["lights"] + self._id: str = light["id"] self._attr_unique_id += f"-{self._id}" self._attr_device_info = DeviceInfo( identifiers={(ADVANTAGE_AIR_DOMAIN, self._attr_unique_id)}, @@ -54,7 +54,7 @@ class AdvantageAirLight(AdvantageAirEntity, LightEntity): ) @property - def _light(self): + def _light(self) -> dict[str, Any]: """Return the light object.""" return self.coordinator.data["myLights"]["lights"][self._id] @@ -65,11 +65,11 @@ class AdvantageAirLight(AdvantageAirEntity, LightEntity): async def async_turn_on(self, **kwargs: Any) -> None: """Turn the light on.""" - await self.async_set_light({"id": self._id, "state": ADVANTAGE_AIR_STATE_ON}) + await self.lights({"id": self._id, "state": ADVANTAGE_AIR_STATE_ON}) async def async_turn_off(self, **kwargs: Any) -> None: """Turn the light off.""" - await self.async_set_light({"id": self._id, "state": ADVANTAGE_AIR_STATE_OFF}) + await self.lights({"id": self._id, "state": ADVANTAGE_AIR_STATE_OFF}) class AdvantageAirLightDimmable(AdvantageAirLight): @@ -84,7 +84,7 @@ class AdvantageAirLightDimmable(AdvantageAirLight): async def async_turn_on(self, **kwargs: Any) -> None: """Turn the light on and optionally set the brightness.""" - data = {"id": self._id, "state": ADVANTAGE_AIR_STATE_ON} + data: dict[str, Any] = {"id": self._id, "state": ADVANTAGE_AIR_STATE_ON} if ATTR_BRIGHTNESS in kwargs: data["value"] = round(kwargs[ATTR_BRIGHTNESS] * 100 / 255) - await self.async_set_light(data) + await self.lights(data) diff --git a/homeassistant/components/advantage_air/select.py b/homeassistant/components/advantage_air/select.py index f6c46cb7f87..742ce810011 100644 --- a/homeassistant/components/advantage_air/select.py +++ b/homeassistant/components/advantage_air/select.py @@ -1,4 +1,6 @@ """Select platform for Advantage Air integration.""" +from typing import Any + from homeassistant.components.select import SelectEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant @@ -19,9 +21,10 @@ async def async_setup_entry( instance = hass.data[ADVANTAGE_AIR_DOMAIN][config_entry.entry_id] - entities = [] - for ac_key in instance["coordinator"].data["aircons"]: - entities.append(AdvantageAirMyZone(instance, ac_key)) + entities: list[SelectEntity] = [] + if aircons := instance["coordinator"].data.get("aircons"): + for ac_key in aircons: + entities.append(AdvantageAirMyZone(instance, ac_key)) async_add_entities(entities) @@ -31,7 +34,7 @@ class AdvantageAirMyZone(AdvantageAirAcEntity, SelectEntity): _attr_icon = "mdi:home-thermometer" _attr_name = "MyZone" - def __init__(self, instance, ac_key): + def __init__(self, instance: dict[str, Any], ac_key: str) -> None: """Initialize an Advantage Air MyZone control.""" super().__init__(instance, ac_key) self._attr_unique_id += "-myzone" @@ -52,6 +55,6 @@ class AdvantageAirMyZone(AdvantageAirAcEntity, SelectEntity): async def async_select_option(self, option: str) -> None: """Set the MyZone.""" - await self.async_change( + await self.aircon( {self.ac_key: {"info": {"myZone": self._name_to_number[option]}}} ) diff --git a/homeassistant/components/advantage_air/sensor.py b/homeassistant/components/advantage_air/sensor.py index b110294b2fd..60e640d36e9 100644 --- a/homeassistant/components/advantage_air/sensor.py +++ b/homeassistant/components/advantage_air/sensor.py @@ -1,6 +1,9 @@ """Sensor platform for Advantage Air integration.""" from __future__ import annotations +from decimal import Decimal +from typing import Any + import voluptuous as vol from homeassistant.components.sensor import ( @@ -35,17 +38,18 @@ async def async_setup_entry( instance = hass.data[ADVANTAGE_AIR_DOMAIN][config_entry.entry_id] entities: list[SensorEntity] = [] - for ac_key, ac_device in instance["coordinator"].data["aircons"].items(): - entities.append(AdvantageAirTimeTo(instance, ac_key, "On")) - entities.append(AdvantageAirTimeTo(instance, ac_key, "Off")) - for zone_key, zone in ac_device["zones"].items(): - # Only show damper and temp sensors when zone is in temperature control - if zone["type"] != 0: - entities.append(AdvantageAirZoneVent(instance, ac_key, zone_key)) - entities.append(AdvantageAirZoneTemp(instance, ac_key, zone_key)) - # Only show wireless signal strength sensors when using wireless sensors - if zone["rssi"] > 0: - entities.append(AdvantageAirZoneSignal(instance, ac_key, zone_key)) + if aircons := instance["coordinator"].data.get("aircons"): + for ac_key, ac_device in aircons.items(): + entities.append(AdvantageAirTimeTo(instance, ac_key, "On")) + entities.append(AdvantageAirTimeTo(instance, ac_key, "Off")) + for zone_key, zone in ac_device["zones"].items(): + # Only show damper and temp sensors when zone is in temperature control + if zone["type"] != 0: + entities.append(AdvantageAirZoneVent(instance, ac_key, zone_key)) + entities.append(AdvantageAirZoneTemp(instance, ac_key, zone_key)) + # Only show wireless signal strength sensors when using wireless sensors + if zone["rssi"] > 0: + entities.append(AdvantageAirZoneSignal(instance, ac_key, zone_key)) async_add_entities(entities) platform = entity_platform.async_get_current_platform() @@ -62,7 +66,7 @@ class AdvantageAirTimeTo(AdvantageAirAcEntity, SensorEntity): _attr_native_unit_of_measurement = ADVANTAGE_AIR_SET_COUNTDOWN_UNIT _attr_entity_category = EntityCategory.DIAGNOSTIC - def __init__(self, instance, ac_key, action): + def __init__(self, instance: dict[str, Any], ac_key: str, action: str) -> None: """Initialize the Advantage Air timer control.""" super().__init__(instance, ac_key) self.action = action @@ -71,21 +75,21 @@ class AdvantageAirTimeTo(AdvantageAirAcEntity, SensorEntity): self._attr_unique_id += f"-timeto{action}" @property - def native_value(self): + def native_value(self) -> Decimal: """Return the current value.""" return self._ac[self._time_key] @property - def icon(self): + def icon(self) -> str: """Return a representative icon of the timer.""" if self._ac[self._time_key] > 0: return "mdi:timer-outline" return "mdi:timer-off-outline" - async def set_time_to(self, **kwargs): + async def set_time_to(self, **kwargs: Any) -> None: """Set the timer value.""" value = min(720, max(0, int(kwargs[ADVANTAGE_AIR_SET_COUNTDOWN_VALUE]))) - await self.async_change({self.ac_key: {"info": {self._time_key: value}}}) + await self.aircon({self.ac_key: {"info": {self._time_key: value}}}) class AdvantageAirZoneVent(AdvantageAirZoneEntity, SensorEntity): @@ -95,21 +99,21 @@ class AdvantageAirZoneVent(AdvantageAirZoneEntity, SensorEntity): _attr_state_class = SensorStateClass.MEASUREMENT _attr_entity_category = EntityCategory.DIAGNOSTIC - def __init__(self, instance, ac_key, zone_key): + def __init__(self, instance: dict[str, Any], ac_key: str, zone_key: str) -> None: """Initialize an Advantage Air Zone Vent Sensor.""" super().__init__(instance, ac_key, zone_key=zone_key) self._attr_name = f'{self._zone["name"]} vent' self._attr_unique_id += "-vent" @property - def native_value(self): + def native_value(self) -> Decimal: """Return the current value of the air vent.""" if self._zone["state"] == ADVANTAGE_AIR_STATE_OPEN: return self._zone["value"] - return 0 + return Decimal(0) @property - def icon(self): + def icon(self) -> str: """Return a representative icon.""" if self._zone["state"] == ADVANTAGE_AIR_STATE_OPEN: return "mdi:fan" @@ -123,19 +127,19 @@ class AdvantageAirZoneSignal(AdvantageAirZoneEntity, SensorEntity): _attr_state_class = SensorStateClass.MEASUREMENT _attr_entity_category = EntityCategory.DIAGNOSTIC - def __init__(self, instance, ac_key, zone_key): + def __init__(self, instance: dict[str, Any], ac_key: str, zone_key: str) -> None: """Initialize an Advantage Air Zone wireless signal sensor.""" super().__init__(instance, ac_key, zone_key) self._attr_name = f'{self._zone["name"]} signal' self._attr_unique_id += "-signal" @property - def native_value(self): + def native_value(self) -> Decimal: """Return the current value of the wireless signal.""" return self._zone["rssi"] @property - def icon(self): + def icon(self) -> str: """Return a representative icon.""" if self._zone["rssi"] >= 80: return "mdi:wifi-strength-4" @@ -157,13 +161,13 @@ class AdvantageAirZoneTemp(AdvantageAirZoneEntity, SensorEntity): _attr_entity_registry_enabled_default = False _attr_entity_category = EntityCategory.DIAGNOSTIC - def __init__(self, instance, ac_key, zone_key): + def __init__(self, instance: dict[str, Any], ac_key: str, zone_key: str) -> None: """Initialize an Advantage Air Zone Temp Sensor.""" super().__init__(instance, ac_key, zone_key) self._attr_name = f'{self._zone["name"]} temperature' self._attr_unique_id += "-temp" @property - def native_value(self): + def native_value(self) -> Decimal: """Return the current value of the measured temperature.""" return self._zone["measuredTemp"] diff --git a/homeassistant/components/advantage_air/switch.py b/homeassistant/components/advantage_air/switch.py index 52992ae9531..e3504ab7624 100644 --- a/homeassistant/components/advantage_air/switch.py +++ b/homeassistant/components/advantage_air/switch.py @@ -23,10 +23,11 @@ async def async_setup_entry( instance = hass.data[ADVANTAGE_AIR_DOMAIN][config_entry.entry_id] - entities = [] - for ac_key, ac_device in instance["coordinator"].data["aircons"].items(): - if ac_device["info"]["freshAirStatus"] != "none": - entities.append(AdvantageAirFreshAir(instance, ac_key)) + entities: list[SwitchEntity] = [] + if aircons := instance["coordinator"].data.get("aircons"): + for ac_key, ac_device in aircons.items(): + if ac_device["info"]["freshAirStatus"] != "none": + entities.append(AdvantageAirFreshAir(instance, ac_key)) async_add_entities(entities) @@ -36,24 +37,24 @@ class AdvantageAirFreshAir(AdvantageAirAcEntity, SwitchEntity): _attr_icon = "mdi:air-filter" _attr_name = "Fresh air" - def __init__(self, instance, ac_key): + def __init__(self, instance: dict[str, Any], ac_key: str) -> None: """Initialize an Advantage Air fresh air control.""" super().__init__(instance, ac_key) self._attr_unique_id += "-freshair" @property - def is_on(self): + def is_on(self) -> bool: """Return the fresh air status.""" return self._ac["freshAirStatus"] == ADVANTAGE_AIR_STATE_ON async def async_turn_on(self, **kwargs: Any) -> None: """Turn fresh air on.""" - await self.async_change( + await self.aircon( {self.ac_key: {"info": {"freshAirStatus": ADVANTAGE_AIR_STATE_ON}}} ) async def async_turn_off(self, **kwargs: Any) -> None: """Turn fresh air off.""" - await self.async_change( + await self.aircon( {self.ac_key: {"info": {"freshAirStatus": ADVANTAGE_AIR_STATE_OFF}}} ) diff --git a/homeassistant/components/advantage_air/update.py b/homeassistant/components/advantage_air/update.py index 9294ecab238..404fcad7447 100644 --- a/homeassistant/components/advantage_air/update.py +++ b/homeassistant/components/advantage_air/update.py @@ -1,4 +1,6 @@ """Advantage Air Update platform.""" +from typing import Any + from homeassistant.components.update import UpdateEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant @@ -26,7 +28,7 @@ class AdvantageAirApp(AdvantageAirEntity, UpdateEntity): _attr_name = "App" - def __init__(self, instance): + def __init__(self, instance: dict[str, Any]) -> None: """Initialize the Advantage Air App.""" super().__init__(instance) self._attr_device_info = DeviceInfo( @@ -40,12 +42,12 @@ class AdvantageAirApp(AdvantageAirEntity, UpdateEntity): ) @property - def installed_version(self): + def installed_version(self) -> str: """Return the current app version.""" return self.coordinator.data["system"]["myAppRev"] @property - def latest_version(self): + def latest_version(self) -> str: """Return if there is an update.""" if self.coordinator.data["system"]["needsUpdate"]: return "Needs Update" diff --git a/tests/components/advantage_air/test_climate.py b/tests/components/advantage_air/test_climate.py index f1b118ab3b3..39999ba4ed9 100644 --- a/tests/components/advantage_air/test_climate.py +++ b/tests/components/advantage_air/test_climate.py @@ -1,6 +1,8 @@ """Test the Advantage Air Climate Platform.""" from json import loads +import pytest + from homeassistant.components.advantage_air.climate import ( HASS_FAN_MODES, HASS_HVAC_MODES, @@ -20,9 +22,10 @@ from homeassistant.components.climate.const import ( HVACMode, ) from homeassistant.const import ATTR_ENTITY_ID, ATTR_TEMPERATURE +from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import entity_registry as er -from tests.components.advantage_air import ( +from . import ( TEST_SET_RESPONSE, TEST_SET_URL, TEST_SYSTEM_DATA, @@ -184,12 +187,13 @@ async def test_climate_async_failed_update(hass, aioclient_mock): assert len(aioclient_mock.mock_calls) == 1 - await hass.services.async_call( - CLIMATE_DOMAIN, - SERVICE_SET_TEMPERATURE, - {ATTR_ENTITY_ID: ["climate.ac_one"], ATTR_TEMPERATURE: 25}, - blocking=True, - ) + with pytest.raises(HomeAssistantError): + await hass.services.async_call( + CLIMATE_DOMAIN, + SERVICE_SET_TEMPERATURE, + {ATTR_ENTITY_ID: ["climate.ac_one"], ATTR_TEMPERATURE: 25}, + blocking=True, + ) assert len(aioclient_mock.mock_calls) == 2 assert aioclient_mock.mock_calls[-1][0] == "GET" assert aioclient_mock.mock_calls[-1][1].path == "/setAircon"