Co-authored-by: Jean-Marc Collin <jean-marc.collin-extern@renault.com>
This commit is contained in:
@@ -3,9 +3,9 @@ default_config:
|
||||
logger:
|
||||
default: warning
|
||||
logs:
|
||||
# custom_components.versatile_thermostat: debug
|
||||
# custom_components.versatile_thermostat.underlyings: debug
|
||||
# custom_components.versatile_thermostat.climate: debug
|
||||
custom_components.versatile_thermostat: info
|
||||
custom_components.versatile_thermostat.underlyings: info
|
||||
custom_components.versatile_thermostat.climate: info
|
||||
|
||||
# If you need to debug uncommment the line below (doc: https://www.home-assistant.io/integrations/debugpy/)
|
||||
debugpy:
|
||||
|
||||
@@ -107,6 +107,8 @@ async def async_setup(
|
||||
"VersatileThermostat - HA is started, initialize all links between VTherm entities"
|
||||
)
|
||||
await api.init_vtherm_links()
|
||||
await api.notify_central_mode_change()
|
||||
await api.reload_central_boiler_entities_list()
|
||||
|
||||
if hass.state == CoreState.running:
|
||||
await _async_startup_internal()
|
||||
@@ -156,8 +158,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
|
||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||
|
||||
await api.reload_central_boiler_entities_list()
|
||||
await api.init_vtherm_links()
|
||||
if hass.state == CoreState.running:
|
||||
await api.reload_central_boiler_entities_list()
|
||||
await api.init_vtherm_links()
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@@ -629,7 +629,8 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
|
||||
self.async_on_remove(self.remove_thermostat)
|
||||
|
||||
await self.async_startup()
|
||||
# issue 428. Link to others entities will start at link
|
||||
# await self.async_startup()
|
||||
|
||||
def remove_thermostat(self):
|
||||
"""Called when the thermostat will be removed"""
|
||||
@@ -637,155 +638,157 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
for under in self._underlyings:
|
||||
under.remove_entity()
|
||||
|
||||
async def async_startup(self):
|
||||
async def async_startup(self, central_configuration):
|
||||
"""Triggered on startup, used to get old state and set internal states accordingly"""
|
||||
_LOGGER.debug("%s - Calling async_startup", self)
|
||||
|
||||
@callback
|
||||
async def _async_startup_internal(*_):
|
||||
_LOGGER.debug("%s - Calling async_startup_internal", self)
|
||||
need_write_state = False
|
||||
_LOGGER.debug("%s - Calling async_startup_internal", self)
|
||||
need_write_state = False
|
||||
|
||||
# Initialize all UnderlyingEntities
|
||||
self.init_underlyings()
|
||||
await self.get_my_previous_state()
|
||||
|
||||
temperature_state = self.hass.states.get(self._temp_sensor_entity_id)
|
||||
if temperature_state and temperature_state.state not in (
|
||||
await self.init_presets(central_configuration)
|
||||
|
||||
# Initialize all UnderlyingEntities
|
||||
self.init_underlyings()
|
||||
|
||||
temperature_state = self.hass.states.get(self._temp_sensor_entity_id)
|
||||
if temperature_state and temperature_state.state not in (
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_UNKNOWN,
|
||||
):
|
||||
_LOGGER.debug(
|
||||
"%s - temperature sensor have been retrieved: %.1f",
|
||||
self,
|
||||
float(temperature_state.state),
|
||||
)
|
||||
await self._async_update_temp(temperature_state)
|
||||
need_write_state = True
|
||||
|
||||
if self._ext_temp_sensor_entity_id:
|
||||
ext_temperature_state = self.hass.states.get(
|
||||
self._ext_temp_sensor_entity_id
|
||||
)
|
||||
if ext_temperature_state and ext_temperature_state.state not in (
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_UNKNOWN,
|
||||
):
|
||||
_LOGGER.debug(
|
||||
"%s - temperature sensor have been retrieved: %.1f",
|
||||
"%s - external temperature sensor have been retrieved: %.1f",
|
||||
self,
|
||||
float(temperature_state.state),
|
||||
float(ext_temperature_state.state),
|
||||
)
|
||||
await self._async_update_temp(temperature_state)
|
||||
need_write_state = True
|
||||
|
||||
if self._ext_temp_sensor_entity_id:
|
||||
ext_temperature_state = self.hass.states.get(
|
||||
self._ext_temp_sensor_entity_id
|
||||
)
|
||||
if ext_temperature_state and ext_temperature_state.state not in (
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_UNKNOWN,
|
||||
):
|
||||
_LOGGER.debug(
|
||||
"%s - external temperature sensor have been retrieved: %.1f",
|
||||
self,
|
||||
float(ext_temperature_state.state),
|
||||
)
|
||||
await self._async_update_ext_temp(ext_temperature_state)
|
||||
else:
|
||||
_LOGGER.debug(
|
||||
"%s - external temperature sensor have NOT been retrieved cause unknown or unavailable",
|
||||
self,
|
||||
)
|
||||
await self._async_update_ext_temp(ext_temperature_state)
|
||||
else:
|
||||
_LOGGER.debug(
|
||||
"%s - external temperature sensor have NOT been retrieved cause no external sensor",
|
||||
"%s - external temperature sensor have NOT been retrieved cause unknown or unavailable",
|
||||
self,
|
||||
)
|
||||
|
||||
if self._pmax_on:
|
||||
# try to acquire current power and power max
|
||||
current_power_state = self.hass.states.get(self._power_sensor_entity_id)
|
||||
if current_power_state and current_power_state.state not in (
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_UNKNOWN,
|
||||
):
|
||||
self._current_power = float(current_power_state.state)
|
||||
_LOGGER.debug(
|
||||
"%s - Current power have been retrieved: %.3f",
|
||||
self,
|
||||
self._current_power,
|
||||
)
|
||||
need_write_state = True
|
||||
|
||||
# Try to acquire power max
|
||||
current_power_max_state = self.hass.states.get(
|
||||
self._max_power_sensor_entity_id
|
||||
)
|
||||
if current_power_max_state and current_power_max_state.state not in (
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_UNKNOWN,
|
||||
):
|
||||
self._current_power_max = float(current_power_max_state.state)
|
||||
_LOGGER.debug(
|
||||
"%s - Current power max have been retrieved: %.3f",
|
||||
self,
|
||||
self._current_power_max,
|
||||
)
|
||||
need_write_state = True
|
||||
|
||||
# try to acquire window entity state
|
||||
if self._window_sensor_entity_id:
|
||||
window_state = self.hass.states.get(self._window_sensor_entity_id)
|
||||
if window_state and window_state.state not in (
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_UNKNOWN,
|
||||
):
|
||||
self._window_state = window_state.state == STATE_ON
|
||||
_LOGGER.debug(
|
||||
"%s - Window state have been retrieved: %s",
|
||||
self,
|
||||
self._window_state,
|
||||
)
|
||||
need_write_state = True
|
||||
|
||||
# try to acquire motion entity state
|
||||
if self._motion_sensor_entity_id:
|
||||
motion_state = self.hass.states.get(self._motion_sensor_entity_id)
|
||||
if motion_state and motion_state.state not in (
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_UNKNOWN,
|
||||
):
|
||||
self._motion_state = motion_state.state
|
||||
_LOGGER.debug(
|
||||
"%s - Motion state have been retrieved: %s",
|
||||
self,
|
||||
self._motion_state,
|
||||
)
|
||||
# recalculate the right target_temp in activity mode
|
||||
await self._async_update_motion_temp()
|
||||
need_write_state = True
|
||||
|
||||
if self._presence_on:
|
||||
# try to acquire presence entity state
|
||||
presence_state = self.hass.states.get(self._presence_sensor_entity_id)
|
||||
if presence_state and presence_state.state not in (
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_UNKNOWN,
|
||||
):
|
||||
await self._async_update_presence(presence_state.state)
|
||||
_LOGGER.debug(
|
||||
"%s - Presence have been retrieved: %s",
|
||||
self,
|
||||
presence_state.state,
|
||||
)
|
||||
need_write_state = True
|
||||
|
||||
if need_write_state:
|
||||
self.async_write_ha_state()
|
||||
if self._prop_algorithm:
|
||||
self._prop_algorithm.calculate(
|
||||
self._target_temp,
|
||||
self._cur_temp,
|
||||
self._cur_ext_temp,
|
||||
self._hvac_mode or HVACMode.OFF,
|
||||
)
|
||||
|
||||
self.reset_last_change_time()
|
||||
|
||||
await self.get_my_previous_state()
|
||||
|
||||
if self.hass.state == CoreState.running:
|
||||
await _async_startup_internal()
|
||||
else:
|
||||
self.hass.bus.async_listen_once(
|
||||
EVENT_HOMEASSISTANT_START, _async_startup_internal
|
||||
_LOGGER.debug(
|
||||
"%s - external temperature sensor have NOT been retrieved cause no external sensor",
|
||||
self,
|
||||
)
|
||||
|
||||
if self._pmax_on:
|
||||
# try to acquire current power and power max
|
||||
current_power_state = self.hass.states.get(self._power_sensor_entity_id)
|
||||
if current_power_state and current_power_state.state not in (
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_UNKNOWN,
|
||||
):
|
||||
self._current_power = float(current_power_state.state)
|
||||
_LOGGER.debug(
|
||||
"%s - Current power have been retrieved: %.3f",
|
||||
self,
|
||||
self._current_power,
|
||||
)
|
||||
need_write_state = True
|
||||
|
||||
# Try to acquire power max
|
||||
current_power_max_state = self.hass.states.get(
|
||||
self._max_power_sensor_entity_id
|
||||
)
|
||||
if current_power_max_state and current_power_max_state.state not in (
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_UNKNOWN,
|
||||
):
|
||||
self._current_power_max = float(current_power_max_state.state)
|
||||
_LOGGER.debug(
|
||||
"%s - Current power max have been retrieved: %.3f",
|
||||
self,
|
||||
self._current_power_max,
|
||||
)
|
||||
need_write_state = True
|
||||
|
||||
# try to acquire window entity state
|
||||
if self._window_sensor_entity_id:
|
||||
window_state = self.hass.states.get(self._window_sensor_entity_id)
|
||||
if window_state and window_state.state not in (
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_UNKNOWN,
|
||||
):
|
||||
self._window_state = window_state.state == STATE_ON
|
||||
_LOGGER.debug(
|
||||
"%s - Window state have been retrieved: %s",
|
||||
self,
|
||||
self._window_state,
|
||||
)
|
||||
need_write_state = True
|
||||
|
||||
# try to acquire motion entity state
|
||||
if self._motion_sensor_entity_id:
|
||||
motion_state = self.hass.states.get(self._motion_sensor_entity_id)
|
||||
if motion_state and motion_state.state not in (
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_UNKNOWN,
|
||||
):
|
||||
self._motion_state = motion_state.state
|
||||
_LOGGER.debug(
|
||||
"%s - Motion state have been retrieved: %s",
|
||||
self,
|
||||
self._motion_state,
|
||||
)
|
||||
# recalculate the right target_temp in activity mode
|
||||
await self._async_update_motion_temp()
|
||||
need_write_state = True
|
||||
|
||||
if self._presence_on:
|
||||
# try to acquire presence entity state
|
||||
presence_state = self.hass.states.get(self._presence_sensor_entity_id)
|
||||
if presence_state and presence_state.state not in (
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_UNKNOWN,
|
||||
):
|
||||
await self._async_update_presence(presence_state.state)
|
||||
_LOGGER.debug(
|
||||
"%s - Presence have been retrieved: %s",
|
||||
self,
|
||||
presence_state.state,
|
||||
)
|
||||
need_write_state = True
|
||||
|
||||
if need_write_state:
|
||||
self.async_write_ha_state()
|
||||
if self._prop_algorithm:
|
||||
self._prop_algorithm.calculate(
|
||||
self._target_temp,
|
||||
self._cur_temp,
|
||||
self._cur_ext_temp,
|
||||
self._hvac_mode or HVACMode.OFF,
|
||||
)
|
||||
|
||||
self.hass.create_task(self._check_initial_state())
|
||||
|
||||
self.reset_last_change_time()
|
||||
|
||||
# if self.hass.state == CoreState.running:
|
||||
# await _async_startup_internal()
|
||||
# else:
|
||||
# self.hass.bus.async_listen_once(
|
||||
# EVENT_HOMEASSISTANT_START, _async_startup_internal
|
||||
# )
|
||||
|
||||
def init_underlyings(self):
|
||||
"""Initialize all underlyings. Should be overriden if necessary"""
|
||||
|
||||
@@ -825,19 +828,20 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
# Never restore a Power or Security preset
|
||||
if old_preset_mode is not None and old_preset_mode not in HIDDEN_PRESETS:
|
||||
# old_preset_mode in self._attr_preset_modes
|
||||
self._attr_preset_mode = old_state.attributes.get(ATTR_PRESET_MODE)
|
||||
self._attr_preset_mode = old_preset_mode
|
||||
self.save_preset_mode()
|
||||
else:
|
||||
self._attr_preset_mode = PRESET_NONE
|
||||
|
||||
if not self._hvac_mode and old_state.state in [
|
||||
if old_state.state in [
|
||||
HVACMode.OFF,
|
||||
HVACMode.HEAT,
|
||||
HVACMode.COOL,
|
||||
]:
|
||||
self._hvac_mode = old_state.state
|
||||
else:
|
||||
self._hvac_mode = HVACMode.OFF
|
||||
if not self._hvac_mode:
|
||||
self._hvac_mode = HVACMode.OFF
|
||||
|
||||
old_total_energy = old_state.attributes.get(ATTR_TOTAL_ENERGY)
|
||||
if old_total_energy:
|
||||
@@ -2085,6 +2089,8 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
new_central_mode,
|
||||
)
|
||||
|
||||
first_init = self._last_central_mode == None
|
||||
|
||||
self._last_central_mode = new_central_mode
|
||||
|
||||
def save_all():
|
||||
@@ -2093,7 +2099,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
self.save_hvac_mode()
|
||||
|
||||
if new_central_mode == CENTRAL_MODE_AUTO:
|
||||
if self.window_state is not STATE_ON:
|
||||
if self.window_state is not STATE_ON and not first_init:
|
||||
await self.restore_hvac_mode()
|
||||
await self.restore_preset_mode()
|
||||
|
||||
@@ -2707,8 +2713,6 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
if self._attr_preset_mode:
|
||||
await self._async_set_preset_mode_internal(self._attr_preset_mode, True)
|
||||
|
||||
self.hass.create_task(self._check_initial_state())
|
||||
|
||||
async def async_turn_off(self) -> None:
|
||||
await self.async_set_hvac_mode(HVACMode.OFF)
|
||||
|
||||
|
||||
@@ -353,7 +353,7 @@ class CentralConfigTemperatureNumber(
|
||||
# We have to reload all VTherm for which uses the central configuration
|
||||
api: VersatileThermostatAPI = VersatileThermostatAPI.get_vtherm_api(self.hass)
|
||||
# Update the VTherms which have temperature in central config
|
||||
self.hass.create_task(api.init_vtherm_links(only_use_central=True))
|
||||
self.hass.create_task(api.init_vtherm_preset_with_central())
|
||||
|
||||
def __str__(self):
|
||||
return f"VersatileThermostat-{self.name}"
|
||||
|
||||
@@ -18,6 +18,9 @@ from custom_components.versatile_thermostat.base_thermostat import (
|
||||
BaseThermostat,
|
||||
ConfigData,
|
||||
)
|
||||
|
||||
from custom_components.versatile_thermostat.vtherm_api import VersatileThermostatAPI
|
||||
|
||||
from .const import (
|
||||
DOMAIN,
|
||||
DEVICE_MANUFACTURER,
|
||||
@@ -96,17 +99,20 @@ class CentralModeSelect(SelectEntity, RestoreEntity):
|
||||
if old_state is not None:
|
||||
self._attr_current_option = old_state.state
|
||||
|
||||
@callback
|
||||
async def _async_startup_internal(*_):
|
||||
_LOGGER.debug("%s - Calling async_startup_internal", self)
|
||||
await self.notify_central_mode_change()
|
||||
api: VersatileThermostatAPI = VersatileThermostatAPI.get_vtherm_api(self.hass)
|
||||
api.register_central_mode_select(self)
|
||||
|
||||
if self.hass.state == CoreState.running:
|
||||
await _async_startup_internal()
|
||||
else:
|
||||
self.hass.bus.async_listen_once(
|
||||
EVENT_HOMEASSISTANT_START, _async_startup_internal
|
||||
)
|
||||
# @callback
|
||||
# async def _async_startup_internal(*_):
|
||||
# _LOGGER.debug("%s - Calling async_startup_internal", self)
|
||||
# await self.notify_central_mode_change()
|
||||
#
|
||||
# if self.hass.state == CoreState.running:
|
||||
# await _async_startup_internal()
|
||||
# else:
|
||||
# self.hass.bus.async_listen_once(
|
||||
# EVENT_HOMEASSISTANT_START, _async_startup_internal
|
||||
# )
|
||||
|
||||
@overrides
|
||||
async def async_select_option(self, option: str) -> None:
|
||||
@@ -122,17 +128,9 @@ class CentralModeSelect(SelectEntity, RestoreEntity):
|
||||
|
||||
async def notify_central_mode_change(self, old_central_mode: str | None = None):
|
||||
"""Notify all VTherm that the central_mode have change"""
|
||||
api: VersatileThermostatAPI = VersatileThermostatAPI.get_vtherm_api(self.hass)
|
||||
# Update all VTherm states
|
||||
component: EntityComponent[ClimateEntity] = self.hass.data[CLIMATE_DOMAIN]
|
||||
for entity in component.entities:
|
||||
if isinstance(entity, BaseThermostat):
|
||||
_LOGGER.debug(
|
||||
"Changing the central_mode. We have find %s to update",
|
||||
entity.name,
|
||||
)
|
||||
await entity.check_central_mode(
|
||||
self._attr_current_option, old_central_mode
|
||||
)
|
||||
await api.notify_central_mode_change(old_central_mode)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"VersatileThermostat-{self.name}"
|
||||
|
||||
@@ -486,8 +486,8 @@ class UnderlyingClimate(UnderlyingEntity):
|
||||
self._underlying_climate,
|
||||
)
|
||||
else:
|
||||
_LOGGER.error(
|
||||
"%s - Cannot find the underlying climate entity: %s. Thermostat will not be operational",
|
||||
_LOGGER.info(
|
||||
"%s - Cannot find the underlying climate entity: %s. Thermostat will not be operational. Will try later.",
|
||||
self,
|
||||
self.entity_id,
|
||||
)
|
||||
@@ -780,15 +780,19 @@ class UnderlyingValve(UnderlyingEntity):
|
||||
"""Send the percent open to the underlying valve"""
|
||||
# This may fails if called after shutdown
|
||||
try:
|
||||
data = {ATTR_ENTITY_ID: self._entity_id, "value": self._percent_open}
|
||||
data = {"value": self._percent_open}
|
||||
target = {ATTR_ENTITY_ID: self._entity_id}
|
||||
domain = self._entity_id.split(".")[0]
|
||||
await self._hass.services.async_call(
|
||||
domain,
|
||||
SERVICE_SET_VALUE,
|
||||
data,
|
||||
domain=domain,
|
||||
service=SERVICE_SET_VALUE,
|
||||
service_data=data,
|
||||
target=target,
|
||||
)
|
||||
except ServiceNotFound as err:
|
||||
_LOGGER.error(err)
|
||||
# This could happens in unit test if input_number domain is not yet loaded
|
||||
# raise err
|
||||
|
||||
async def turn_off(self):
|
||||
"""Turn heater toggleable device off."""
|
||||
|
||||
@@ -57,6 +57,7 @@ class VersatileThermostatAPI(dict):
|
||||
self._threshold_number_entity = None
|
||||
self._nb_active_number_entity = None
|
||||
self._central_configuration = None
|
||||
self._central_mode_select = None
|
||||
# A dict that will store all Number entities which holds the temperature
|
||||
self._number_temperatures = dict()
|
||||
|
||||
@@ -149,8 +150,8 @@ class VersatileThermostatAPI(dict):
|
||||
return entity.state
|
||||
return None
|
||||
|
||||
async def init_vtherm_links(self, only_use_central=False):
|
||||
"""INitialize all VTherms entities links
|
||||
async def init_vtherm_links(self):
|
||||
"""Initialize all VTherms entities links
|
||||
This method is called when HA is fully started (and all entities should be initialized)
|
||||
Or when we need to reload all VTherm links (with Number temp entities, central boiler, ...)
|
||||
"""
|
||||
@@ -162,12 +163,34 @@ class VersatileThermostatAPI(dict):
|
||||
)
|
||||
if component:
|
||||
for entity in component.entities:
|
||||
if hasattr(entity, "init_presets"):
|
||||
if (
|
||||
only_use_central is False
|
||||
or entity.use_central_config_temperature
|
||||
):
|
||||
await entity.init_presets(self.find_central_configuration())
|
||||
# if hasattr(entity, "init_presets"):
|
||||
# if (
|
||||
# only_use_central is False
|
||||
# or entity.use_central_config_temperature
|
||||
# ):
|
||||
# await entity.init_presets(self.find_central_configuration())
|
||||
|
||||
# A little hack to test if the climate is a VTherm. Cannot use isinstance due to circular dependency of BaseThermostat
|
||||
if (
|
||||
entity.device_info
|
||||
and entity.device_info.get("model", None) == DOMAIN
|
||||
):
|
||||
await entity.async_startup(self.find_central_configuration())
|
||||
|
||||
async def init_vtherm_preset_with_central(self):
|
||||
"""Init all VTherm presets when the VTherm uses central temperature"""
|
||||
# Initialization of all preset for all VTherm
|
||||
component: EntityComponent[ClimateEntity] = self._hass.data.get(
|
||||
CLIMATE_DOMAIN, None
|
||||
)
|
||||
if component:
|
||||
for entity in component.entities:
|
||||
if (
|
||||
entity.device_info
|
||||
and entity.device_info.get("model", None) == DOMAIN
|
||||
and entity.use_central_config_temperature
|
||||
):
|
||||
await entity.init_presets(self.find_central_configuration())
|
||||
|
||||
async def reload_central_boiler_binary_listener(self):
|
||||
"""Reloads the BinarySensor entity which listen to the number of
|
||||
@@ -180,6 +203,27 @@ class VersatileThermostatAPI(dict):
|
||||
if self._nb_active_number_entity is not None:
|
||||
await self._nb_active_number_entity.listen_vtherms_entities()
|
||||
|
||||
def register_central_mode_select(self, central_mode_select):
|
||||
"""Register the select entity which holds the central_mode"""
|
||||
self._central_mode_select = central_mode_select
|
||||
|
||||
async def notify_central_mode_change(self, old_central_mode: str | None = None):
|
||||
"""Notify all VTherm that the central_mode have change"""
|
||||
if self._central_mode_select is None:
|
||||
return
|
||||
|
||||
# Update all VTherm states
|
||||
component: EntityComponent[ClimateEntity] = self.hass.data[CLIMATE_DOMAIN]
|
||||
for entity in component.entities:
|
||||
if entity.device_info and entity.device_info.get("model", None) == DOMAIN:
|
||||
_LOGGER.debug(
|
||||
"Changing the central_mode. We have find %s to update",
|
||||
entity.name,
|
||||
)
|
||||
await entity.check_central_mode(
|
||||
self._central_mode_select.state, old_central_mode
|
||||
)
|
||||
|
||||
@property
|
||||
def self_regulation_expert(self):
|
||||
"""Get the self regulation params"""
|
||||
@@ -229,6 +273,14 @@ class VersatileThermostatAPI(dict):
|
||||
return None
|
||||
return int(self._threshold_number_entity.native_value)
|
||||
|
||||
@property
|
||||
def central_mode(self) -> str | None:
|
||||
"""Get the current central mode or None"""
|
||||
if self._central_mode_select:
|
||||
return self._central_mode_select.state
|
||||
else:
|
||||
return None
|
||||
|
||||
@property
|
||||
def hass(self):
|
||||
"""Get the HomeAssistant object"""
|
||||
|
||||
@@ -181,14 +181,18 @@ async def test_over_valve_full_start(
|
||||
mock_service_call.assert_has_calls(
|
||||
[
|
||||
call.async_call(
|
||||
"number",
|
||||
"set_value",
|
||||
{"entity_id": "number.mock_valve", "value": 90},
|
||||
domain="number",
|
||||
service="set_value",
|
||||
service_data={"value": 90},
|
||||
target={"entity_id": "number.mock_valve"},
|
||||
# {"entity_id": "number.mock_valve", "value": 90},
|
||||
),
|
||||
call.async_call(
|
||||
"number",
|
||||
"set_value",
|
||||
{"entity_id": "number.mock_valve", "value": 98},
|
||||
domain="number",
|
||||
service="set_value",
|
||||
service_data={"value": 98},
|
||||
target={"entity_id": "number.mock_valve"},
|
||||
# {"entity_id": "number.mock_valve", "value": 98},
|
||||
),
|
||||
]
|
||||
)
|
||||
@@ -241,9 +245,10 @@ async def test_over_valve_full_start(
|
||||
mock_service_call.assert_has_calls(
|
||||
[
|
||||
call.async_call(
|
||||
"number",
|
||||
"set_value",
|
||||
{"entity_id": "number.mock_valve", "value": 10},
|
||||
domain="number",
|
||||
service="set_value",
|
||||
service_data={"value": 10},
|
||||
target={"entity_id": "number.mock_valve"},
|
||||
)
|
||||
]
|
||||
)
|
||||
@@ -254,20 +259,16 @@ async def test_over_valve_full_start(
|
||||
mock_service_call.assert_has_calls(
|
||||
[
|
||||
call.async_call(
|
||||
"number",
|
||||
"set_value",
|
||||
{
|
||||
"entity_id": "number.mock_valve",
|
||||
"value": 10,
|
||||
}, # the min allowed value
|
||||
domain="number",
|
||||
service="set_value",
|
||||
service_data={"value": 10},
|
||||
target={"entity_id": "number.mock_valve"}, # the min allowed value
|
||||
),
|
||||
call.async_call(
|
||||
"number",
|
||||
"set_value",
|
||||
{
|
||||
"entity_id": "number.mock_valve",
|
||||
"value": 50,
|
||||
}, # the max allowed value
|
||||
domain="number",
|
||||
service="set_value",
|
||||
service_data={"value": 50}, # the min allowed value
|
||||
target={"entity_id": "number.mock_valve"},
|
||||
),
|
||||
]
|
||||
)
|
||||
@@ -466,9 +467,10 @@ async def test_over_valve_regulation(
|
||||
mock_service_call.assert_has_calls(
|
||||
[
|
||||
call.async_call(
|
||||
"number",
|
||||
"set_value",
|
||||
{"entity_id": "number.mock_valve", "value": 90},
|
||||
domain="number",
|
||||
service="set_value",
|
||||
service_data={"value": 90},
|
||||
target={"entity_id": "number.mock_valve"},
|
||||
),
|
||||
]
|
||||
)
|
||||
@@ -524,9 +526,10 @@ async def test_over_valve_regulation(
|
||||
mock_service_call.assert_has_calls(
|
||||
[
|
||||
call.async_call(
|
||||
"number",
|
||||
"set_value",
|
||||
{"entity_id": "number.mock_valve", "value": 96},
|
||||
domain="number",
|
||||
service="set_value",
|
||||
service_data={"value": 96},
|
||||
target={"entity_id": "number.mock_valve"},
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user