Add more type hints in the thermostat classes and selected files (#364)

This commit is contained in:
Paulo Ferreira de Castro
2024-01-26 09:51:25 +00:00
committed by GitHub
parent 5d453393f8
commit ed977b53cd
5 changed files with 131 additions and 87 deletions

View File

@@ -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:

View File

@@ -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}"

View File

@@ -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:

View File

@@ -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")

View File

@@ -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.
"""