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