Add more type hints in the thermostat classes and selected files (#364)
This commit is contained in:
committed by
GitHub
parent
5d453393f8
commit
ed977b53cd
@@ -6,6 +6,8 @@ import math
|
||||
import logging
|
||||
|
||||
from datetime import timedelta, datetime
|
||||
from types import MappingProxyType
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.util import dt as dt_util
|
||||
from homeassistant.core import (
|
||||
@@ -20,10 +22,12 @@ from homeassistant.components.climate import ClimateEntity
|
||||
from homeassistant.helpers.restore_state import RestoreEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.helpers.device_registry import DeviceInfo, DeviceEntryType
|
||||
from homeassistant.helpers.typing import EventType as HASSEventType
|
||||
|
||||
from homeassistant.helpers.event import (
|
||||
async_track_state_change_event,
|
||||
async_call_later,
|
||||
EventStateChangedData,
|
||||
)
|
||||
|
||||
from homeassistant.exceptions import ConditionError
|
||||
@@ -134,6 +138,7 @@ from .open_window_algorithm import WindowOpenDetectionAlgorithm
|
||||
from .ema import ExponentialMovingAverage
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
ConfigData = MappingProxyType[str, Any]
|
||||
|
||||
|
||||
def get_tz(hass: HomeAssistant):
|
||||
@@ -197,7 +202,13 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
)
|
||||
)
|
||||
|
||||
def __init__(self, hass: HomeAssistant, unique_id, name, entry_infos) -> None:
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
unique_id: str,
|
||||
name: str,
|
||||
entry_infos: ConfigData,
|
||||
):
|
||||
"""Initialize the thermostat."""
|
||||
|
||||
super().__init__()
|
||||
@@ -262,7 +273,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
|
||||
self._last_change_time = None
|
||||
|
||||
self._underlyings = []
|
||||
self._underlyings: list[UnderlyingEntity] = []
|
||||
|
||||
self._ema_temp = None
|
||||
self._ema_algo = None
|
||||
@@ -276,7 +287,9 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
|
||||
self.post_init(entry_infos)
|
||||
|
||||
def clean_central_config_doublon(self, config_entry, central_config) -> dict:
|
||||
def clean_central_config_doublon(
|
||||
self, config_entry: ConfigData, central_config: ConfigEntry | None
|
||||
) -> dict[str, Any]:
|
||||
"""Removes all values from config with are concerned by central_config"""
|
||||
|
||||
def clean_one(cfg, schema: vol.Schema):
|
||||
@@ -322,7 +335,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
|
||||
return entry_infos
|
||||
|
||||
def post_init(self, config_entry):
|
||||
def post_init(self, config_entry: ConfigData):
|
||||
"""Finish the initialization of the thermostast"""
|
||||
|
||||
_LOGGER.info(
|
||||
@@ -345,7 +358,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
self._attr_target_temperature_step = step
|
||||
|
||||
# convert entry_infos into usable attributes
|
||||
presets = {}
|
||||
presets: dict[str, Any] = {}
|
||||
items = CONF_PRESETS_WITH_AC.items() if self._ac_mode else CONF_PRESETS.items()
|
||||
for key, value in items:
|
||||
_LOGGER.debug("looking for key=%s, value=%s", key, value)
|
||||
@@ -357,7 +370,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
self._attr_max_temp if self._ac_mode else self._attr_min_temp
|
||||
)
|
||||
|
||||
presets_away = {}
|
||||
presets_away: dict[str, Any] = {}
|
||||
items = (
|
||||
CONF_PRESETS_AWAY_WITH_AC.items()
|
||||
if self._ac_mode
|
||||
@@ -805,7 +818,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
def init_underlyings(self):
|
||||
"""Initialize all underlyings. Should be overriden if necessary"""
|
||||
|
||||
def restore_specific_previous_state(self, old_state):
|
||||
def restore_specific_previous_state(self, old_state: State):
|
||||
"""Should be overriden in each specific thermostat
|
||||
if a specific previous state or attribute should be
|
||||
restored
|
||||
@@ -886,7 +899,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
self._hvac_mode,
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
def __str__(self) -> str:
|
||||
return f"VersatileThermostat-{self.name}"
|
||||
|
||||
@property
|
||||
@@ -916,19 +929,19 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
)
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
def unique_id(self) -> str:
|
||||
return self._unique_id
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
def should_poll(self) -> bool:
|
||||
return False
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
def name(self) -> str:
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def hvac_modes(self):
|
||||
def hvac_modes(self) -> list[HVACMode]:
|
||||
"""List of available operation modes."""
|
||||
return self._hvac_list
|
||||
|
||||
@@ -1016,17 +1029,17 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
return self._is_used_by_central_boiler
|
||||
|
||||
@property
|
||||
def target_temperature(self):
|
||||
def target_temperature(self) -> float | None:
|
||||
"""Return the temperature we try to reach."""
|
||||
return self._target_temp
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
def supported_features(self) -> ClimateEntityFeature:
|
||||
"""Return the list of supported features."""
|
||||
return self._support_flags
|
||||
|
||||
@property
|
||||
def is_device_active(self):
|
||||
def is_device_active(self) -> bool:
|
||||
"""Returns true if one underlying is active"""
|
||||
for under in self._underlyings:
|
||||
if under.is_device_active:
|
||||
@@ -1034,7 +1047,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
return False
|
||||
|
||||
@property
|
||||
def current_temperature(self):
|
||||
def current_temperature(self) -> float | None:
|
||||
"""Return the sensor temperature."""
|
||||
return self._cur_temp
|
||||
|
||||
@@ -1203,7 +1216,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
"""Turn auxiliary heater off."""
|
||||
raise NotImplementedError()
|
||||
|
||||
async def async_set_hvac_mode(self, hvac_mode, need_control_heating=True):
|
||||
async def async_set_hvac_mode(self, hvac_mode: HVACMode, need_control_heating=True):
|
||||
"""Set new target hvac mode."""
|
||||
_LOGGER.info("%s - Set hvac mode: %s", self, hvac_mode)
|
||||
|
||||
@@ -1239,7 +1252,9 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
self.send_event(EventType.HVAC_MODE_EVENT, {"hvac_mode": self._hvac_mode})
|
||||
|
||||
@overrides
|
||||
async def async_set_preset_mode(self, preset_mode, overwrite_saved_preset=True):
|
||||
async def async_set_preset_mode(
|
||||
self, preset_mode: str, overwrite_saved_preset=True
|
||||
):
|
||||
"""Set new preset mode."""
|
||||
await self._async_set_preset_mode_internal(
|
||||
preset_mode, force=False, overwrite_saved_preset=overwrite_saved_preset
|
||||
@@ -1247,7 +1262,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
await self.async_control_heating(force=True)
|
||||
|
||||
async def _async_set_preset_mode_internal(
|
||||
self, preset_mode, force=False, overwrite_saved_preset=True
|
||||
self, preset_mode: str, force=False, overwrite_saved_preset=True
|
||||
):
|
||||
"""Set new preset mode."""
|
||||
_LOGGER.info("%s - Set preset_mode: %s force=%s", self, preset_mode, force)
|
||||
@@ -1296,13 +1311,13 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
self.send_event(EventType.PRESET_EVENT, {"preset": self._attr_preset_mode})
|
||||
|
||||
def reset_last_change_time(
|
||||
self, old_preset_mode=None
|
||||
self, old_preset_mode: str | None = None
|
||||
): # pylint: disable=unused-argument
|
||||
"""Reset to now the last change time"""
|
||||
self._last_change_time = datetime.now(tz=self._current_tz)
|
||||
_LOGGER.debug("%s - last_change_time is now %s", self, self._last_change_time)
|
||||
|
||||
def reset_last_temperature_time(self, old_preset_mode=None):
|
||||
def reset_last_temperature_time(self, old_preset_mode: str | None = None):
|
||||
"""Reset to now the last temperature time if conditions are satisfied"""
|
||||
if (
|
||||
self._attr_preset_mode not in HIDDEN_PRESETS
|
||||
@@ -1312,7 +1327,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
self._last_ext_temperature_measure
|
||||
) = datetime.now(tz=self._current_tz)
|
||||
|
||||
def find_preset_temp(self, preset_mode):
|
||||
def find_preset_temp(self, preset_mode: str):
|
||||
"""Find the right temperature of a preset considering the presence if configured"""
|
||||
if preset_mode is None or preset_mode == "none":
|
||||
return (
|
||||
@@ -1348,11 +1363,11 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
else:
|
||||
return self._presets_away[self.get_preset_away_name(preset_mode)]
|
||||
|
||||
def get_preset_away_name(self, preset_mode):
|
||||
def get_preset_away_name(self, preset_mode: str) -> str:
|
||||
"""Get the preset name in away mode (when presence is off)"""
|
||||
return preset_mode + PRESET_AWAY_SUFFIX
|
||||
|
||||
async def async_set_fan_mode(self, fan_mode):
|
||||
async def async_set_fan_mode(self, fan_mode: str):
|
||||
"""Set new target fan mode."""
|
||||
_LOGGER.info("%s - Set fan mode: %s", self, fan_mode)
|
||||
return
|
||||
@@ -1362,7 +1377,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
_LOGGER.info("%s - Set fan mode: %s", self, humidity)
|
||||
return
|
||||
|
||||
async def async_set_swing_mode(self, swing_mode):
|
||||
async def async_set_swing_mode(self, swing_mode: str):
|
||||
"""Set new target swing operation."""
|
||||
_LOGGER.info("%s - Set fan mode: %s", self, swing_mode)
|
||||
return
|
||||
@@ -1379,14 +1394,14 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
self.reset_last_change_time()
|
||||
await self.async_control_heating(force=True)
|
||||
|
||||
async def _async_internal_set_temperature(self, temperature):
|
||||
async def _async_internal_set_temperature(self, temperature: float):
|
||||
"""Set the target temperature and the target temperature of underlying climate if any
|
||||
For testing purpose you can pass an event_timestamp.
|
||||
"""
|
||||
self._target_temp = temperature
|
||||
return
|
||||
|
||||
def get_state_date_or_now(self, state: State):
|
||||
def get_state_date_or_now(self, state: State) -> datetime:
|
||||
"""Extract the last_changed state from State or return now if not available"""
|
||||
return (
|
||||
state.last_changed.astimezone(self._current_tz)
|
||||
@@ -1394,7 +1409,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
else datetime.now(tz=self._current_tz)
|
||||
)
|
||||
|
||||
def get_last_updated_date_or_now(self, state: State):
|
||||
def get_last_updated_date_or_now(self, state: State) -> datetime:
|
||||
"""Extract the last_changed state from State or return now if not available"""
|
||||
return (
|
||||
state.last_updated.astimezone(self._current_tz)
|
||||
@@ -1679,7 +1694,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
_LOGGER.error("Unable to update external temperature from sensor: %s", ex)
|
||||
|
||||
@callback
|
||||
async def _async_power_changed(self, event):
|
||||
async def _async_power_changed(self, event: HASSEventType[EventStateChangedData]):
|
||||
"""Handle power changes."""
|
||||
_LOGGER.debug("Thermostat %s - Receive new Power event", self.name)
|
||||
_LOGGER.debug(event)
|
||||
@@ -1705,7 +1720,9 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
_LOGGER.error("Unable to update current_power from sensor: %s", ex)
|
||||
|
||||
@callback
|
||||
async def _async_max_power_changed(self, event):
|
||||
async def _async_max_power_changed(
|
||||
self, event: HASSEventType[EventStateChangedData]
|
||||
):
|
||||
"""Handle power max changes."""
|
||||
_LOGGER.debug("Thermostat %s - Receive new Power Max event", self.name)
|
||||
_LOGGER.debug(event)
|
||||
@@ -1730,7 +1747,9 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
_LOGGER.error("Unable to update current_power from sensor: %s", ex)
|
||||
|
||||
@callback
|
||||
async def _async_presence_changed(self, event):
|
||||
async def _async_presence_changed(
|
||||
self, event: HASSEventType[EventStateChangedData]
|
||||
):
|
||||
"""Handle presence changes."""
|
||||
new_state = event.data.get("new_state")
|
||||
_LOGGER.info(
|
||||
@@ -1746,7 +1765,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
await self._async_update_presence(new_state.state)
|
||||
await self.async_control_heating(force=True)
|
||||
|
||||
async def _async_update_presence(self, new_state):
|
||||
async def _async_update_presence(self, new_state: str):
|
||||
_LOGGER.info("%s - Updating presence. New state is %s", self, new_state)
|
||||
self._presence_state = (
|
||||
STATE_ON if new_state in (STATE_ON, STATE_HOME) else STATE_OFF
|
||||
@@ -2044,7 +2063,9 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
|
||||
return self._overpowering_state
|
||||
|
||||
async def check_central_mode(self, new_central_mode, old_central_mode) -> None:
|
||||
async def check_central_mode(
|
||||
self, new_central_mode: str | None, old_central_mode: str | None
|
||||
):
|
||||
"""Take into account a central mode change"""
|
||||
if not self.is_controlled_by_central_mode:
|
||||
self._last_central_mode = None
|
||||
@@ -2334,7 +2355,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
else: # default is to turn_off
|
||||
await self.async_set_hvac_mode(HVACMode.OFF)
|
||||
|
||||
async def async_control_heating(self, force=False, _=None):
|
||||
async def async_control_heating(self, force=False, _=None) -> bool:
|
||||
"""The main function used to run the calculation at each cycle"""
|
||||
|
||||
_LOGGER.debug(
|
||||
@@ -2402,7 +2423,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
def update_custom_attributes(self):
|
||||
"""Update the custom extra attributes for the entity"""
|
||||
|
||||
self._attr_extra_state_attributes: dict(str, str) = {
|
||||
self._attr_extra_state_attributes: dict[str, Any] = {
|
||||
"is_on": self.is_on,
|
||||
"hvac_action": self.hvac_action,
|
||||
"hvac_mode": self.hvac_mode,
|
||||
@@ -2483,7 +2504,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
"""
|
||||
_LOGGER.info("%s - The config entry have been updated")
|
||||
|
||||
async def service_set_presence(self, presence):
|
||||
async def service_set_presence(self, presence: str):
|
||||
"""Called by a service call:
|
||||
service: versatile_thermostat.set_presence
|
||||
data:
|
||||
@@ -2496,7 +2517,10 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
await self.async_control_heating(force=True)
|
||||
|
||||
async def service_set_preset_temperature(
|
||||
self, preset, temperature=None, temperature_away=None
|
||||
self,
|
||||
preset: str,
|
||||
temperature: float | None = None,
|
||||
temperature_away: float | None = None,
|
||||
):
|
||||
"""Called by a service call:
|
||||
service: versatile_thermostat.set_preset_temperature
|
||||
@@ -2534,7 +2558,12 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
)
|
||||
await self.async_control_heating(force=True)
|
||||
|
||||
async def service_set_security(self, delay_min, min_on_percent, default_on_percent):
|
||||
async def service_set_security(
|
||||
self,
|
||||
delay_min: int | None,
|
||||
min_on_percent: float | None,
|
||||
default_on_percent: float | None,
|
||||
):
|
||||
"""Called by a service call:
|
||||
service: versatile_thermostat.set_security
|
||||
data:
|
||||
@@ -2564,7 +2593,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
||||
await self.async_control_heating()
|
||||
self.update_custom_attributes()
|
||||
|
||||
async def service_set_window_bypass_state(self, window_bypass):
|
||||
async def service_set_window_bypass_state(self, window_bypass: bool):
|
||||
"""Called by a service call:
|
||||
service: versatile_thermostat.set_window_bypass
|
||||
data:
|
||||
|
||||
@@ -14,8 +14,10 @@ from homeassistant.helpers.restore_state import RestoreEntity
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_component import EntityComponent
|
||||
|
||||
|
||||
from custom_components.versatile_thermostat.base_thermostat import BaseThermostat
|
||||
from custom_components.versatile_thermostat.base_thermostat import (
|
||||
BaseThermostat,
|
||||
ConfigData,
|
||||
)
|
||||
from .const import (
|
||||
DOMAIN,
|
||||
DEVICE_MANUFACTURER,
|
||||
@@ -57,7 +59,9 @@ async def async_setup_entry(
|
||||
class CentralModeSelect(SelectEntity, RestoreEntity):
|
||||
"""Representation of the central mode choice"""
|
||||
|
||||
def __init__(self, hass: HomeAssistant, unique_id, name, entry_infos) -> None:
|
||||
def __init__(
|
||||
self, hass: HomeAssistant, unique_id: str, name: str, entry_infos: ConfigData
|
||||
):
|
||||
"""Initialize the energy sensor"""
|
||||
self._config_id = unique_id
|
||||
self._device_name = entry_infos.get(CONF_NAME)
|
||||
@@ -67,7 +71,7 @@ class CentralModeSelect(SelectEntity, RestoreEntity):
|
||||
self._attr_current_option = CENTRAL_MODE_AUTO
|
||||
|
||||
@property
|
||||
def icon(self) -> str | None:
|
||||
def icon(self) -> str:
|
||||
return "mdi:form-select"
|
||||
|
||||
@property
|
||||
@@ -116,7 +120,7 @@ class CentralModeSelect(SelectEntity, RestoreEntity):
|
||||
self._attr_current_option = option
|
||||
await self.notify_central_mode_change(old_central_mode=old_option)
|
||||
|
||||
async def notify_central_mode_change(self, old_central_mode=None):
|
||||
async def notify_central_mode_change(self, old_central_mode: str | None = None):
|
||||
"""Notify all VTherm that the central_mode have change"""
|
||||
# Update all VTherm states
|
||||
component: EntityComponent[ClimateEntity] = self.hass.data[CLIMATE_DOMAIN]
|
||||
@@ -130,5 +134,5 @@ class CentralModeSelect(SelectEntity, RestoreEntity):
|
||||
self._attr_current_option, old_central_mode
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
def __str__(self) -> str:
|
||||
return f"VersatileThermostat-{self.name}"
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
import logging
|
||||
from datetime import timedelta, datetime
|
||||
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.core import HomeAssistant, State, callback
|
||||
from homeassistant.helpers.event import (
|
||||
async_track_state_change_event,
|
||||
async_track_time_interval,
|
||||
EventStateChangedData,
|
||||
)
|
||||
|
||||
from homeassistant.helpers.typing import EventType as HASSEventType
|
||||
from homeassistant.components.climate import (
|
||||
HVACAction,
|
||||
HVACMode,
|
||||
@@ -16,7 +17,7 @@ from homeassistant.components.climate import (
|
||||
)
|
||||
|
||||
from .commons import NowClass, round_to_nearest
|
||||
from .base_thermostat import BaseThermostat
|
||||
from .base_thermostat import BaseThermostat, ConfigData
|
||||
from .pi_algorithm import PITemperatureRegulator
|
||||
|
||||
from .const import (
|
||||
@@ -59,19 +60,19 @@ _LOGGER = logging.getLogger(__name__)
|
||||
class ThermostatOverClimate(BaseThermostat):
|
||||
"""Representation of a base class for a Versatile Thermostat over a climate"""
|
||||
|
||||
_auto_regulation_mode: str = None
|
||||
_auto_regulation_mode: str | None = None
|
||||
_regulation_algo = None
|
||||
_regulated_target_temp: float = None
|
||||
_auto_regulation_dtemp: float = None
|
||||
_auto_regulation_period_min: int = None
|
||||
_last_regulation_change: datetime = None
|
||||
_regulated_target_temp: float | None = None
|
||||
_auto_regulation_dtemp: float | None = None
|
||||
_auto_regulation_period_min: int | None = None
|
||||
_last_regulation_change: datetime | None = None
|
||||
# The fan mode configured in configEntry
|
||||
_auto_fan_mode: str = None
|
||||
_auto_fan_mode: str | None = None
|
||||
# The current fan mode (could be change by service call)
|
||||
_current_auto_fan_mode: str = None
|
||||
_current_auto_fan_mode: str | None = None
|
||||
# The fan_mode name depending of the current_mode
|
||||
_auto_activated_fan_mode: str = None
|
||||
_auto_deactivated_fan_mode: str = None
|
||||
_auto_activated_fan_mode: str | None = None
|
||||
_auto_deactivated_fan_mode: str | None = None
|
||||
|
||||
_entity_component_unrecorded_attributes = (
|
||||
BaseThermostat._entity_component_unrecorded_attributes.union(
|
||||
@@ -94,7 +95,9 @@ class ThermostatOverClimate(BaseThermostat):
|
||||
)
|
||||
)
|
||||
|
||||
def __init__(self, hass: HomeAssistant, unique_id, name, entry_infos) -> None:
|
||||
def __init__(
|
||||
self, hass: HomeAssistant, unique_id: str, name: str, entry_infos: ConfigData
|
||||
):
|
||||
"""Initialize the thermostat over switch."""
|
||||
# super.__init__ calls post_init at the end. So it must be called after regulation initialization
|
||||
super().__init__(hass, unique_id, name, entry_infos)
|
||||
@@ -127,7 +130,7 @@ class ThermostatOverClimate(BaseThermostat):
|
||||
return HVACAction.OFF
|
||||
|
||||
@overrides
|
||||
async def _async_internal_set_temperature(self, temperature):
|
||||
async def _async_internal_set_temperature(self, temperature: float):
|
||||
"""Set the target temperature and the target temperature of underlying climate if any"""
|
||||
await super()._async_internal_set_temperature(temperature)
|
||||
|
||||
@@ -239,7 +242,7 @@ class ThermostatOverClimate(BaseThermostat):
|
||||
await self.async_set_fan_mode(self._auto_deactivated_fan_mode)
|
||||
|
||||
@overrides
|
||||
def post_init(self, config_entry):
|
||||
def post_init(self, config_entry: ConfigData):
|
||||
"""Initialize the Thermostat"""
|
||||
|
||||
super().post_init(config_entry)
|
||||
@@ -281,7 +284,7 @@ class ThermostatOverClimate(BaseThermostat):
|
||||
else CONF_AUTO_FAN_NONE
|
||||
)
|
||||
|
||||
def choose_auto_regulation_mode(self, auto_regulation_mode):
|
||||
def choose_auto_regulation_mode(self, auto_regulation_mode: str):
|
||||
"""Choose or change the regulation mode"""
|
||||
self._auto_regulation_mode = auto_regulation_mode
|
||||
if self._auto_regulation_mode == CONF_AUTO_REGULATION_LIGHT:
|
||||
@@ -357,7 +360,7 @@ class ThermostatOverClimate(BaseThermostat):
|
||||
self.target_temperature, 0, 0, 0, 0, 0.1, 0
|
||||
)
|
||||
|
||||
def choose_auto_fan_mode(self, auto_fan_mode):
|
||||
def choose_auto_fan_mode(self, auto_fan_mode: str):
|
||||
"""Choose the correct fan mode depending of the underlying capacities and the configuration"""
|
||||
|
||||
self._current_auto_fan_mode = auto_fan_mode
|
||||
@@ -369,7 +372,7 @@ class ThermostatOverClimate(BaseThermostat):
|
||||
self._auto_activated_fan_mode = self._auto_deactivated_fan_mode = None
|
||||
return
|
||||
|
||||
def find_fan_mode(fan_modes, fan_mode) -> str:
|
||||
def find_fan_mode(fan_modes: list[str], fan_mode: str) -> str | None:
|
||||
"""Return the fan_mode if it exist of None if not"""
|
||||
try:
|
||||
return fan_mode if fan_modes.index(fan_mode) >= 0 else None
|
||||
@@ -430,7 +433,7 @@ class ThermostatOverClimate(BaseThermostat):
|
||||
self.choose_auto_regulation_mode(self._auto_regulation_mode)
|
||||
|
||||
@overrides
|
||||
def restore_specific_previous_state(self, old_state):
|
||||
def restore_specific_previous_state(self, old_state: State):
|
||||
"""Restore my specific attributes from previous state"""
|
||||
old_error = old_state.attributes.get("regulation_accumulated_error")
|
||||
if old_error:
|
||||
@@ -542,7 +545,7 @@ class ThermostatOverClimate(BaseThermostat):
|
||||
)
|
||||
|
||||
@callback
|
||||
async def _async_climate_changed(self, event):
|
||||
async def _async_climate_changed(self, event: HASSEventType[EventStateChangedData]):
|
||||
"""Handle unerdlying climate state changes.
|
||||
This method takes the underlying values and update the VTherm with them.
|
||||
To avoid loops (issues #121 #101 #95 #99), we discard the event if it is received
|
||||
@@ -552,7 +555,7 @@ class ThermostatOverClimate(BaseThermostat):
|
||||
which is important for feedaback and which cannot generates loops.
|
||||
"""
|
||||
|
||||
async def end_climate_changed(changes):
|
||||
async def end_climate_changed(changes: bool):
|
||||
"""To end the event management"""
|
||||
if changes:
|
||||
self.async_write_ha_state()
|
||||
@@ -745,7 +748,7 @@ class ThermostatOverClimate(BaseThermostat):
|
||||
await end_climate_changed(changes)
|
||||
|
||||
@overrides
|
||||
async def async_control_heating(self, force=False, _=None):
|
||||
async def async_control_heating(self, force=False, _=None) -> bool:
|
||||
"""The main function used to run the calculation at each cycle"""
|
||||
ret = await super().async_control_heating(force, _)
|
||||
|
||||
@@ -757,27 +760,27 @@ class ThermostatOverClimate(BaseThermostat):
|
||||
return ret
|
||||
|
||||
@property
|
||||
def auto_regulation_mode(self):
|
||||
def auto_regulation_mode(self) -> str | None:
|
||||
"""Get the regulation mode"""
|
||||
return self._auto_regulation_mode
|
||||
|
||||
@property
|
||||
def auto_fan_mode(self):
|
||||
def auto_fan_mode(self) -> str | None:
|
||||
"""Get the auto fan mode"""
|
||||
return self._auto_fan_mode
|
||||
|
||||
@property
|
||||
def regulated_target_temp(self):
|
||||
def regulated_target_temp(self) -> float | None:
|
||||
"""Get the regulated target temperature"""
|
||||
return self._regulated_target_temp
|
||||
|
||||
@property
|
||||
def is_regulated(self):
|
||||
def is_regulated(self) -> bool:
|
||||
"""Check if the ThermostatOverClimate is regulated"""
|
||||
return self.auto_regulation_mode != CONF_AUTO_REGULATION_NONE
|
||||
|
||||
@property
|
||||
def hvac_modes(self):
|
||||
def hvac_modes(self) -> list[HVACMode]:
|
||||
"""List of available operation modes."""
|
||||
if self.underlying_entity(0):
|
||||
return self.underlying_entity(0).hvac_modes
|
||||
@@ -944,7 +947,7 @@ class ThermostatOverClimate(BaseThermostat):
|
||||
await under.async_turn_aux_heat_off()
|
||||
|
||||
@overrides
|
||||
async def async_set_fan_mode(self, fan_mode):
|
||||
async def async_set_fan_mode(self, fan_mode: str):
|
||||
"""Set new target fan mode."""
|
||||
_LOGGER.info("%s - Set fan mode: %s", self, fan_mode)
|
||||
if fan_mode is None:
|
||||
@@ -977,7 +980,7 @@ class ThermostatOverClimate(BaseThermostat):
|
||||
self._swing_mode = swing_mode
|
||||
self.async_write_ha_state()
|
||||
|
||||
async def service_set_auto_regulation_mode(self, auto_regulation_mode):
|
||||
async def service_set_auto_regulation_mode(self, auto_regulation_mode: str):
|
||||
"""Called by a service call:
|
||||
service: versatile_thermostat.set_auto_regulation_mode
|
||||
data:
|
||||
@@ -1006,7 +1009,7 @@ class ThermostatOverClimate(BaseThermostat):
|
||||
await self._send_regulated_temperature()
|
||||
self.update_custom_attributes()
|
||||
|
||||
async def service_set_auto_fan_mode(self, auto_fan_mode):
|
||||
async def service_set_auto_fan_mode(self, auto_fan_mode: str):
|
||||
"""Called by a service call:
|
||||
service: versatile_thermostat.set_auto_fan_mode
|
||||
data:
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
""" A climate over switch classe """
|
||||
import logging
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.event import async_track_state_change_event
|
||||
from homeassistant.helpers.event import (
|
||||
async_track_state_change_event,
|
||||
EventStateChangedData,
|
||||
)
|
||||
from homeassistant.helpers.typing import EventType as HASSEventType
|
||||
from homeassistant.components.climate import HVACMode
|
||||
|
||||
from .const import (
|
||||
@@ -15,7 +19,7 @@ from .const import (
|
||||
overrides,
|
||||
)
|
||||
|
||||
from .base_thermostat import BaseThermostat
|
||||
from .base_thermostat import BaseThermostat, ConfigData
|
||||
from .underlyings import UnderlyingSwitch
|
||||
from .prop_algorithm import PropAlgorithm
|
||||
|
||||
@@ -51,7 +55,7 @@ class ThermostatOverSwitch(BaseThermostat):
|
||||
# def __init__(self, hass: HomeAssistant, unique_id, name, config_entry) -> None:
|
||||
# """Initialize the thermostat over switch."""
|
||||
# super().__init__(hass, unique_id, name, config_entry)
|
||||
_is_inversed: bool = None
|
||||
_is_inversed: bool | None = None
|
||||
|
||||
@property
|
||||
def is_over_switch(self) -> bool:
|
||||
@@ -72,7 +76,7 @@ class ThermostatOverSwitch(BaseThermostat):
|
||||
return None
|
||||
|
||||
@overrides
|
||||
def post_init(self, config_entry):
|
||||
def post_init(self, config_entry: ConfigData):
|
||||
"""Initialize the Thermostat"""
|
||||
|
||||
super().post_init(config_entry)
|
||||
@@ -200,7 +204,7 @@ class ThermostatOverSwitch(BaseThermostat):
|
||||
)
|
||||
|
||||
@callback
|
||||
def _async_switch_changed(self, event):
|
||||
def _async_switch_changed(self, event: HASSEventType[EventStateChangedData]):
|
||||
"""Handle heater switch state changes."""
|
||||
new_state = event.data.get("new_state")
|
||||
old_state = event.data.get("old_state")
|
||||
|
||||
@@ -6,11 +6,13 @@ from datetime import timedelta, datetime
|
||||
from homeassistant.helpers.event import (
|
||||
async_track_state_change_event,
|
||||
async_track_time_interval,
|
||||
EventStateChangedData,
|
||||
)
|
||||
from homeassistant.helpers.typing import EventType as HASSEventType
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.components.climate import HVACMode
|
||||
|
||||
from .base_thermostat import BaseThermostat
|
||||
from .base_thermostat import BaseThermostat, ConfigData
|
||||
from .prop_algorithm import PropAlgorithm
|
||||
|
||||
from .const import (
|
||||
@@ -55,12 +57,14 @@ class ThermostatOverValve(BaseThermostat):
|
||||
)
|
||||
)
|
||||
|
||||
def __init__(self, hass: HomeAssistant, unique_id, name, config_entry) -> None:
|
||||
def __init__(
|
||||
self, hass: HomeAssistant, unique_id: str, name: str, config_entry: ConfigData
|
||||
):
|
||||
"""Initialize the thermostat over switch."""
|
||||
self._valve_open_percent: int = 0
|
||||
self._last_calculation_timestamp: datetime = None
|
||||
self._auto_regulation_dpercent: float = None
|
||||
self._auto_regulation_period_min: int = None
|
||||
self._last_calculation_timestamp: datetime | None = None
|
||||
self._auto_regulation_dpercent: float | None = None
|
||||
self._auto_regulation_period_min: int | None = None
|
||||
|
||||
# Call to super must be done after initialization because it calls post_init at the end
|
||||
super().__init__(hass, unique_id, name, config_entry)
|
||||
@@ -79,7 +83,7 @@ class ThermostatOverValve(BaseThermostat):
|
||||
return self._valve_open_percent
|
||||
|
||||
@overrides
|
||||
def post_init(self, config_entry):
|
||||
def post_init(self, config_entry: ConfigData):
|
||||
"""Initialize the Thermostat"""
|
||||
|
||||
super().post_init(config_entry)
|
||||
@@ -144,7 +148,7 @@ class ThermostatOverValve(BaseThermostat):
|
||||
)
|
||||
|
||||
@callback
|
||||
async def _async_valve_changed(self, event):
|
||||
async def _async_valve_changed(self, event: HASSEventType[EventStateChangedData]):
|
||||
"""Handle unerdlying valve state changes.
|
||||
This method just log the change. It changes nothing to avoid loops.
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user