From cec2a40602d6158362b4a4a79ec87f4ebabec481 Mon Sep 17 00:00:00 2001 From: Glenn Waters Date: Tue, 19 Apr 2022 16:52:46 -0400 Subject: [PATCH] ElkM1 integration adding types, part 3 (#70214) * ElkM1 integration adding types, part 3 * Fix default _state value. * Tweak fan get. * change get to dict access. --- .strict-typing | 1 + homeassistant/components/elkm1/__init__.py | 2 +- homeassistant/components/elkm1/climate.py | 62 ++++++++++++---------- mypy.ini | 11 ++++ 4 files changed, 47 insertions(+), 29 deletions(-) diff --git a/.strict-typing b/.strict-typing index f576ba7e1c4..81994fd02c3 100644 --- a/.strict-typing +++ b/.strict-typing @@ -91,6 +91,7 @@ homeassistant.components.dunehd.* homeassistant.components.efergy.* homeassistant.components.elgato.* homeassistant.components.elkm1.__init__ +homeassistant.components.elkm1.climate homeassistant.components.elkm1.discovery homeassistant.components.elkm1.light homeassistant.components.elkm1.scene diff --git a/homeassistant/components/elkm1/__init__.py b/homeassistant/components/elkm1/__init__.py index e18de070ab0..5d12690ffc0 100644 --- a/homeassistant/components/elkm1/__init__.py +++ b/homeassistant/components/elkm1/__init__.py @@ -446,7 +446,7 @@ class ElkEntity(Entity): self._mac = elk_data["mac"] self._prefix = elk_data["prefix"] self._name_prefix = f"{self._prefix} " if self._prefix else "" - self._temperature_unit = elk_data["config"]["temperature_unit"] + self._temperature_unit: str = elk_data["config"]["temperature_unit"] # unique_id starts with elkm1_ iff there is no prefix # it starts with elkm1m_{prefix} iff there is a prefix # this is to avoid a conflict between diff --git a/homeassistant/components/elkm1/climate.py b/homeassistant/components/elkm1/climate.py index 35504e8cc98..bf054cb1df5 100644 --- a/homeassistant/components/elkm1/climate.py +++ b/homeassistant/components/elkm1/climate.py @@ -1,7 +1,12 @@ """Support for control of Elk-M1 connected thermostats.""" from __future__ import annotations +from typing import Any + from elkm1_lib.const import ThermostatFan, ThermostatMode, ThermostatSetting +from elkm1_lib.elements import Element +from elkm1_lib.elk import Elk +from elkm1_lib.thermostats import Thermostat from homeassistant.components.climate import ClimateEntity, ClimateEntityFeature from homeassistant.components.climate.const import ( @@ -77,24 +82,25 @@ class ElkThermostat(ElkEntity, ClimateEntity): | ClimateEntityFeature.AUX_HEAT | ClimateEntityFeature.TARGET_TEMPERATURE_RANGE ) + _element: Thermostat - def __init__(self, element, elk, elk_data): + def __init__(self, element: Element, elk: Elk, elk_data: dict[str, Any]) -> None: """Initialize climate entity.""" super().__init__(element, elk, elk_data) - self._state = None + self._state: str = HVAC_MODE_OFF @property - def temperature_unit(self): + def temperature_unit(self) -> str: """Return the temperature unit.""" return self._temperature_unit @property - def current_temperature(self): + def current_temperature(self) -> float | None: """Return the current temperature.""" return self._element.current_temp @property - def target_temperature(self): + def target_temperature(self) -> float | None: """Return the temperature we are trying to reach.""" if self._element.mode in ( ThermostatMode.HEAT.value, @@ -106,90 +112,90 @@ class ElkThermostat(ElkEntity, ClimateEntity): return None @property - def target_temperature_high(self): + def target_temperature_high(self) -> float | None: """Return the high target temperature.""" return self._element.cool_setpoint @property - def target_temperature_low(self): + def target_temperature_low(self) -> float | None: """Return the low target temperature.""" return self._element.heat_setpoint @property - def target_temperature_step(self): + def target_temperature_step(self) -> float: """Return the supported step of target temperature.""" return 1 @property - def current_humidity(self): + def current_humidity(self) -> int | None: """Return the current humidity.""" return self._element.humidity @property - def hvac_mode(self): + def hvac_mode(self) -> str: """Return current operation ie. heat, cool, idle.""" return self._state @property - def hvac_modes(self): + def hvac_modes(self) -> list[str]: """Return the list of available operation modes.""" return SUPPORT_HVAC @property - def precision(self): + def precision(self) -> int: """Return the precision of the system.""" return PRECISION_WHOLE @property - def is_aux_heat(self): + def is_aux_heat(self) -> bool: """Return if aux heater is on.""" return self._element.mode == ThermostatMode.EMERGENCY_HEAT.value @property - def min_temp(self): + def min_temp(self) -> float: """Return the minimum temperature supported.""" return 1 @property - def max_temp(self): + def max_temp(self) -> float: """Return the maximum temperature supported.""" return 99 @property - def fan_mode(self): + def fan_mode(self) -> str: """Return the fan setting.""" - return ELK_TO_HASS_FAN_MODES.get(self._element.fan) + return ELK_TO_HASS_FAN_MODES[self._element.fan] - def _elk_set(self, mode, fan): + def _elk_set(self, mode: int | None, fan: int | None) -> None: if mode is not None: self._element.set(ThermostatSetting.MODE.value, mode) if fan is not None: self._element.set(ThermostatSetting.FAN.value, fan) - async def async_set_hvac_mode(self, hvac_mode): + async def async_set_hvac_mode(self, hvac_mode: str) -> None: """Set thermostat operation mode.""" thermostat_mode, fan_mode = HASS_TO_ELK_HVAC_MODES[hvac_mode] self._elk_set(thermostat_mode, fan_mode) - async def async_turn_aux_heat_on(self): + async def async_turn_aux_heat_on(self) -> None: """Turn auxiliary heater on.""" self._elk_set(ThermostatMode.EMERGENCY_HEAT.value, None) - async def async_turn_aux_heat_off(self): + async def async_turn_aux_heat_off(self) -> None: """Turn auxiliary heater off.""" self._elk_set(ThermostatMode.HEAT.value, None) @property - def fan_modes(self): + def fan_modes(self) -> list[str]: """Return the list of available fan modes.""" return [FAN_AUTO, FAN_ON] - async def async_set_fan_mode(self, fan_mode): + async def async_set_fan_mode(self, fan_mode: str) -> None: """Set new target fan mode.""" - thermostat_mode, fan_mode = HASS_TO_ELK_HVAC_MODES[fan_mode] - self._elk_set(thermostat_mode, fan_mode) + thermostat_mode, elk_fan_mode = HASS_TO_ELK_HVAC_MODES[fan_mode] + self._elk_set(thermostat_mode, elk_fan_mode) - async def async_set_temperature(self, **kwargs): + async def async_set_temperature(self, **kwargs: Any) -> None: """Set new target temperature.""" low_temp = kwargs.get(ATTR_TARGET_TEMP_LOW) high_temp = kwargs.get(ATTR_TARGET_TEMP_HIGH) @@ -198,7 +204,7 @@ class ElkThermostat(ElkEntity, ClimateEntity): if high_temp is not None: self._element.set(ThermostatSetting.COOL_SETPOINT.value, round(high_temp)) - def _element_changed(self, element, changeset): - self._state = ELK_TO_HASS_HVAC_MODES.get(self._element.mode) + def _element_changed(self, element: Element, changeset: Any) -> None: + self._state = ELK_TO_HASS_HVAC_MODES[self._element.mode] if self._state == HVAC_MODE_OFF and self._element.fan == ThermostatFan.ON.value: self._state = HVAC_MODE_FAN_ONLY diff --git a/mypy.ini b/mypy.ini index 5340df24297..063f57c6856 100644 --- a/mypy.ini +++ b/mypy.ini @@ -803,6 +803,17 @@ no_implicit_optional = true warn_return_any = true warn_unreachable = true +[mypy-homeassistant.components.elkm1.climate] +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.elkm1.discovery] check_untyped_defs = true disallow_incomplete_defs = true