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.
This commit is contained in:
Glenn Waters 2022-04-19 16:52:46 -04:00 committed by GitHub
parent 1fb261cdc5
commit cec2a40602
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 47 additions and 29 deletions

View File

@ -91,6 +91,7 @@ homeassistant.components.dunehd.*
homeassistant.components.efergy.* homeassistant.components.efergy.*
homeassistant.components.elgato.* homeassistant.components.elgato.*
homeassistant.components.elkm1.__init__ homeassistant.components.elkm1.__init__
homeassistant.components.elkm1.climate
homeassistant.components.elkm1.discovery homeassistant.components.elkm1.discovery
homeassistant.components.elkm1.light homeassistant.components.elkm1.light
homeassistant.components.elkm1.scene homeassistant.components.elkm1.scene

View File

@ -446,7 +446,7 @@ class ElkEntity(Entity):
self._mac = elk_data["mac"] self._mac = elk_data["mac"]
self._prefix = elk_data["prefix"] self._prefix = elk_data["prefix"]
self._name_prefix = f"{self._prefix} " if self._prefix else "" 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 # unique_id starts with elkm1_ iff there is no prefix
# it starts with elkm1m_{prefix} iff there is a prefix # it starts with elkm1m_{prefix} iff there is a prefix
# this is to avoid a conflict between # this is to avoid a conflict between

View File

@ -1,7 +1,12 @@
"""Support for control of Elk-M1 connected thermostats.""" """Support for control of Elk-M1 connected thermostats."""
from __future__ import annotations from __future__ import annotations
from typing import Any
from elkm1_lib.const import ThermostatFan, ThermostatMode, ThermostatSetting 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 import ClimateEntity, ClimateEntityFeature
from homeassistant.components.climate.const import ( from homeassistant.components.climate.const import (
@ -77,24 +82,25 @@ class ElkThermostat(ElkEntity, ClimateEntity):
| ClimateEntityFeature.AUX_HEAT | ClimateEntityFeature.AUX_HEAT
| ClimateEntityFeature.TARGET_TEMPERATURE_RANGE | 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.""" """Initialize climate entity."""
super().__init__(element, elk, elk_data) super().__init__(element, elk, elk_data)
self._state = None self._state: str = HVAC_MODE_OFF
@property @property
def temperature_unit(self): def temperature_unit(self) -> str:
"""Return the temperature unit.""" """Return the temperature unit."""
return self._temperature_unit return self._temperature_unit
@property @property
def current_temperature(self): def current_temperature(self) -> float | None:
"""Return the current temperature.""" """Return the current temperature."""
return self._element.current_temp return self._element.current_temp
@property @property
def target_temperature(self): def target_temperature(self) -> float | None:
"""Return the temperature we are trying to reach.""" """Return the temperature we are trying to reach."""
if self._element.mode in ( if self._element.mode in (
ThermostatMode.HEAT.value, ThermostatMode.HEAT.value,
@ -106,90 +112,90 @@ class ElkThermostat(ElkEntity, ClimateEntity):
return None return None
@property @property
def target_temperature_high(self): def target_temperature_high(self) -> float | None:
"""Return the high target temperature.""" """Return the high target temperature."""
return self._element.cool_setpoint return self._element.cool_setpoint
@property @property
def target_temperature_low(self): def target_temperature_low(self) -> float | None:
"""Return the low target temperature.""" """Return the low target temperature."""
return self._element.heat_setpoint return self._element.heat_setpoint
@property @property
def target_temperature_step(self): def target_temperature_step(self) -> float:
"""Return the supported step of target temperature.""" """Return the supported step of target temperature."""
return 1 return 1
@property @property
def current_humidity(self): def current_humidity(self) -> int | None:
"""Return the current humidity.""" """Return the current humidity."""
return self._element.humidity return self._element.humidity
@property @property
def hvac_mode(self): def hvac_mode(self) -> str:
"""Return current operation ie. heat, cool, idle.""" """Return current operation ie. heat, cool, idle."""
return self._state return self._state
@property @property
def hvac_modes(self): def hvac_modes(self) -> list[str]:
"""Return the list of available operation modes.""" """Return the list of available operation modes."""
return SUPPORT_HVAC return SUPPORT_HVAC
@property @property
def precision(self): def precision(self) -> int:
"""Return the precision of the system.""" """Return the precision of the system."""
return PRECISION_WHOLE return PRECISION_WHOLE
@property @property
def is_aux_heat(self): def is_aux_heat(self) -> bool:
"""Return if aux heater is on.""" """Return if aux heater is on."""
return self._element.mode == ThermostatMode.EMERGENCY_HEAT.value return self._element.mode == ThermostatMode.EMERGENCY_HEAT.value
@property @property
def min_temp(self): def min_temp(self) -> float:
"""Return the minimum temperature supported.""" """Return the minimum temperature supported."""
return 1 return 1
@property @property
def max_temp(self): def max_temp(self) -> float:
"""Return the maximum temperature supported.""" """Return the maximum temperature supported."""
return 99 return 99
@property @property
def fan_mode(self): def fan_mode(self) -> str:
"""Return the fan setting.""" """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: if mode is not None:
self._element.set(ThermostatSetting.MODE.value, mode) self._element.set(ThermostatSetting.MODE.value, mode)
if fan is not None: if fan is not None:
self._element.set(ThermostatSetting.FAN.value, fan) 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.""" """Set thermostat operation mode."""
thermostat_mode, fan_mode = HASS_TO_ELK_HVAC_MODES[hvac_mode] thermostat_mode, fan_mode = HASS_TO_ELK_HVAC_MODES[hvac_mode]
self._elk_set(thermostat_mode, fan_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.""" """Turn auxiliary heater on."""
self._elk_set(ThermostatMode.EMERGENCY_HEAT.value, None) 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.""" """Turn auxiliary heater off."""
self._elk_set(ThermostatMode.HEAT.value, None) self._elk_set(ThermostatMode.HEAT.value, None)
@property @property
def fan_modes(self): def fan_modes(self) -> list[str]:
"""Return the list of available fan modes.""" """Return the list of available fan modes."""
return [FAN_AUTO, FAN_ON] 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.""" """Set new target fan mode."""
thermostat_mode, fan_mode = HASS_TO_ELK_HVAC_MODES[fan_mode] thermostat_mode, elk_fan_mode = HASS_TO_ELK_HVAC_MODES[fan_mode]
self._elk_set(thermostat_mode, 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.""" """Set new target temperature."""
low_temp = kwargs.get(ATTR_TARGET_TEMP_LOW) low_temp = kwargs.get(ATTR_TARGET_TEMP_LOW)
high_temp = kwargs.get(ATTR_TARGET_TEMP_HIGH) high_temp = kwargs.get(ATTR_TARGET_TEMP_HIGH)
@ -198,7 +204,7 @@ class ElkThermostat(ElkEntity, ClimateEntity):
if high_temp is not None: if high_temp is not None:
self._element.set(ThermostatSetting.COOL_SETPOINT.value, round(high_temp)) self._element.set(ThermostatSetting.COOL_SETPOINT.value, round(high_temp))
def _element_changed(self, element, changeset): def _element_changed(self, element: Element, changeset: Any) -> None:
self._state = ELK_TO_HASS_HVAC_MODES.get(self._element.mode) self._state = ELK_TO_HASS_HVAC_MODES[self._element.mode]
if self._state == HVAC_MODE_OFF and self._element.fan == ThermostatFan.ON.value: if self._state == HVAC_MODE_OFF and self._element.fan == ThermostatFan.ON.value:
self._state = HVAC_MODE_FAN_ONLY self._state = HVAC_MODE_FAN_ONLY

View File

@ -803,6 +803,17 @@ no_implicit_optional = true
warn_return_any = true warn_return_any = true
warn_unreachable = 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] [mypy-homeassistant.components.elkm1.discovery]
check_untyped_defs = true check_untyped_defs = true
disallow_incomplete_defs = true disallow_incomplete_defs = true