Compare commits

..

12 Commits

Author SHA1 Message Date
Jean-Marc Collin
f0a85c10ff Fix underlying target is not updated 2024-11-20 06:45:41 +00:00
Jean-Marc Collin
592b2ca574 Fix hvac_action
Fix offset_calibration=room_temp - (local_temp - current_offset)
2024-11-19 19:32:20 +00:00
Jean-Marc Collin
9102b09691 Calculate offset_calibration as room_temp - local_temp
Fix hvac_action calculation
2024-11-19 06:58:20 +00:00
Jean-Marc Collin
5b64a8fba0 Add #602 - implement a max_on_percent setting 2024-11-18 10:04:04 +00:00
Jean-Marc Collin
14bb7474ae Fix release name 2024-11-18 10:04:04 +00:00
Jean-Marc Collin
bc1c18d719 Release 2024-11-18 10:04:03 +00:00
Jean-Marc Collin
c935ee3af5 Fix Testus 2024-11-18 10:04:02 +00:00
Jean-Marc Collin
ce73f1275b Work in simuated environment 2024-11-18 10:04:01 +00:00
Jean-Marc Collin
cd08dca913 With 1rst implementation of VTherm TRVZB and underlying 2024-11-18 10:02:18 +00:00
Jean-Marc Collin
93079e974f Next (not finished) 2024-11-18 10:02:17 +00:00
Jean-Marc Collin
db38392dab Fix configuration 2024-11-18 10:02:16 +00:00
Jean-Marc Collin
ac705df862 With Sonoff configuration ok 2024-11-18 10:02:15 +00:00
224 changed files with 3745 additions and 9156 deletions

File diff suppressed because it is too large Load Diff

1690
README.md

File diff suppressed because it is too large Load Diff

View File

@@ -57,13 +57,10 @@ class AutoStartStopDetectionAlgorithm:
_accumulated_error: float = 0
_error_threshold: float | None = None
_last_calculation_date: datetime | None = None
_last_switch_date: datetime | None = None
def __init__(self, level: TYPE_AUTO_START_STOP_LEVELS, vtherm_name) -> None:
"""Initalize a new algorithm with the right constants"""
self._vtherm_name = vtherm_name
self._last_calculation_date = None
self._last_switch_date = None
self._init_level(level)
def _init_level(self, level: TYPE_AUTO_START_STOP_LEVELS):
@@ -146,26 +143,17 @@ class AutoStartStopDetectionAlgorithm:
temp_at_dt = current_temp + slope_min * self._dt
# Calculate the number of minute from last_switch
nb_minutes_since_last_switch = 999
if self._last_switch_date is not None:
nb_minutes_since_last_switch = (
now - self._last_switch_date
).total_seconds() / 60
# Check to turn-off
# When we hit the threshold, that mean we can turn off
if hvac_mode == HVACMode.HEAT:
if (
self._accumulated_error <= -self._error_threshold
and temp_at_dt >= target_temp + TEMP_HYSTERESIS
and nb_minutes_since_last_switch >= self._dt
):
_LOGGER.info(
"%s - We need to stop, there is no need for heating for a long time.",
self,
)
self._last_switch_date = now
return AUTO_START_STOP_ACTION_OFF
else:
_LOGGER.debug("%s - nothing to do, we are heating", self)
@@ -175,13 +163,11 @@ class AutoStartStopDetectionAlgorithm:
if (
self._accumulated_error >= self._error_threshold
and temp_at_dt <= target_temp - TEMP_HYSTERESIS
and nb_minutes_since_last_switch >= self._dt
):
_LOGGER.info(
"%s - We need to stop, there is no need for cooling for a long time.",
self,
)
self._last_switch_date = now
return AUTO_START_STOP_ACTION_OFF
else:
_LOGGER.debug(
@@ -192,15 +178,11 @@ class AutoStartStopDetectionAlgorithm:
# check to turn on
if hvac_mode == HVACMode.OFF and saved_hvac_mode == HVACMode.HEAT:
if (
temp_at_dt <= target_temp - TEMP_HYSTERESIS
and nb_minutes_since_last_switch >= self._dt
):
if temp_at_dt <= target_temp - TEMP_HYSTERESIS:
_LOGGER.info(
"%s - We need to start, because it will be time to heat",
self,
)
self._last_switch_date = now
return AUTO_START_STOP_ACTION_ON
else:
_LOGGER.debug(
@@ -210,15 +192,11 @@ class AutoStartStopDetectionAlgorithm:
return AUTO_START_STOP_ACTION_NOTHING
if hvac_mode == HVACMode.OFF and saved_hvac_mode == HVACMode.COOL:
if (
temp_at_dt >= target_temp + TEMP_HYSTERESIS
and nb_minutes_since_last_switch >= self._dt
):
if temp_at_dt >= target_temp + TEMP_HYSTERESIS:
_LOGGER.info(
"%s - We need to start, because it will be time to cool",
self,
)
self._last_switch_date = now
return AUTO_START_STOP_ACTION_ON
else:
_LOGGER.debug(
@@ -257,10 +235,5 @@ class AutoStartStopDetectionAlgorithm:
"""Get the level value"""
return self._level
@property
def last_switch_date(self) -> datetime | None:
"""Get the last of the last switch"""
return self._last_switch_date
def __str__(self) -> str:
return f"AutoStartStopDetectionAlgorithm-{self._vtherm_name}"

View File

@@ -9,6 +9,7 @@ from datetime import timedelta, datetime
from types import MappingProxyType
from typing import Any, TypeVar, Generic
from homeassistant.util import dt as dt_util
from homeassistant.core import (
HomeAssistant,
callback,
@@ -79,6 +80,13 @@ _LOGGER = logging.getLogger(__name__)
ConfigData = MappingProxyType[str, Any]
T = TypeVar("T", bound=UnderlyingEntity)
def get_tz(hass: HomeAssistant):
"""Get the current timezone"""
return dt_util.get_time_zone(hass.config.time_zone)
class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
"""Representation of a base class for all Versatile Thermostat device."""
@@ -127,12 +135,10 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
"max_power_sensor_entity_id",
"temperature_unit",
"is_device_active",
"nb_device_actives",
"target_temperature_step",
"is_used_by_central_boiler",
"temperature_slope",
"max_on_percent",
"have_valve_regulation",
"max_on_percent"
}
)
)
@@ -454,8 +460,8 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
else DEFAULT_SECURITY_DEFAULT_ON_PERCENT
)
self._minimal_activation_delay = entry_infos.get(CONF_MINIMAL_ACTIVATION_DELAY)
self._last_temperature_measure = self.now
self._last_ext_temperature_measure = self.now
self._last_temperature_measure = datetime.now(tz=self._current_tz)
self._last_ext_temperature_measure = datetime.now(tz=self._current_tz)
self._security_state = False
# Initiate the ProportionalAlgorithm
@@ -996,15 +1002,6 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
return True
return False
@property
def nb_device_actives(self) -> int:
"""Calculate the number of active devices"""
ret = 0
for under in self._underlyings:
if under.is_device_active:
ret += 1
return ret
@property
def current_temperature(self) -> float | None:
"""Return the sensor temperature."""
@@ -1132,11 +1129,6 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
"""Returns the underlying entities"""
return self._underlyings
@property
def activable_underlying_entities(self) -> list | None:
"""Returns the activable underlying entities for controling the central boiler"""
return self.underlying_entities
def find_underlying_by_entity_id(self, entity_id: str) -> Entity | None:
"""Get the underlying entity by a entity_id"""
for under in self._underlyings:
@@ -1329,8 +1321,8 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
self._attr_preset_mode = PRESET_ACTIVITY
await self._async_update_motion_temp()
else:
# if self._attr_preset_mode == PRESET_NONE:
# self._saved_target_temp = self._target_temp
if self._attr_preset_mode == PRESET_NONE:
self._saved_target_temp = self._target_temp
self._attr_preset_mode = preset_mode
await self._async_internal_set_temperature(
self.find_preset_temp(preset_mode)
@@ -1350,7 +1342,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
self, old_preset_mode: str | None = None
): # pylint: disable=unused-argument
"""Reset to now the last change time"""
self._last_change_time = self.now
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: str | None = None):
@@ -1360,7 +1352,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
and old_preset_mode not in HIDDEN_PRESETS
):
self._last_temperature_measure = self._last_ext_temperature_measure = (
self.now
datetime.now(tz=self._current_tz)
)
def find_preset_temp(self, preset_mode: str):
@@ -1393,10 +1385,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
)
if motion_preset in self._presets:
if self._presence_on and self.presence_state in [STATE_OFF, None]:
return self._presets_away[motion_preset + PRESET_AWAY_SUFFIX]
else:
return self._presets[motion_preset]
return self._presets[motion_preset]
else:
return None
else:
@@ -1466,16 +1455,16 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
"""Extract the last_changed state from State or return now if not available"""
return (
state.last_changed.astimezone(self._current_tz)
if isinstance(state.last_changed, datetime)
else self.now
if state.last_changed is not None
else datetime.now(tz=self._current_tz)
)
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)
if isinstance(state.last_updated, datetime)
else self.now
if state.last_updated is not None
else datetime.now(tz=self._current_tz)
)
@callback
@@ -1917,12 +1906,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
STATE_NOT_HOME,
):
return
if self._attr_preset_mode not in [
PRESET_BOOST,
PRESET_COMFORT,
PRESET_ECO,
PRESET_ACTIVITY,
]:
if self._attr_preset_mode not in [PRESET_BOOST, PRESET_COMFORT, PRESET_ECO]:
return
new_temp = self.find_preset_temp(self.preset_mode)
@@ -2012,7 +1996,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
if in_cycle:
slope = self._window_auto_algo.check_age_last_measurement(
temperature=self._ema_temp,
datetime_now=self.now,
datetime_now=datetime.now(get_tz(self._hass)),
)
else:
slope = self._window_auto_algo.add_temp_measurement(
@@ -2300,11 +2284,10 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
@property
def now(self) -> datetime:
"""Get now. The local datetime or the overloaded _set_now date"""
return self._now if self._now is not None else NowClass.get_now(self._hass)
return self._now if self._now is not None else datetime.now(self._current_tz)
async def check_safety(self) -> bool:
"""Check if last temperature date is too long"""
now = self.now
delta_temp = (
now - self._last_temperature_measure.replace(tzinfo=self._current_tz)
@@ -2500,7 +2483,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
)
else:
_LOGGER.info(
"%s - Window is open. Apply window action %s", self, self._window_action
"%s - Window is open. Set hvac_mode to '%s'", self, HVACMode.OFF
)
if self._window_action == CONF_WINDOW_TURN_OFF and not self.is_on:
_LOGGER.debug(
@@ -2672,17 +2655,17 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
"device_power": self._device_power,
ATTR_MEAN_POWER_CYCLE: self.mean_cycle_power,
ATTR_TOTAL_ENERGY: self.total_energy,
"last_update_datetime": self.now.isoformat(),
"last_update_datetime": datetime.now()
.astimezone(self._current_tz)
.isoformat(),
"timezone": str(self._current_tz),
"temperature_unit": self.temperature_unit,
"is_device_active": self.is_device_active,
"nb_device_actives": self.nb_device_actives,
"ema_temp": self._ema_temp,
"is_used_by_central_boiler": self.is_used_by_central_boiler,
"temperature_slope": round(self.last_temperature_slope or 0, 3),
"hvac_off_reason": self.hvac_off_reason,
"max_on_percent": self._max_on_percent,
"have_valve_regulation": self.have_valve_regulation,
}
_LOGGER.debug(
@@ -2701,11 +2684,6 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
)
return super().async_write_ha_state()
@property
def have_valve_regulation(self) -> bool:
"""True if the Thermostat is regulated by valve"""
return False
@callback
def async_registry_entry_updated(self):
"""update the entity if the config entry have been updated

View File

@@ -108,7 +108,7 @@ class SecurityBinarySensor(VersatileThermostatBaseEntity, BinarySensorEntity):
@callback
async def async_my_climate_changed(self, event: Event = None):
"""Called when my climate have change"""
# _LOGGER.debug("%s - climate state change", self._attr_unique_id)
_LOGGER.debug("%s - climate state change", self._attr_unique_id)
old_state = self._attr_is_on
self._attr_is_on = self.my_climate.security_state is True
@@ -147,7 +147,7 @@ class OverpoweringBinarySensor(VersatileThermostatBaseEntity, BinarySensorEntity
@callback
async def async_my_climate_changed(self, event: Event = None):
"""Called when my climate have change"""
# _LOGGER.debug("%s - climate state change", self._attr_unique_id)
_LOGGER.debug("%s - climate state change", self._attr_unique_id)
old_state = self._attr_is_on
self._attr_is_on = self.my_climate.overpowering_state is True
@@ -186,7 +186,7 @@ class WindowBinarySensor(VersatileThermostatBaseEntity, BinarySensorEntity):
@callback
async def async_my_climate_changed(self, event: Event = None):
"""Called when my climate have change"""
# _LOGGER.debug("%s - climate state change", self._attr_unique_id)
_LOGGER.debug("%s - climate state change", self._attr_unique_id)
old_state = self._attr_is_on
# Issue 120 - only take defined presence value
@@ -236,7 +236,7 @@ class MotionBinarySensor(VersatileThermostatBaseEntity, BinarySensorEntity):
@callback
async def async_my_climate_changed(self, event: Event = None):
"""Called when my climate have change"""
# _LOGGER.debug("%s - climate state change", self._attr_unique_id)
_LOGGER.debug("%s - climate state change", self._attr_unique_id)
old_state = self._attr_is_on
# Issue 120 - only take defined presence value
if self.my_climate.motion_state in [STATE_ON, STATE_OFF]:
@@ -277,7 +277,7 @@ class PresenceBinarySensor(VersatileThermostatBaseEntity, BinarySensorEntity):
async def async_my_climate_changed(self, event: Event = None):
"""Called when my climate have change"""
# _LOGGER.debug("%s - climate state change", self._attr_unique_id)
_LOGGER.debug("%s - climate state change", self._attr_unique_id)
old_state = self._attr_is_on
# Issue 120 - only take defined presence value
if self.my_climate.presence_state in [STATE_ON, STATE_OFF]:
@@ -317,7 +317,7 @@ class WindowByPassBinarySensor(VersatileThermostatBaseEntity, BinarySensorEntity
@callback
async def async_my_climate_changed(self, event: Event = None):
"""Called when my climate have change"""
# _LOGGER.debug("%s - climate state change", self._attr_unique_id)
_LOGGER.debug("%s - climate state change", self._attr_unique_id)
old_state = self._attr_is_on
if self.my_climate.window_bypass_state in [True, False]:
self._attr_is_on = self.my_climate.window_bypass_state

View File

@@ -22,12 +22,28 @@ from homeassistant.const import (
STATE_NOT_HOME,
)
from .const import * # pylint: disable=wildcard-import,unused-wildcard-import
from .const import (
DOMAIN,
PLATFORMS,
CONF_PRESETS_WITH_AC,
SERVICE_SET_PRESENCE,
SERVICE_SET_PRESET_TEMPERATURE,
SERVICE_SET_SECURITY,
SERVICE_SET_WINDOW_BYPASS,
SERVICE_SET_AUTO_REGULATION_MODE,
SERVICE_SET_AUTO_FAN_MODE,
CONF_THERMOSTAT_TYPE,
CONF_THERMOSTAT_SWITCH,
CONF_THERMOSTAT_CLIMATE,
CONF_THERMOSTAT_VALVE,
CONF_THERMOSTAT_CENTRAL_CONFIG,
CONF_SONOFF_TRZB_MODE,
)
from .thermostat_switch import ThermostatOverSwitch
from .thermostat_climate import ThermostatOverClimate
from .thermostat_valve import ThermostatOverValve
from .thermostat_climate_valve import ThermostatOverClimateValve
from .thermostat_sonoff_trvzb import ThermostatOverSonoffTRVZB
_LOGGER = logging.getLogger(__name__)
@@ -46,9 +62,7 @@ async def async_setup_entry(
unique_id = entry.entry_id
name = entry.data.get(CONF_NAME)
vt_type = entry.data.get(CONF_THERMOSTAT_TYPE)
have_valve_regulation = (
entry.data.get(CONF_AUTO_REGULATION_MODE) == CONF_AUTO_REGULATION_VALVE
)
is_sonoff_trvzb = entry.data.get(CONF_SONOFF_TRZB_MODE)
if vt_type == CONF_THERMOSTAT_CENTRAL_CONFIG:
return
@@ -58,8 +72,8 @@ async def async_setup_entry(
if vt_type == CONF_THERMOSTAT_SWITCH:
entity = ThermostatOverSwitch(hass, unique_id, name, entry.data)
elif vt_type == CONF_THERMOSTAT_CLIMATE:
if have_valve_regulation is True:
entity = ThermostatOverClimateValve(hass, unique_id, name, entry.data)
if is_sonoff_trvzb is True:
entity = ThermostatOverSonoffTRVZB(hass, unique_id, name, entry.data)
else:
entity = ThermostatOverClimate(hass, unique_id, name, entry.data)
elif vt_type == CONF_THERMOSTAT_VALVE:

View File

@@ -3,20 +3,38 @@
# pylint: disable=line-too-long
import logging
from datetime import timedelta
from datetime import timedelta, datetime
from homeassistant.core import HomeAssistant, callback, Event
from homeassistant.components.climate import ClimateEntity, DOMAIN as CLIMATE_DOMAIN
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.device_registry import DeviceInfo, DeviceEntryType
from homeassistant.helpers.event import async_track_state_change_event, async_call_later
from homeassistant.util import dt as dt_util
from .base_thermostat import BaseThermostat
from .const import DOMAIN, DEVICE_MANUFACTURER, ServiceConfigurationError
_LOGGER = logging.getLogger(__name__)
def get_tz(hass: HomeAssistant):
"""Get the current timezone"""
return dt_util.get_time_zone(hass.config.time_zone)
class NowClass:
"""For testing purpose only"""
@staticmethod
def get_now(hass: HomeAssistant) -> datetime:
"""A test function to get the now.
For testing purpose this method can be overriden to get a specific
timestamp.
"""
return datetime.now(get_tz(hass))
def round_to_nearest(n: float, x: float) -> float:
"""Round a number to the nearest x (which should be decimal but not null)
Example:

View File

@@ -29,6 +29,27 @@ COMES_FROM = "comes_from"
_LOGGER = logging.getLogger(__name__)
# Not used but can be useful in other context
# def schema_defaults(schema, **defaults):
# """Create a new schema with default values filled in."""
# copy = schema.extend({})
# for field, field_type in copy.schema.items():
# if isinstance(field_type, vol.In):
# value = None
#
# if value in field_type.container:
# # field.default = vol.default_factory(value)
# field.description = {"suggested_value": value}
# continue
#
# if field.schema in defaults:
# # field.default = vol.default_factory(defaults[field])
# field.description = {"suggested_value": defaults[field]}
# return copy
#
def add_suggested_values_to_schema(
data_schema: vol.Schema, suggested_values: Mapping[str, Any]
) -> vol.Schema:
@@ -56,6 +77,7 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
VERSION = CONFIG_VERSION
MINOR_VERSION = CONFIG_MINOR_VERSION
_infos: dict
_placeholders = {
CONF_NAME: "",
}
@@ -63,7 +85,7 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
def __init__(self, infos) -> None:
super().__init__()
_LOGGER.debug("CTOR BaseConfigFlow infos: %s", infos)
self._infos: dict = infos
self._infos = infos
# VTherm API should have been initialized before arriving here
vtherm_api = VersatileThermostatAPI.get_vtherm_api()
@@ -72,8 +94,8 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
else:
self._central_config = None
self._init_central_config_flags(infos)
self._init_feature_flags(infos)
self._init_central_config_flags(infos)
def _init_feature_flags(self, _):
"""Fix features selection depending to infos"""
@@ -140,40 +162,21 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
if COMES_FROM in self._infos:
del self._infos[COMES_FROM]
def is_valve_regulation_selected(self, infos) -> bool:
"""True of the valve regulation mode is selected"""
return infos.get(CONF_AUTO_REGULATION_MODE, None) == CONF_AUTO_REGULATION_VALVE
def check_valve_regulation_nb_entities(self, data: dict, step_id=None) -> bool:
"""Check the number of entities for Valve regulation"""
if step_id not in ["type", "valve_regulation", "check_complete"]:
return True
underlyings_to_check = data if step_id == "type" else self._infos
# underlyings_to_check = self._infos # data if step_id == "type" else self._infos
regulation_infos_to_check = (
data if step_id == "valve_regulation" else self._infos
)
def check_sonoff_trvzb_nb_entities(self, data: dict) -> bool:
"""Check the number of entities for Sonoff TRVZB"""
ret = True
if (
self.is_valve_regulation_selected(underlyings_to_check)
and step_id != "type"
self._infos.get(CONF_SONOFF_TRZB_MODE)
and data.get(CONF_OFFSET_CALIBRATION_LIST) is not None
):
nb_unders = len(underlyings_to_check.get(CONF_UNDERLYING_LIST))
nb_offset = len(
regulation_infos_to_check.get(CONF_OFFSET_CALIBRATION_LIST, [])
)
nb_opening = len(
regulation_infos_to_check.get(CONF_OPENING_DEGREE_LIST, [])
)
nb_closing = len(
regulation_infos_to_check.get(CONF_CLOSING_DEGREE_LIST, [])
)
nb_unders = len(self._infos.get(CONF_UNDERLYING_LIST))
nb_offset = len(data.get(CONF_OFFSET_CALIBRATION_LIST))
nb_opening = len(data.get(CONF_OPENING_DEGREE_LIST))
nb_closing = len(data.get(CONF_CLOSING_DEGREE_LIST))
if (
nb_unders != nb_opening
or (nb_unders != nb_offset and nb_offset > 0)
or (nb_unders != nb_closing and nb_closing > 0)
nb_unders != nb_offset
or nb_unders != nb_opening
or nb_unders != nb_closing
):
ret = False
return ret
@@ -256,8 +259,8 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
# Check that the number of offet_calibration and opening_degree and closing_degree are equals
# to the number of underlying entities
if not self.check_valve_regulation_nb_entities(data, step_id):
raise ValveRegulationNbEntitiesIncorrect()
if not self.check_sonoff_trvzb_nb_entities(data):
raise SonoffTRVZBNbEntitiesIncorrect()
def check_config_complete(self, infos) -> bool:
"""True if the config is now complete (ie all mandatory attributes are set)"""
@@ -354,7 +357,7 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
):
return False
if not self.check_valve_regulation_nb_entities(infos, "check_complete"):
if not self.check_sonoff_trvzb_nb_entities(infos):
return False
return True
@@ -397,8 +400,8 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
errors[str(err)] = "service_configuration_format"
except ConfigurationNotCompleteError as err:
errors["base"] = "configuration_not_complete"
except ValveRegulationNbEntitiesIncorrect as err:
errors["base"] = "valve_regulation_nb_entities_incorrect"
except SonoffTRVZBNbEntitiesIncorrect as err:
errors["base"] = "sonoff_trvzb_nb_entities_incorrect"
except Exception: # pylint: disable=broad-except
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
@@ -450,7 +453,6 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
if (
self._infos.get(CONF_PROP_FUNCTION) == PROPORTIONAL_FUNCTION_TPI
or is_central_config
or self.is_valve_regulation_selected(self._infos)
):
menu_options.append("tpi")
@@ -486,8 +488,8 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
]:
menu_options.append("auto_start_stop")
if self.is_valve_regulation_selected(self._infos):
menu_options.append("valve_regulation")
if self._infos.get(CONF_SONOFF_TRZB_MODE) is True:
menu_options.append("sonoff_trvzb")
menu_options.append("advanced")
@@ -561,10 +563,11 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
if (
self._infos[CONF_THERMOSTAT_TYPE] == CONF_THERMOSTAT_CLIMATE
and user_input is not None
and not self.is_valve_regulation_selected(user_input)
and not user_input.get(CONF_SONOFF_TRZB_MODE)
):
# Remove TPI info
for key in [
PROPORTIONAL_FUNCTION_TPI,
CONF_PROP_FUNCTION,
CONF_TPI_COEF_INT,
CONF_TPI_COEF_EXT,
@@ -618,21 +621,19 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
return await self.generic_step("auto_start_stop", schema, user_input, next_step)
async def async_step_valve_regulation(
async def async_step_sonoff_trvzb(
self, user_input: dict | None = None
) -> FlowResult:
"""Handle the valve regulation configuration step"""
"""Handle the Sonoff TRVZB configuration step"""
_LOGGER.debug(
"Into ConfigFlow.async_step_valve_regulation user_input=%s", user_input
"Into ConfigFlow.async_step_sonoff_trvzb user_input=%s", user_input
)
schema = STEP_VALVE_REGULATION
schema = STEP_SONOFF_TRVZB
self._infos[COMES_FROM] = None
next_step = self.async_step_menu
return await self.generic_step(
"valve_regulation", schema, user_input, next_step
)
return await self.generic_step("sonoff_trvzb", schema, user_input, next_step)
async def async_step_tpi(self, user_input: dict | None = None) -> FlowResult:
"""Handle the TPI flow steps"""

View File

@@ -141,6 +141,7 @@ STEP_THERMOSTAT_CLIMATE = vol.Schema( # pylint: disable=invalid-name
selector.EntitySelectorConfig(domain=CLIMATE_DOMAIN, multiple=True),
),
vol.Optional(CONF_AC_MODE, default=False): cv.boolean,
vol.Optional(CONF_SONOFF_TRZB_MODE, default=False): cv.boolean,
vol.Optional(
CONF_AUTO_REGULATION_MODE, default=CONF_AUTO_REGULATION_NONE
): selector.SelectSelector(
@@ -197,19 +198,19 @@ STEP_AUTO_START_STOP = vol.Schema( # pylint: disable=invalid-name
}
)
STEP_VALVE_REGULATION = vol.Schema( # pylint: disable=invalid-name
STEP_SONOFF_TRVZB = vol.Schema( # pylint: disable=invalid-name
{
vol.Required(CONF_OFFSET_CALIBRATION_LIST): selector.EntitySelector(
selector.EntitySelectorConfig(
domain=[NUMBER_DOMAIN, INPUT_NUMBER_DOMAIN], multiple=True
),
),
vol.Required(CONF_OPENING_DEGREE_LIST): selector.EntitySelector(
selector.EntitySelectorConfig(
domain=[NUMBER_DOMAIN, INPUT_NUMBER_DOMAIN], multiple=True
),
),
vol.Optional(CONF_OFFSET_CALIBRATION_LIST): selector.EntitySelector(
selector.EntitySelectorConfig(
domain=[NUMBER_DOMAIN, INPUT_NUMBER_DOMAIN], multiple=True
),
),
vol.Optional(CONF_CLOSING_DEGREE_LIST): selector.EntitySelector(
vol.Required(CONF_CLOSING_DEGREE_LIST): selector.EntitySelector(
selector.EntitySelectorConfig(
domain=[NUMBER_DOMAIN, INPUT_NUMBER_DOMAIN], multiple=True
),
@@ -230,16 +231,8 @@ STEP_TPI_DATA_SCHEMA = vol.Schema( # pylint: disable=invalid-name
STEP_CENTRAL_TPI_DATA_SCHEMA = vol.Schema( # pylint: disable=invalid-name
{
vol.Required(CONF_TPI_COEF_INT, default=0.6): selector.NumberSelector(
selector.NumberSelectorConfig(
min=0.0, max=1.0, step=0.01, mode=selector.NumberSelectorMode.BOX
)
),
vol.Required(CONF_TPI_COEF_EXT, default=0.01): selector.NumberSelector(
selector.NumberSelectorConfig(
min=0.0, max=1.0, step=0.01, mode=selector.NumberSelectorMode.BOX
)
),
vol.Required(CONF_TPI_COEF_INT, default=0.6): vol.Coerce(float),
vol.Required(CONF_TPI_COEF_EXT, default=0.01): vol.Coerce(float),
}
)

View File

@@ -4,10 +4,8 @@
import logging
import math
from typing import Literal
from datetime import datetime
from enum import Enum
from homeassistant.core import HomeAssistant
from homeassistant.const import CONF_NAME, Platform
from homeassistant.components.climate import (
@@ -19,7 +17,6 @@ from homeassistant.components.climate import (
)
from homeassistant.exceptions import HomeAssistantError
from homeassistant.util import dt as dt_util
from .prop_algorithm import (
PROPORTIONAL_FUNCTION_TPI,
@@ -98,12 +95,12 @@ CONF_USE_POWER_FEATURE = "use_power_feature"
CONF_USE_CENTRAL_BOILER_FEATURE = "use_central_boiler_feature"
CONF_USE_AUTO_START_STOP_FEATURE = "use_auto_start_stop_feature"
CONF_AC_MODE = "ac_mode"
CONF_SONOFF_TRZB_MODE = "sonoff_trvzb_mode"
CONF_WINDOW_AUTO_OPEN_THRESHOLD = "window_auto_open_threshold"
CONF_WINDOW_AUTO_CLOSE_THRESHOLD = "window_auto_close_threshold"
CONF_WINDOW_AUTO_MAX_DURATION = "window_auto_max_duration"
CONF_AUTO_REGULATION_MODE = "auto_regulation_mode"
CONF_AUTO_REGULATION_NONE = "auto_regulation_none"
CONF_AUTO_REGULATION_VALVE = "auto_regulation_valve"
CONF_AUTO_REGULATION_SLOW = "auto_regulation_slow"
CONF_AUTO_REGULATION_LIGHT = "auto_regulation_light"
CONF_AUTO_REGULATION_MEDIUM = "auto_regulation_medium"
@@ -296,6 +293,7 @@ ALL_CONF = (
CONF_USE_POWER_FEATURE,
CONF_USE_CENTRAL_BOILER_FEATURE,
CONF_AC_MODE,
CONF_SONOFF_TRZB_MODE,
CONF_AUTO_REGULATION_MODE,
CONF_AUTO_REGULATION_DTEMP,
CONF_AUTO_REGULATION_PERIOD_MIN,
@@ -329,7 +327,6 @@ CONF_FUNCTIONS = [
CONF_AUTO_REGULATION_MODES = [
CONF_AUTO_REGULATION_NONE,
CONF_AUTO_REGULATION_VALVE,
CONF_AUTO_REGULATION_LIGHT,
CONF_AUTO_REGULATION_MEDIUM,
CONF_AUTO_REGULATION_STRONG,
@@ -509,24 +506,6 @@ def get_safe_float(hass, entity_id: str):
return None if math.isinf(float_val) or not math.isfinite(float_val) else float_val
def get_tz(hass: HomeAssistant):
"""Get the current timezone"""
return dt_util.get_time_zone(hass.config.time_zone)
class NowClass:
"""For testing purpose only"""
@staticmethod
def get_now(hass: HomeAssistant) -> datetime:
"""A test function to get the now.
For testing purpose this method can be overriden to get a specific
timestamp.
"""
return datetime.now(get_tz(hass))
class UnknownEntity(HomeAssistantError):
"""Error to indicate there is an unknown entity_id given."""
@@ -547,8 +526,8 @@ class ConfigurationNotCompleteError(HomeAssistantError):
"""Error the configuration is not complete"""
class ValveRegulationNbEntitiesIncorrect(HomeAssistantError):
"""Error to indicate there is an error in the configuration of the TRV with valve regulation.
class SonoffTRVZBNbEntitiesIncorrect(HomeAssistantError):
"""Error to indicate there is an error in the configuration of the Sonoff TRVZB.
The number of specific entities is incorrect."""

View File

@@ -26,14 +26,20 @@ MIN_NB_POINT = 4 # do not calculate slope until we have enough point
class WindowOpenDetectionAlgorithm:
"""The class that implements the algorithm listed above"""
_alert_threshold: float
_end_alert_threshold: float
_last_slope: float
_last_datetime: datetime
_last_temperature: float
_nb_point: int
def __init__(self, alert_threshold, end_alert_threshold) -> None:
"""Initalize a new algorithm with the both threshold"""
self._alert_threshold: float = alert_threshold
self._end_alert_threshold: float = end_alert_threshold
self._last_slope: float | None = None
self._last_datetime: datetime = None
self._last_temperature: float | None = None
self._nb_point: int = 0
self._alert_threshold = alert_threshold
self._end_alert_threshold = end_alert_threshold
self._last_slope = None
self._last_datetime = None
self._nb_point = 0
def check_age_last_measurement(self, temperature, datetime_now) -> float:
""" " Check if last measurement is old and add

View File

@@ -3,7 +3,7 @@
import logging
import math
from homeassistant.core import HomeAssistant, callback, Event, CoreState, State
from homeassistant.core import HomeAssistant, callback, Event, CoreState
from homeassistant.const import (
UnitOfTime,
@@ -23,13 +23,13 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.device_registry import DeviceInfo, DeviceEntryType
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.event import (
async_track_state_change_event,
)
from homeassistant.helpers.event import async_track_state_change_event
from homeassistant.components.climate import (
ClimateEntity,
DOMAIN as CLIMATE_DOMAIN,
HVACAction,
HVACMode,
)
@@ -49,8 +49,7 @@ from .const import (
CONF_THERMOSTAT_TYPE,
CONF_THERMOSTAT_CENTRAL_CONFIG,
CONF_USE_CENTRAL_BOILER_FEATURE,
CONF_AUTO_REGULATION_VALVE,
CONF_AUTO_REGULATION_MODE,
CONF_SONOFF_TRZB_MODE,
overrides,
)
@@ -72,9 +71,7 @@ async def async_setup_entry(
unique_id = entry.entry_id
name = entry.data.get(CONF_NAME)
vt_type = entry.data.get(CONF_THERMOSTAT_TYPE)
have_valve_regulation = (
entry.data.get(CONF_AUTO_REGULATION_MODE) == CONF_AUTO_REGULATION_VALVE
)
is_sonoff_trvzb = entry.data.get(CONF_SONOFF_TRZB_MODE)
entities = None
@@ -105,13 +102,13 @@ async def async_setup_entry(
if (
entry.data.get(CONF_THERMOSTAT_TYPE) == CONF_THERMOSTAT_VALVE
or have_valve_regulation
or is_sonoff_trvzb
):
entities.append(ValveOpenPercentSensor(hass, unique_id, name, entry.data))
if (
entry.data.get(CONF_THERMOSTAT_TYPE) == CONF_THERMOSTAT_CLIMATE
and not have_valve_regulation
and not is_sonoff_trvzb
):
entities.append(
RegulatedTemperatureSensor(hass, unique_id, name, entry.data)
@@ -133,7 +130,7 @@ class EnergySensor(VersatileThermostatBaseEntity, SensorEntity):
@callback
async def async_my_climate_changed(self, event: Event = None):
"""Called when my climate have change"""
# _LOGGER.debug("%s - climate state change", self._attr_unique_id)
_LOGGER.debug("%s - climate state change", self._attr_unique_id)
energy = self.my_climate.total_energy
if energy is None:
@@ -188,7 +185,7 @@ class MeanPowerSensor(VersatileThermostatBaseEntity, SensorEntity):
@callback
async def async_my_climate_changed(self, event: Event = None):
"""Called when my climate have change"""
# _LOGGER.debug("%s - climate state change", self._attr_unique_id)
_LOGGER.debug("%s - climate state change", self._attr_unique_id)
if math.isnan(float(self.my_climate.mean_cycle_power)) or math.isinf(
self.my_climate.mean_cycle_power
@@ -245,7 +242,7 @@ class OnPercentSensor(VersatileThermostatBaseEntity, SensorEntity):
@callback
async def async_my_climate_changed(self, event: Event = None):
"""Called when my climate have change"""
# _LOGGER.debug("%s - climate state change", self._attr_unique_id)
_LOGGER.debug("%s - climate state change", self._attr_unique_id)
on_percent = (
float(self.my_climate.proportional_algorithm.on_percent)
@@ -300,7 +297,7 @@ class ValveOpenPercentSensor(VersatileThermostatBaseEntity, SensorEntity):
@callback
async def async_my_climate_changed(self, event: Event = None):
"""Called when my climate have change"""
# _LOGGER.debug("%s - climate state change", self._attr_unique_id)
_LOGGER.debug("%s - climate state change", self._attr_unique_id)
old_state = self._attr_native_value
self._attr_native_value = self.my_climate.valve_open_percent
@@ -342,7 +339,7 @@ class OnTimeSensor(VersatileThermostatBaseEntity, SensorEntity):
@callback
async def async_my_climate_changed(self, event: Event = None):
"""Called when my climate have change"""
# _LOGGER.debug("%s - climate state change", self._attr_unique_id)
_LOGGER.debug("%s - climate state change", self._attr_unique_id)
on_time = (
float(self.my_climate.proportional_algorithm.on_time_sec)
@@ -391,7 +388,7 @@ class OffTimeSensor(VersatileThermostatBaseEntity, SensorEntity):
@callback
async def async_my_climate_changed(self, event: Event = None):
"""Called when my climate have change"""
# _LOGGER.debug("%s - climate state change", self._attr_unique_id)
_LOGGER.debug("%s - climate state change", self._attr_unique_id)
off_time = (
float(self.my_climate.proportional_algorithm.off_time_sec)
@@ -439,7 +436,7 @@ class LastTemperatureSensor(VersatileThermostatBaseEntity, SensorEntity):
@callback
async def async_my_climate_changed(self, event: Event = None):
"""Called when my climate have change"""
# _LOGGER.debug("%s - climate state change", self._attr_unique_id)
_LOGGER.debug("%s - climate state change", self._attr_unique_id)
old_state = self._attr_native_value
self._attr_native_value = self.my_climate.last_temperature_measure
@@ -468,7 +465,7 @@ class LastExtTemperatureSensor(VersatileThermostatBaseEntity, SensorEntity):
@callback
async def async_my_climate_changed(self, event: Event = None):
"""Called when my climate have change"""
# _LOGGER.debug("%s - climate state change", self._attr_unique_id)
_LOGGER.debug("%s - climate state change", self._attr_unique_id)
old_state = self._attr_native_value
self._attr_native_value = self.my_climate.last_ext_temperature_measure
@@ -497,7 +494,7 @@ class TemperatureSlopeSensor(VersatileThermostatBaseEntity, SensorEntity):
@callback
async def async_my_climate_changed(self, event: Event = None):
"""Called when my climate have change"""
# _LOGGER.debug("%s - climate state change", self._attr_unique_id)
_LOGGER.debug("%s - climate state change", self._attr_unique_id)
last_slope = self.my_climate.last_temperature_slope
if last_slope is None:
@@ -550,7 +547,7 @@ class RegulatedTemperatureSensor(VersatileThermostatBaseEntity, SensorEntity):
@callback
async def async_my_climate_changed(self, event: Event = None):
"""Called when my climate have change"""
# _LOGGER.debug("%s - climate state change", self._attr_unique_id)
_LOGGER.debug("%s - climate state change", self._attr_unique_id)
new_temp = self.my_climate.regulated_target_temp
if new_temp is None:
@@ -601,7 +598,7 @@ class EMATemperatureSensor(VersatileThermostatBaseEntity, SensorEntity):
@callback
async def async_my_climate_changed(self, event: Event = None):
"""Called when my climate have change"""
# _LOGGER.debug("%s - climate state change", self._attr_unique_id)
_LOGGER.debug("%s - climate state change", self._attr_unique_id)
new_ema = self.my_climate.ema_temperature
if new_ema is None:
@@ -708,7 +705,7 @@ class NbActiveDeviceForBoilerSensor(SensorEntity):
for entity in component.entities:
if isinstance(entity, BaseThermostat) and entity.is_used_by_central_boiler:
self._entities.append(entity)
for under in entity.activable_underlying_entities:
for under in entity.underlying_entities:
underlying_entities_id.append(under.entity_id)
if len(underlying_entities_id) > 0:
# Arme l'écoute de la première entité
@@ -728,65 +725,25 @@ class NbActiveDeviceForBoilerSensor(SensorEntity):
await self.calculate_nb_active_devices(None)
async def calculate_nb_active_devices(self, event: Event):
async def calculate_nb_active_devices(self, _):
"""Calculate the number of active VTherm that have an
influence on central boiler"""
# _LOGGER.debug("%s- calculate_nb_active_devices - the event is %s ", self, event)
if event is not None:
new_state: State = event.data.get("new_state")
# _LOGGER.debug(
# "%s - calculate_nb_active_devices new_state is %s", self, new_state
# )
if not new_state:
return
old_state: State = event.data.get("old_state")
# For underlying climate, we need to observe also the hvac_action if available
new_hvac_action = new_state.attributes.get("hvac_action")
old_hvac_action = (
old_state.attributes.get("hvac_action")
if old_state is not None
else None
)
# Filter events that are not interested for us
if (
old_state is not None
and new_state.state == old_state.state
and new_hvac_action == old_hvac_action
):
# A false state change
return
_LOGGER.debug(
"%s - calculating the number of active underlying device for boiler activation. change change from %s to %s",
self,
old_state,
new_state,
)
else:
_LOGGER.debug(
"%s - calculating the number of active underlying device for boiler activation. First time calculation",
self,
)
_LOGGER.debug("%s - calculating the number of active VTherm", self)
nb_active = 0
for entity in self._entities:
nb_active += entity.nb_device_actives
_LOGGER.debug(
"After examining the hvac_action of %s, nb_active is %s",
"Examining the hvac_action of %s",
entity.name,
nb_active,
)
if (
entity.hvac_mode in [HVACMode.HEAT, HVACMode.AUTO]
and entity.hvac_action == HVACAction.HEATING
):
for under in entity.underlying_entities:
nb_active += 1 if under.is_device_active else 0
self._attr_native_value = nb_active
_LOGGER.debug(
"%s - Number of active underlying entities is %s", self, nb_active
)
self.async_write_ha_state()
def __str__(self):

View File

@@ -28,7 +28,7 @@
"presence": "Presence detection",
"advanced": "Advanced parameters",
"auto_start_stop": "Auto start and stop",
"valve_regulation": "Valve regulation configuration",
"sonoff_trvzb": "Sonoff TRVZB configuration",
"finalize": "All done",
"configuration_not_complete": "Configuration not complete"
}
@@ -65,7 +65,7 @@
"use_motion_feature": "Use motion detection",
"use_power_feature": "Use power management",
"use_presence_feature": "Use presence detection",
"use_central_boiler_feature": "Use a central boiler. Check to add a control to your central boiler. You will have to configure the VTherm which will have a control of the central boiler after selecting this checkbox to take effect. If one VTherm requires heating, the boiler will be turned on. If no VTherm requires heating, the boiler will be turned off. Commands for turning on/off the central boiler are given in the related configuration page",
"use_central_boiler_feature": "Use a central boiler. Check to add a control to your central boiler. You will have to configure the VTherm which will have a control of the central boiler after seecting this checkbox to take effect. If one VTherm requires heating, the boiler will be turned on. If no VTherm requires heating, the boiler will be turned off. Commands for turning on/off the central boiler are given in the related configuration page",
"use_auto_start_stop_feature": "Use the auto start and stop feature"
}
},
@@ -77,6 +77,7 @@
"heater_keep_alive": "Switch keep-alive interval in seconds",
"proportional_function": "Algorithm",
"ac_mode": "AC mode",
"sonoff_trvzb_mode": "SONOFF TRVZB mode",
"auto_regulation_mode": "Self-regulation",
"auto_regulation_dtemp": "Regulation threshold",
"auto_regulation_periode_min": "Regulation minimum period",
@@ -89,6 +90,7 @@
"heater_keep_alive": "Optional heater switch state refresh interval. Leave empty if not required.",
"proportional_function": "Algorithm to use (TPI is the only one for now)",
"ac_mode": "Use the Air Conditioning (AC) mode",
"sonoff_trvzb_mode": "The underlyings are SONOFF TRVZB. You have to configure some extra entities in the specific menu option 'Sonoff trvzb configuration'",
"auto_regulation_mode": "Auto adjustment of the target temperature",
"auto_regulation_dtemp": "The threshold in ° (or % for valve) under which the temperature change will not be sent",
"auto_regulation_periode_min": "Duration in minutes between two regulation update",
@@ -217,9 +219,9 @@
"central_boiler_deactivation_service": "Command to turn-off the central boiler formatted like entity_id/service_name[/attribut:valeur]"
}
},
"valve_regulation": {
"title": "Self-regulation with valve",
"description": "Configuration for self-regulation with direct control of the valve",
"sonoff_trvzb": {
"title": "Sonoff TRVZB configuration",
"description": "Specific Sonoff TRVZB configuration",
"data": {
"offset_calibration_entity_ids": "Offset calibration entities",
"opening_degree_entity_ids": "Opening degree entities",
@@ -227,9 +229,9 @@
"proportional_function": "Algorithm"
},
"data_description": {
"offset_calibration_entity_ids": "The list of the 'offset calibration' entities. Set it if your TRV have the entity for better regulation. There should be one per underlying climate entities",
"offset_calibration_entity_ids": "The list of the 'offset calibration' entities. There should be one per underlying climate entities",
"opening_degree_entity_ids": "The list of the 'opening degree' entities. There should be one per underlying climate entities",
"closing_degree_entity_ids": "The list of the 'closing degree' entities. Set it if your TRV have the entity for better regulation. There should be one per underlying climate entities",
"closing_degree_entity_ids": "The list of the 'closing degree' entities. There should be one per underlying climate entities",
"proportional_function": "Algorithm to use (TPI is the only one for now)"
}
}
@@ -272,7 +274,7 @@
"presence": "Presence detection",
"advanced": "Advanced parameters",
"auto_start_stop": "Auto start and stop",
"valve_regulation": "Valve regulation configuration",
"sonoff_trvzb": "Sonoff TRVZB configuration",
"finalize": "All done",
"configuration_not_complete": "Configuration not complete"
}
@@ -309,7 +311,7 @@
"use_motion_feature": "Use motion detection",
"use_power_feature": "Use power management",
"use_presence_feature": "Use presence detection",
"use_central_boiler_feature": "Use a central boiler. Check to add a control to your central boiler. You will have to configure the VTherm which will have a control of the central boiler after selecting this checkbox to take effect. If one VTherm requires heating, the boiler will be turned on. If no VTherm requires heating, the boiler will be turned off. Commands for turning on/off the central boiler are given in the related configuration page",
"use_central_boiler_feature": "Use a central boiler. Check to add a control to your central boiler. You will have to configure the VTherm which will have a control of the central boiler after seecting this checkbox to take effect. If one VTherm requires heating, the boiler will be turned on. If no VTherm requires heating, the boiler will be turned off. Commands for turning on/off the central boiler are given in the related configuration page",
"use_auto_start_stop_feature": "Use the auto start and stop feature"
}
},
@@ -321,6 +323,7 @@
"heater_keep_alive": "Switch keep-alive interval in seconds",
"proportional_function": "Algorithm",
"ac_mode": "AC mode",
"sonoff_trvzb_mode": "SONOFF TRVZB mode",
"auto_regulation_mode": "Self-regulation",
"auto_regulation_dtemp": "Regulation threshold",
"auto_regulation_periode_min": "Regulation minimum period",
@@ -333,6 +336,7 @@
"heater_keep_alive": "Optional heater switch state refresh interval. Leave empty if not required.",
"proportional_function": "Algorithm to use (TPI is the only one for now)",
"ac_mode": "Use the Air Conditioning (AC) mode",
"sonoff_trvzb_mode": "The underlyings are SONOFF TRVZB. You have to configure some extra entities in the specific menu option 'Sonoff trvzb configuration'",
"auto_regulation_mode": "Auto adjustment of the target temperature",
"auto_regulation_dtemp": "The threshold in ° (or % for valve) under which the temperature change will not be sent",
"auto_regulation_periode_min": "Duration in minutes between two regulation update",
@@ -461,9 +465,9 @@
"central_boiler_deactivation_service": "Command to turn-off the central boiler formatted like entity_id/service_name[/attribut:valeur]"
}
},
"valve_regulation": {
"title": "Self-regulation with valve - {name}",
"description": "Configuration for self-regulation with direct control of the valve",
"sonoff_trvzb": {
"title": "Sonoff TRVZB configuration - {name}",
"description": "Specific Sonoff TRVZB configuration",
"data": {
"offset_calibration_entity_ids": "Offset calibration entities",
"opening_degree_entity_ids": "Opening degree entities",
@@ -471,9 +475,9 @@
"proportional_function": "Algorithm"
},
"data_description": {
"offset_calibration_entity_ids": "The list of the 'offset calibration' entities. Set it if your TRV have the entity for better regulation. There should be one per underlying climate entities",
"offset_calibration_entity_ids": "The list of the 'offset calibration' entities. There should be one per underlying climate entities",
"opening_degree_entity_ids": "The list of the 'opening degree' entities. There should be one per underlying climate entities",
"closing_degree_entity_ids": "The list of the 'closing degree' entities. Set it if your TRV have the entity for better regulation. There should be one per underlying climate entities",
"closing_degree_entity_ids": "The list of the 'closing degree' entities. There should be one per underlying climate entities",
"proportional_function": "Algorithm to use (TPI is the only one for now)"
}
}
@@ -484,7 +488,7 @@
"window_open_detection_method": "Only one window open detection method should be used. Use either window sensor or automatic detection through temperature threshold but not both",
"no_central_config": "You cannot check 'use central configuration' because no central configuration was found. You need to create a Versatile Thermostat of type 'Central Configuration' to use it.",
"service_configuration_format": "The format of the service configuration is wrong",
"valve_regulation_nb_entities_incorrect": "The number of valve entities for valve regulation should be equal to the number of underlyings"
"sonoff_trvzb_nb_entities_incorrect": "The number of specific entities for Sonoff TRVZB should be equal to the number of underlyings"
},
"abort": {
"already_configured": "Device is already configured"
@@ -506,8 +510,7 @@
"auto_regulation_medium": "Medium",
"auto_regulation_light": "Light",
"auto_regulation_expert": "Expert",
"auto_regulation_none": "No auto-regulation",
"auto_regulation_valve": "Direct control of valve"
"auto_regulation_none": "No auto-regulation"
}
},
"auto_fan_mode": {

View File

@@ -16,7 +16,7 @@ from homeassistant.components.climate import (
ClimateEntityFeature,
)
from .commons import round_to_nearest
from .commons import NowClass, round_to_nearest
from .base_thermostat import BaseThermostat, ConfigData
from .pi_algorithm import PITemperatureRegulator
@@ -42,6 +42,24 @@ HVAC_ACTION_ON = [ # pylint: disable=invalid-name
class ThermostatOverClimate(BaseThermostat[UnderlyingClimate]):
"""Representation of a base class for a Versatile Thermostat over a climate"""
_auto_regulation_mode: str | None = None
_regulation_algo = 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 = None
# The current fan mode (could be change by service call)
_current_auto_fan_mode: str | None = None
# The fan_mode name depending of the current_mode
_auto_activated_fan_mode: str | None = None
_auto_deactivated_fan_mode: str | None = None
_auto_start_stop_level: TYPE_AUTO_START_STOP_LEVELS = AUTO_START_STOP_LEVEL_NONE
_auto_start_stop_algo: AutoStartStopDetectionAlgorithm | None = None
_is_auto_start_stop_enabled: bool = False
_follow_underlying_temp_change: bool = False
_entity_component_unrecorded_attributes = BaseThermostat._entity_component_unrecorded_attributes.union( # pylint: disable=protected-access
frozenset(
{
@@ -60,7 +78,6 @@ class ThermostatOverClimate(BaseThermostat[UnderlyingClimate]):
"auto_start_stop_enable",
"auto_start_stop_accumulated_error",
"auto_start_stop_accumulated_error_threshold",
"auto_start_stop_last_switch_date",
"follow_underlying_temp_change",
}
)
@@ -70,30 +87,10 @@ class ThermostatOverClimate(BaseThermostat[UnderlyingClimate]):
self, hass: HomeAssistant, unique_id: str, name: str, entry_infos: ConfigData
):
"""Initialize the thermostat over switch."""
self._auto_regulation_mode: str | None = None
self._regulation_algo = None
self._regulated_target_temp: float | None = None
self._auto_regulation_dtemp: float | None = None
self._auto_regulation_period_min: int | None = None
self._last_regulation_change: datetime | None = None
# The fan mode configured in configEntry
self._auto_fan_mode: str | None = None
# The current fan mode (could be change by service call)
self._current_auto_fan_mode: str | None = None
# The fan_mode name depending of the current_mode
self._auto_activated_fan_mode: str | None = None
self._auto_deactivated_fan_mode: str | None = None
self._auto_start_stop_level: TYPE_AUTO_START_STOP_LEVELS = (
AUTO_START_STOP_LEVEL_NONE
)
self._auto_start_stop_algo: AutoStartStopDetectionAlgorithm | None = None
self._is_auto_start_stop_enabled: bool = False
self._follow_underlying_temp_change: bool = False
self._last_regulation_change = None # NowClass.get_now(hass)
# super.__init__ calls post_init at the end. So it must be called after regulation initialization
super().__init__(hass, unique_id, name, entry_infos)
self._regulated_target_temp = self.target_temperature
self._last_regulation_change = NowClass.get_now(hass)
@overrides
def post_init(self, config_entry: ConfigData):
@@ -183,8 +180,7 @@ class ThermostatOverClimate(BaseThermostat[UnderlyingClimate]):
await super()._async_internal_set_temperature(temperature)
self._regulation_algo.set_target_temp(self.target_temperature)
# is done by control_heating method. No need to do it here
# await self._send_regulated_temperature(force=True)
await self._send_regulated_temperature(force=True)
async def _send_regulated_temperature(self, force=False):
"""Sends the regulated temperature to all underlying"""
@@ -209,18 +205,16 @@ class ThermostatOverClimate(BaseThermostat[UnderlyingClimate]):
force,
)
if self._last_regulation_change is not None:
period = (
float((self.now - self._last_regulation_change).total_seconds()) / 60.0
now: datetime = NowClass.get_now(self._hass)
period = float((now - self._last_regulation_change).total_seconds()) / 60.0
if not force and period < self._auto_regulation_period_min:
_LOGGER.info(
"%s - period (%.1f) min is < %.0f min -> forget the regulation send",
self,
period,
self._auto_regulation_period_min,
)
if not force and period < self._auto_regulation_period_min:
_LOGGER.info(
"%s - period (%.1f) min is < %.0f min -> forget the regulation send",
self,
period,
self._auto_regulation_period_min,
)
return
return
if not self._regulated_target_temp:
self._regulated_target_temp = self.target_temperature
@@ -258,7 +252,7 @@ class ThermostatOverClimate(BaseThermostat[UnderlyingClimate]):
new_regulated_temp,
)
self._last_regulation_change = self.now
self._last_regulation_change = now
for under in self._underlyings:
# issue 348 - use device temperature if configured as offset
offset_temp = 0
@@ -556,10 +550,6 @@ class ThermostatOverClimate(BaseThermostat[UnderlyingClimate]):
"auto_start_stop_accumulated_error_threshold"
] = self._auto_start_stop_algo.accumulated_error_threshold
self._attr_extra_state_attributes["auto_start_stop_last_switch_date"] = (
self._auto_start_stop_algo.last_switch_date
)
self._attr_extra_state_attributes["follow_underlying_temp_change"] = (
self._follow_underlying_temp_change
)
@@ -990,32 +980,6 @@ class ThermostatOverClimate(BaseThermostat[UnderlyingClimate]):
def set_auto_start_stop_enable(self, is_enabled: bool):
"""Enable/Disable the auto-start/stop feature"""
self._is_auto_start_stop_enabled = is_enabled
if (
self.hvac_mode == HVACMode.OFF
and self.hvac_off_reason == HVAC_OFF_REASON_AUTO_START_STOP
):
_LOGGER.debug(
"%s - the vtherm is off cause auto-start/stop and enable have been set to false -> starts the VTherm"
)
self.hass.create_task(self.async_turn_on())
# Send an event
self.send_event(
event_type=EventType.AUTO_START_STOP_EVENT,
data={
"type": "start",
"name": self.name,
"cause": "Auto start stop disabled",
"hvac_mode": self.hvac_mode,
"saved_hvac_mode": self._saved_hvac_mode,
"target_temperature": self.target_temperature,
"current_temperature": self.current_temperature,
"temperature_slope": round(self.last_temperature_slope or 0, 3),
"accumulated_error": self._auto_start_stop_algo.accumulated_error,
"accumulated_error_threshold": self._auto_start_stop_algo.accumulated_error_threshold,
},
)
self.update_custom_attributes()
def set_follow_underlying_temp_change(self, follow: bool):
@@ -1119,6 +1083,15 @@ class ThermostatOverClimate(BaseThermostat[UnderlyingClimate]):
return self._support_flags
# We keep the step configured for the VTherm and not the step of the underlying
# @property
# def target_temperature_step(self) -> float | None:
# """Return the supported step of target temperature."""
# if self.underlying_entity(0):
# return self.underlying_entity(0).target_temperature_step
#
# return None
@property
def target_temperature_high(self) -> float | None:
"""Return the highbound target temperature we try to reach.
@@ -1285,13 +1258,6 @@ class ThermostatOverClimate(BaseThermostat[UnderlyingClimate]):
self.choose_auto_regulation_mode(CONF_AUTO_REGULATION_SLOW)
elif auto_regulation_mode == "Expert":
self.choose_auto_regulation_mode(CONF_AUTO_REGULATION_EXPERT)
else:
_LOGGER.warning(
"%s - auto_regulation_mode %s is not supported",
self,
auto_regulation_mode,
)
return
await self._send_regulated_temperature()
self.update_custom_attributes()

View File

@@ -1,5 +1,5 @@
# pylint: disable=line-too-long, too-many-lines, abstract-method
""" A climate with a direct valve regulation class """
""" A climate over Sonoff TRVZB classe """
import logging
from datetime import datetime
@@ -7,7 +7,7 @@ from datetime import datetime
from homeassistant.core import HomeAssistant
from homeassistant.components.climate import HVACMode, HVACAction
from .underlyings import UnderlyingValveRegulation
from .underlyings import UnderlyingSonoffTRVZB
# from .commons import NowClass, round_to_nearest
from .base_thermostat import ConfigData
@@ -21,14 +21,14 @@ from .const import * # pylint: disable=wildcard-import, unused-wildcard-import
_LOGGER = logging.getLogger(__name__)
class ThermostatOverClimateValve(ThermostatOverClimate):
"""This class represent a VTherm over a climate with a direct valve regulation"""
class ThermostatOverSonoffTRVZB(ThermostatOverClimate):
"""This class represent a VTherm over a Sonoff TRVZB climate"""
_entity_component_unrecorded_attributes = ThermostatOverClimate._entity_component_unrecorded_attributes.union( # pylint: disable=protected-access
frozenset(
{
"is_over_climate",
"have_valve_regulation",
"is_over_sonoff_trvzb",
"underlying_entities",
"on_time_sec",
"off_time_sec",
@@ -40,25 +40,28 @@ class ThermostatOverClimateValve(ThermostatOverClimate):
}
)
)
_underlyings_sonoff_trvzb: list[UnderlyingSonoffTRVZB] = []
_valve_open_percent: int | None = None
_last_calculation_timestamp: datetime | None = None
_auto_regulation_dpercent: float | None = None
_auto_regulation_period_min: int | None = None
def __init__(
self, hass: HomeAssistant, unique_id: str, name: str, entry_infos: ConfigData
):
"""Initialize the ThermostatOverClimateValve class"""
_LOGGER.debug("%s - creating a ThermostatOverClimateValve VTherm", name)
self._underlyings_valve_regulation: list[UnderlyingValveRegulation] = []
self._valve_open_percent: int | None = None
self._last_calculation_timestamp: datetime | None = None
self._auto_regulation_dpercent: float | None = None
self._auto_regulation_period_min: int | None = None
"""Initialize the ThermostatOverSonoffTRVZB class"""
_LOGGER.debug("%s - creating a ThermostatOverSonoffTRVZB VTherm", name)
super().__init__(hass, unique_id, name, entry_infos)
# self._valve_open_percent: int = 0
# self._last_calculation_timestamp: datetime | None = None
# self._auto_regulation_dpercent: float | None = None
# self._auto_regulation_period_min: int | None = None
@overrides
def post_init(self, config_entry: ConfigData):
"""Initialize the Thermostat and underlyings
Beware that the underlyings list contains the climate which represent the TRV
but also the UnderlyingValveRegulation which reprensent the valve"""
Beware that the underlyings list contains the climate which represent the Sonoff TRVZB
but also the UnderlyingSonoff which reprensent the valve"""
super().post_init(config_entry)
@@ -83,15 +86,11 @@ class ThermostatOverClimateValve(ThermostatOverClimate):
self.name,
)
offset_list = config_entry.get(CONF_OFFSET_CALIBRATION_LIST, [])
opening_list = config_entry.get(CONF_OPENING_DEGREE_LIST)
closing_list = config_entry.get(CONF_CLOSING_DEGREE_LIST, [])
for idx, _ in enumerate(config_entry.get(CONF_UNDERLYING_LIST)):
offset = offset_list[idx] if idx < len(offset_list) else None
# number of opening should equal number of underlying
opening = opening_list[idx]
closing = closing_list[idx] if idx < len(closing_list) else None
under = UnderlyingValveRegulation(
offset = config_entry.get(CONF_OFFSET_CALIBRATION_LIST)[idx]
opening = config_entry.get(CONF_OPENING_DEGREE_LIST)[idx]
closing = config_entry.get(CONF_CLOSING_DEGREE_LIST)[idx]
under = UnderlyingSonoffTRVZB(
hass=self._hass,
thermostat=self,
offset_calibration_entity_id=offset,
@@ -99,20 +98,19 @@ class ThermostatOverClimateValve(ThermostatOverClimate):
closing_degree_entity_id=closing,
climate_underlying=self._underlyings[idx],
)
self._underlyings_valve_regulation.append(under)
self._underlyings_sonoff_trvzb.append(under)
@overrides
def update_custom_attributes(self):
"""Custom attributes"""
super().update_custom_attributes()
self._attr_extra_state_attributes["have_valve_regulation"] = (
self.have_valve_regulation
self._attr_extra_state_attributes["is_over_sonoff_trvzb"] = (
self.is_over_sonoff_trvzb
)
self._attr_extra_state_attributes["underlyings_valve_regulation"] = [
underlying.valve_entity_ids
for underlying in self._underlyings_valve_regulation
self._attr_extra_state_attributes["underlying_sonoff_trvzb_entities"] = [
underlying.entity_id for underlying in self._underlyings_sonoff_trvzb
]
self._attr_extra_state_attributes["on_percent"] = (
@@ -219,9 +217,12 @@ class ThermostatOverClimateValve(ThermostatOverClimate):
self._valve_open_percent = new_valve_percent
for under in self._underlyings_sonoff_trvzb:
under.set_valve_open_percent()
self._last_calculation_timestamp = now
super().recalculate()
self.update_custom_attributes()
async def _send_regulated_temperature(self, force=False):
"""Sends the regulated temperature to all underlying"""
@@ -229,19 +230,17 @@ class ThermostatOverClimateValve(ThermostatOverClimate):
return
for under in self._underlyings:
if self.target_temperature != under.last_sent_temperature:
await under.set_temperature(
self.target_temperature,
self._attr_max_temp,
self._attr_min_temp,
)
await under.set_temperature(
self.target_temperature,
self._attr_max_temp,
self._attr_min_temp,
)
for under in self._underlyings_valve_regulation:
await under.set_valve_open_percent()
self.recalculate()
@property
def have_valve_regulation(self) -> bool:
"""True if the Thermostat is regulated by valve"""
def is_over_sonoff_trvzb(self) -> bool:
"""True if the Thermostat is over_sonoff_trvzb"""
return True
@property
@@ -267,29 +266,6 @@ class ThermostatOverClimateValve(ThermostatOverClimate):
@property
def hvac_action(self) -> HVACAction | None:
"""Returns the current hvac_action by checking all hvac_action of the _underlyings_valve_regulation"""
"""Returns the current hvac_action by checking all hvac_action of the _underlyings_sonoff_trvzb"""
return self.calculate_hvac_action(self._underlyings_valve_regulation)
@property
def is_device_active(self) -> bool:
"""A hack to overrides the state from underlyings"""
return self.valve_open_percent > 0
@property
def nb_device_actives(self) -> int:
"""Calculate the number of active devices"""
if self.is_device_active:
return len(self._underlyings_valve_regulation)
else:
return 0
@property
def activable_underlying_entities(self) -> list | None:
"""Returns the activable underlying entities for controling the central boiler"""
return self._underlyings_valve_regulation
@overrides
async def service_set_auto_regulation_mode(self, auto_regulation_mode: str):
"""This should not be possible in valve regulation mode"""
return
return self.calculate_hvac_action(self._underlyings_sonoff_trvzb)

View File

@@ -7,7 +7,6 @@ from homeassistant.helpers.event import (
async_track_state_change_event,
EventStateChangedData,
)
from homeassistant.core import HomeAssistant
from homeassistant.components.climate import HVACMode
from .const import (
@@ -46,10 +45,11 @@ class ThermostatOverSwitch(BaseThermostat[UnderlyingSwitch]):
)
)
def __init__(self, hass: HomeAssistant, unique_id, name, config_entry) -> None:
"""Initialize the thermostat over switch."""
self._is_inversed: bool | None = None
super().__init__(hass, unique_id, name, config_entry)
# useless for now
# 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 = None
@property
def is_over_switch(self) -> bool:

View File

@@ -248,9 +248,8 @@ class ThermostatOverValve(BaseThermostat[UnderlyingValve]): # pylint: disable=a
self._valve_open_percent = new_valve_percent
# is one in start_cycle now
# for under in self._underlyings:
# under.set_valve_open_percent()
for under in self._underlyings:
under.set_valve_open_percent()
self._last_calculation_timestamp = now

View File

@@ -28,7 +28,7 @@
"presence": "Presence detection",
"advanced": "Advanced parameters",
"auto_start_stop": "Auto start and stop",
"valve_regulation": "Valve regulation configuration",
"sonoff_trvzb": "Sonoff TRVZB configuration",
"finalize": "All done",
"configuration_not_complete": "Configuration not complete"
}
@@ -65,7 +65,7 @@
"use_motion_feature": "Use motion detection",
"use_power_feature": "Use power management",
"use_presence_feature": "Use presence detection",
"use_central_boiler_feature": "Use a central boiler. Check to add a control to your central boiler. You will have to configure the VTherm which will have a control of the central boiler after selecting this checkbox to take effect. If one VTherm requires heating, the boiler will be turned on. If no VTherm requires heating, the boiler will be turned off. Commands for turning on/off the central boiler are given in the related configuration page",
"use_central_boiler_feature": "Use a central boiler. Check to add a control to your central boiler. You will have to configure the VTherm which will have a control of the central boiler after seecting this checkbox to take effect. If one VTherm requires heating, the boiler will be turned on. If no VTherm requires heating, the boiler will be turned off. Commands for turning on/off the central boiler are given in the related configuration page",
"use_auto_start_stop_feature": "Use the auto start and stop feature"
}
},
@@ -77,6 +77,7 @@
"heater_keep_alive": "Switch keep-alive interval in seconds",
"proportional_function": "Algorithm",
"ac_mode": "AC mode",
"sonoff_trvzb_mode": "SONOFF TRVZB mode",
"auto_regulation_mode": "Self-regulation",
"auto_regulation_dtemp": "Regulation threshold",
"auto_regulation_periode_min": "Regulation minimum period",
@@ -89,6 +90,7 @@
"heater_keep_alive": "Optional heater switch state refresh interval. Leave empty if not required.",
"proportional_function": "Algorithm to use (TPI is the only one for now)",
"ac_mode": "Use the Air Conditioning (AC) mode",
"sonoff_trvzb_mode": "The underlyings are SONOFF TRVZB. You have to configure some extra entities in the specific menu option 'Sonoff trvzb configuration'",
"auto_regulation_mode": "Auto adjustment of the target temperature",
"auto_regulation_dtemp": "The threshold in ° (or % for valve) under which the temperature change will not be sent",
"auto_regulation_periode_min": "Duration in minutes between two regulation update",
@@ -217,9 +219,9 @@
"central_boiler_deactivation_service": "Command to turn-off the central boiler formatted like entity_id/service_name[/attribut:valeur]"
}
},
"valve_regulation": {
"title": "Self-regulation with valve",
"description": "Configuration for self-regulation with direct control of the valve",
"sonoff_trvzb": {
"title": "Sonoff TRVZB configuration",
"description": "Specific Sonoff TRVZB configuration",
"data": {
"offset_calibration_entity_ids": "Offset calibration entities",
"opening_degree_entity_ids": "Opening degree entities",
@@ -227,9 +229,9 @@
"proportional_function": "Algorithm"
},
"data_description": {
"offset_calibration_entity_ids": "The list of the 'offset calibration' entities. Set it if your TRV have the entity for better regulation. There should be one per underlying climate entities",
"offset_calibration_entity_ids": "The list of the 'offset calibration' entities. There should be one per underlying climate entities",
"opening_degree_entity_ids": "The list of the 'opening degree' entities. There should be one per underlying climate entities",
"closing_degree_entity_ids": "The list of the 'closing degree' entities. Set it if your TRV have the entity for better regulation. There should be one per underlying climate entities",
"closing_degree_entity_ids": "The list of the 'closing degree' entities. There should be one per underlying climate entities",
"proportional_function": "Algorithm to use (TPI is the only one for now)"
}
}
@@ -272,7 +274,7 @@
"presence": "Presence detection",
"advanced": "Advanced parameters",
"auto_start_stop": "Auto start and stop",
"valve_regulation": "Valve regulation configuration",
"sonoff_trvzb": "Sonoff TRVZB configuration",
"finalize": "All done",
"configuration_not_complete": "Configuration not complete"
}
@@ -309,7 +311,7 @@
"use_motion_feature": "Use motion detection",
"use_power_feature": "Use power management",
"use_presence_feature": "Use presence detection",
"use_central_boiler_feature": "Use a central boiler. Check to add a control to your central boiler. You will have to configure the VTherm which will have a control of the central boiler after selecting this checkbox to take effect. If one VTherm requires heating, the boiler will be turned on. If no VTherm requires heating, the boiler will be turned off. Commands for turning on/off the central boiler are given in the related configuration page",
"use_central_boiler_feature": "Use a central boiler. Check to add a control to your central boiler. You will have to configure the VTherm which will have a control of the central boiler after seecting this checkbox to take effect. If one VTherm requires heating, the boiler will be turned on. If no VTherm requires heating, the boiler will be turned off. Commands for turning on/off the central boiler are given in the related configuration page",
"use_auto_start_stop_feature": "Use the auto start and stop feature"
}
},
@@ -321,6 +323,7 @@
"heater_keep_alive": "Switch keep-alive interval in seconds",
"proportional_function": "Algorithm",
"ac_mode": "AC mode",
"sonoff_trvzb_mode": "SONOFF TRVZB mode",
"auto_regulation_mode": "Self-regulation",
"auto_regulation_dtemp": "Regulation threshold",
"auto_regulation_periode_min": "Regulation minimum period",
@@ -333,6 +336,7 @@
"heater_keep_alive": "Optional heater switch state refresh interval. Leave empty if not required.",
"proportional_function": "Algorithm to use (TPI is the only one for now)",
"ac_mode": "Use the Air Conditioning (AC) mode",
"sonoff_trvzb_mode": "The underlyings are SONOFF TRVZB. You have to configure some extra entities in the specific menu option 'Sonoff trvzb configuration'",
"auto_regulation_mode": "Auto adjustment of the target temperature",
"auto_regulation_dtemp": "The threshold in ° (or % for valve) under which the temperature change will not be sent",
"auto_regulation_periode_min": "Duration in minutes between two regulation update",
@@ -450,7 +454,7 @@
}
},
"central_boiler": {
"title": "Control of the central boiler - {name}",
"title": "Control of the central boiler",
"description": "Enter the services to call to turn on/off the central boiler. Leave blank if no service call is to be made (in this case, you will have to manage the turning on/off of your central boiler yourself). The service called must be formatted as follows: `entity_id/service_name[/attribute:value]` (/attribute:value is optional)\nFor example:\n- to turn on a switch: `switch.controle_chaudiere/switch.turn_on`\n- to turn off a switch: `switch.controle_chaudiere/switch.turn_off`\n- to program the boiler to 25° and thus force its ignition: `climate.thermostat_chaudiere/climate.set_temperature/temperature:25`\n- to send 10° to the boiler and thus force its extinction: `climate.thermostat_chaudiere/climate.set_temperature/temperature:10`",
"data": {
"central_boiler_activation_service": "Command to turn-on",
@@ -461,9 +465,9 @@
"central_boiler_deactivation_service": "Command to turn-off the central boiler formatted like entity_id/service_name[/attribut:valeur]"
}
},
"valve_regulation": {
"title": "Self-regulation with valve - {name}",
"description": "Configuration for self-regulation with direct control of the valve",
"sonoff_trvzb": {
"title": "Sonoff TRVZB configuration",
"description": "Specific Sonoff TRVZB configuration",
"data": {
"offset_calibration_entity_ids": "Offset calibration entities",
"opening_degree_entity_ids": "Opening degree entities",
@@ -471,9 +475,9 @@
"proportional_function": "Algorithm"
},
"data_description": {
"offset_calibration_entity_ids": "The list of the 'offset calibration' entities. Set it if your TRV have the entity for better regulation. There should be one per underlying climate entities",
"offset_calibration_entity_ids": "The list of the 'offset calibration' entities. There should be one per underlying climate entities",
"opening_degree_entity_ids": "The list of the 'opening degree' entities. There should be one per underlying climate entities",
"closing_degree_entity_ids": "The list of the 'closing degree' entities. Set it if your TRV have the entity for better regulation. There should be one per underlying climate entities",
"closing_degree_entity_ids": "The list of the 'closing degree' entities. There should be one per underlying climate entities",
"proportional_function": "Algorithm to use (TPI is the only one for now)"
}
}
@@ -484,7 +488,7 @@
"window_open_detection_method": "Only one window open detection method should be used. Use either window sensor or automatic detection through temperature threshold but not both",
"no_central_config": "You cannot check 'use central configuration' because no central configuration was found. You need to create a Versatile Thermostat of type 'Central Configuration' to use it.",
"service_configuration_format": "The format of the service configuration is wrong",
"valve_regulation_nb_entities_incorrect": "The number of valve entities for valve regulation should be equal to the number of underlyings"
"sonoff_trvzb_nb_entities_incorrect": "The number of specific entities for Sonoff TRVZB should be equal to the number of underlyings"
},
"abort": {
"already_configured": "Device is already configured"
@@ -506,8 +510,7 @@
"auto_regulation_medium": "Medium",
"auto_regulation_light": "Light",
"auto_regulation_expert": "Expert",
"auto_regulation_none": "No auto-regulation",
"auto_regulation_valve": "Direct control of valve"
"auto_regulation_none": "No auto-regulation"
}
},
"auto_fan_mode": {

View File

@@ -28,7 +28,7 @@
"presence": "Détection de présence",
"advanced": "Paramètres avancés",
"auto_start_stop": "Allumage/extinction automatique",
"valve_regulation": "Configuration de la regulation par vanne",
"sonoff_trvzb": "Configuration spécifique à Sonoff TRVZB",
"finalize": "Finaliser la création",
"configuration_not_complete": "Configuration incomplète"
}
@@ -77,6 +77,7 @@
"heater_keep_alive": "keep-alive (sec)",
"proportional_function": "Algorithme",
"ac_mode": "AC mode ?",
"sonoff_trvzb_mode": "Mode Sonoff TRVZB",
"auto_regulation_mode": "Auto-régulation",
"auto_regulation_dtemp": "Seuil de régulation",
"auto_regulation_periode_min": "Période minimale de régulation",
@@ -89,8 +90,9 @@
"heater_keep_alive": "Intervalle de rafraichissement du switch en secondes. Laisser vide pour désactiver. À n'utiliser que pour les switchs qui le nécessite.",
"proportional_function": "Algorithme à utiliser (Seul TPI est disponible pour l'instant)",
"ac_mode": "Utilisation du mode Air Conditionné (AC)",
"auto_regulation_mode": "Utilisation de l'auto-régulation faite par VTherm",
"auto_regulation_dtemp": "Le seuil en ° (ou % pour les vannes) en-dessous duquel la régulation ne sera pas envoyée",
"sonoff_trvzb_mode": "Les équipements sont des Sonoff TRVZB. Vous devez configurer les entités dédiées dans le menu 'Configuration Sonoff TRVZB'",
"auto_regulation_mode": "Ajustement automatique de la température cible",
"auto_regulation_dtemp": "Le seuil en ° (ou % pour les valves) en-dessous duquel la régulation ne sera pas envoyée",
"auto_regulation_periode_min": "La durée en minutes entre deux mise à jour faites par la régulation",
"auto_regulation_use_device_temp": "Compenser la temperature interne du sous-jacent pour accélérer l'auto-régulation",
"inverse_switch_command": "Inverse la commande du switch pour une installation avec fil pilote et diode",
@@ -217,19 +219,19 @@
"central_boiler_deactivation_service": "Commande à éxecuter pour étiendre la chaudière centrale au format entity_id/service_name[/attribut:valeur]"
}
},
"valve_regulation": {
"title": "Auto-régulation par vanne - {name}",
"description": "Configuration de l'auto-régulation par controle direct de la vanne",
"sonoff_trvzb": {
"title": "Configuration Sonoff TRVZB",
"description": "Configuration spécifique des Sonoff TRVZB",
"data": {
"offset_calibration_entity_ids": "Entités de 'calibrage du décalage''",
"opening_degree_entity_ids": "Entités 'ouverture de vanne'",
"closing_degree_entity_ids": "Entités 'fermeture de la vanne'",
"offset_calibration_entity_ids": "Entités de 'Offset calibration'",
"opening_degree_entity_ids": "Entités de 'Opening degree'",
"closing_degree_entity_ids": "Entités de 'Closing degree'",
"proportional_function": "Algorithme"
},
"data_description": {
"offset_calibration_entity_ids": "La liste des entités 'calibrage du décalage' (offset calibration). Configurez le si votre TRV possède cette fonction pour une meilleure régulation. Il doit y en avoir une par entité climate sous-jacente",
"opening_degree_entity_ids": "La liste des entités 'ouverture de vanne'. Il doit y en avoir une par entité climate sous-jacente",
"closing_degree_entity_ids": "La liste des entités 'fermeture de la vanne'. Configurez le si votre TRV possède cette fonction pour une meilleure régulation. Il doit y en avoir une par entité climate sous-jacente",
"offset_calibration_entity_ids": "La liste des entités 'offset calibration' entities. Il doit y en avoir une par entité climate sous-jacente",
"opening_degree_entity_ids": "La liste des entités 'opening degree' entities. Il doit y en avoir une par entité climate sous-jacente",
"closing_degree_entity_ids": "La liste des entités 'closing degree' entities. Il doit y en avoir une par entité climate sous-jacente",
"proportional_function": "Algorithme à utiliser (seulement TPI est disponible)"
}
}
@@ -272,7 +274,7 @@
"presence": "Détection de présence",
"advanced": "Paramètres avancés",
"auto_start_stop": "Allumage/extinction automatique",
"valve_regulation": "Configuration de la regulation par vanne",
"sonoff_trvzb": "Configuration spécifique à Sonoff TRVZB",
"finalize": "Finaliser les modifications",
"configuration_not_complete": "Configuration incomplète"
}
@@ -321,6 +323,7 @@
"heater_keep_alive": "keep-alive (sec)",
"proportional_function": "Algorithme",
"ac_mode": "AC mode ?",
"sonoff_trvzb_mode": "Mode Sonoff TRVZB",
"auto_regulation_mode": "Auto-régulation",
"auto_regulation_dtemp": "Seuil de régulation",
"auto_regulation_periode_min": "Période minimale de régulation",
@@ -333,8 +336,9 @@
"heater_keep_alive": "Intervalle de rafraichissement du switch en secondes. Laisser vide pour désactiver. À n'utiliser que pour les switchs qui le nécessite.",
"proportional_function": "Algorithme à utiliser (Seul TPI est disponible pour l'instant)",
"ac_mode": "Utilisation du mode Air Conditionné (AC)",
"auto_regulation_mode": "Utilisation de l'auto-régulation faite par VTherm",
"auto_regulation_dtemp": "Le seuil en ° (ou % pour les vannes) en-dessous duquel la régulation ne sera pas envoyée",
"sonoff_trvzb_mode": "Les équipements sont des Sonoff TRVZB. Vous devez configurer les entités dédiées dans le menu 'Configuration Sonoff TRVZB'",
"auto_regulation_mode": "Ajustement automatique de la température cible",
"auto_regulation_dtemp": "Le seuil en ° (ou % pour les valves) en-dessous duquel la régulation ne sera pas envoyée",
"auto_regulation_periode_min": "La durée en minutes entre deux mise à jour faites par la régulation",
"auto_regulation_use_device_temp": "Compenser la temperature interne du sous-jacent pour accélérer l'auto-régulation",
"inverse_switch_command": "Inverse la commande du switch pour une installation avec fil pilote et diode",
@@ -455,19 +459,19 @@
"central_boiler_deactivation_service": "Commande à éxecuter pour étiendre la chaudière centrale au format entity_id/service_name[/attribut:valeur]"
}
},
"valve_regulation": {
"title": "Auto-régulation par vanne - {name}",
"description": "Configuration de l'auto-régulation par controle direct de la vanne",
"sonoff_trvzb": {
"title": "Configuration Sonoff TRVZB - {name}",
"description": "Configuration spécifique des Sonoff TRVZB",
"data": {
"offset_calibration_entity_ids": "Entités de 'calibrage du décalage''",
"opening_degree_entity_ids": "Entités 'ouverture de vanne'",
"closing_degree_entity_ids": "Entités 'fermeture de la vanne'",
"offset_calibration_entity_ids": "Entités de 'Offset calibration'",
"opening_degree_entity_ids": "Entités de 'Opening degree'",
"closing_degree_entity_ids": "Entités de 'Closing degree'",
"proportional_function": "Algorithme"
},
"data_description": {
"offset_calibration_entity_ids": "La liste des entités 'calibrage du décalage' (offset calibration). Configurez le si votre TRV possède cette fonction pour une meilleure régulation. Il doit y en avoir une par entité climate sous-jacente",
"opening_degree_entity_ids": "La liste des entités 'ouverture de vanne'. Il doit y en avoir une par entité climate sous-jacente",
"closing_degree_entity_ids": "La liste des entités 'fermeture de la vanne'. Configurez le si votre TRV possède cette fonction pour une meilleure régulation. Il doit y en avoir une par entité climate sous-jacente",
"offset_calibration_entity_ids": "La liste des entités 'offset calibration' entities. Il doit y en avoir une par entité climate sous-jacente",
"opening_degree_entity_ids": "La liste des entités 'opening degree' entities. Il doit y en avoir une par entité climate sous-jacente",
"closing_degree_entity_ids": "La liste des entités 'closing degree' entities. Il doit y en avoir une par entité climate sous-jacente",
"proportional_function": "Algorithme à utiliser (seulement TPI est disponible)"
}
}
@@ -478,7 +482,7 @@
"window_open_detection_method": "Une seule méthode de détection des ouvertures ouvertes doit être utilisée. Utilisez le détecteur d'ouverture ou les seuils de température mais pas les deux.",
"no_central_config": "Vous ne pouvez pas cocher 'Utiliser la configuration centrale' car aucune configuration centrale n'a été trouvée. Vous devez créer un Versatile Thermostat de type 'Central Configuration' pour pouvoir l'utiliser.",
"service_configuration_format": "Mauvais format de la configuration du service",
"valve_regulation_nb_entities_incorrect": "Le nombre d'entités pour la régulation par vanne doit être égal au nombre d'entité sous-jacentes"
"sonoff_trvzb_nb_entities_incorrect": "Le nombre d'entités spécifiques au Sonoff TRVZB doit être égal au nombre d'entité sous-jacentes"
},
"abort": {
"already_configured": "Le device est déjà configuré"
@@ -500,8 +504,7 @@
"auto_regulation_medium": "Moyenne",
"auto_regulation_light": "Légère",
"auto_regulation_expert": "Expert",
"auto_regulation_none": "Aucune",
"auto_regulation_valve": "Contrôle direct de la vanne"
"auto_regulation_none": "Aucune"
}
},
"auto_fan_mode": {

View File

@@ -53,8 +53,8 @@ class UnderlyingEntityType(StrEnum):
# a valve
VALVE = "valve"
# a direct valve regulation
VALVE_REGULATION = "valve_regulation"
# a Sonoff TRVZB
SONOFF_TRVZB = "sonoff_trvzb"
class UnderlyingEntity:
@@ -871,11 +871,7 @@ class UnderlyingValve(UnderlyingEntity):
_last_sent_temperature = None
def __init__(
self,
hass: HomeAssistant,
thermostat: Any,
valve_entity_id: str,
entity_type: UnderlyingEntityType = UnderlyingEntityType.VALVE,
self, hass: HomeAssistant, thermostat: Any, valve_entity_id: str
) -> None:
"""Initialize the underlying valve"""
@@ -924,7 +920,7 @@ class UnderlyingValve(UnderlyingEntity):
async def turn_on(self):
"""Nothing to do for Valve because it cannot be turned on"""
await self.set_valve_open_percent()
self.set_valve_open_percent()
async def set_hvac_mode(self, hvac_mode: HVACMode) -> bool:
"""Set the HVACmode. Returns true if something have change"""
@@ -962,8 +958,11 @@ class UnderlyingValve(UnderlyingEntity):
force=False,
):
"""We use this function to change the on_percent"""
# if force:
await self.set_valve_open_percent()
if force:
# self._percent_open = self.cap_sent_value(self._percent_open)
# await self.send_percent_open()
# avoid to send 2 times the same value at startup
self.set_valve_open_percent()
@overrides
def cap_sent_value(self, value) -> float:
@@ -996,7 +995,7 @@ class UnderlyingValve(UnderlyingEntity):
return new_value
async def set_valve_open_percent(self):
def set_valve_open_percent(self):
"""Update the valve open percent"""
caped_val = self.cap_sent_value(self._thermostat.valve_open_percent)
if self._percent_open == caped_val:
@@ -1010,16 +1009,19 @@ class UnderlyingValve(UnderlyingEntity):
"%s - Setting valve ouverture percent to %s", self, self._percent_open
)
# Send the change to the valve, in background
# self._hass.create_task(self.send_percent_open())
await self.send_percent_open()
self._hass.create_task(self.send_percent_open())
def remove_entity(self):
"""Remove the entity after stopping its cycle"""
self._cancel_cycle()
class UnderlyingValveRegulation(UnderlyingValve):
"""A specific underlying class for Valve regulation"""
class UnderlyingSonoffTRVZB(UnderlyingValve):
"""A specific underlying class for Sonoff TRVZB TRV"""
_offset_calibration_entity_id: str
_opening_degree_entity_id: str
_closing_degree_entity_id: str
def __init__(
self,
@@ -1030,21 +1032,16 @@ class UnderlyingValveRegulation(UnderlyingValve):
closing_degree_entity_id: str,
climate_underlying: UnderlyingClimate,
) -> None:
"""Initialize the underlying TRV with valve regulation"""
super().__init__(
hass,
thermostat,
opening_degree_entity_id,
entity_type=UnderlyingEntityType.VALVE_REGULATION,
)
self._offset_calibration_entity_id: str = offset_calibration_entity_id
self._opening_degree_entity_id: str = opening_degree_entity_id
self._closing_degree_entity_id: str = closing_degree_entity_id
"""Initialize the underlying Sonoff TRV"""
super().__init__(hass, thermostat, opening_degree_entity_id)
self._offset_calibration_entity_id = offset_calibration_entity_id
self._opening_degree_entity_id = opening_degree_entity_id
self._closing_degree_entity_id = closing_degree_entity_id
self._climate_underlying = climate_underlying
self._is_min_max_initialized: bool = False
self._max_opening_degree: float = None
self._min_offset_calibration: float = None
self._max_offset_calibration: float = None
self._is_min_max_initialized = False
self._max_opening_degree = None
self._min_offset_calibration = None
self._max_offset_calibration = None
async def send_percent_open(self):
"""Send the percent open to the underlying valve"""
@@ -1055,21 +1052,17 @@ class UnderlyingValveRegulation(UnderlyingValve):
self._max_opening_degree = self._hass.states.get(
self._opening_degree_entity_id
).attributes.get("max")
self._min_offset_calibration = self._hass.states.get(
self._offset_calibration_entity_id
).attributes.get("min")
self._max_offset_calibration = self._hass.states.get(
self._offset_calibration_entity_id
).attributes.get("max")
if self.have_offset_calibration_entity:
self._min_offset_calibration = self._hass.states.get(
self._offset_calibration_entity_id
).attributes.get("min")
self._max_offset_calibration = self._hass.states.get(
self._offset_calibration_entity_id
).attributes.get("max")
self._is_min_max_initialized = self._max_opening_degree is not None and (
not self.have_offset_calibration_entity
or (
self._min_offset_calibration is not None
and self._max_offset_calibration is not None
)
self._is_min_max_initialized = (
self._max_opening_degree is not None
and self._min_offset_calibration is not None
and self._max_offset_calibration is not None
)
if not self._is_min_max_initialized:
@@ -1083,7 +1076,7 @@ class UnderlyingValveRegulation(UnderlyingValve):
# Send closing_degree if set
closing_degree = None
if self.have_closing_degree_entity:
if self._closing_degree_entity_id is not None:
await self._send_value_to_number(
self._closing_degree_entity_id,
closing_degree := self._max_opening_degree - self._percent_open,
@@ -1091,7 +1084,7 @@ class UnderlyingValveRegulation(UnderlyingValve):
# send offset_calibration to the difference between target temp and local temp
offset = None
if self.have_offset_calibration_entity:
if self._offset_calibration_entity_id is not None:
if (
(local_temp := self._climate_underlying.underlying_current_temperature)
is not None
@@ -1116,7 +1109,7 @@ class UnderlyingValveRegulation(UnderlyingValve):
)
_LOGGER.debug(
"%s - valve regulation - I have sent offset_calibration=%s opening_degree=%s closing_degree=%s",
"%s - SonoffTRVZB - I have sent offset_calibration=%s opening_degree=%s closing_degree=%s",
self,
offset,
self._percent_open,
@@ -1138,16 +1131,6 @@ class UnderlyingValveRegulation(UnderlyingValve):
"""The offset_calibration_entity_id"""
return self._closing_degree_entity_id
@property
def have_closing_degree_entity(self) -> bool:
"""Return True if the underlying have a closing_degree entity"""
return self._closing_degree_entity_id is not None
@property
def have_offset_calibration_entity(self) -> bool:
"""Return True if the underlying have a offset_calibration entity"""
return self._offset_calibration_entity_id is not None
@property
def hvac_modes(self) -> list[HVACMode]:
"""Get the hvac_modes"""
@@ -1155,19 +1138,6 @@ class UnderlyingValveRegulation(UnderlyingValve):
return []
return [HVACMode.OFF, HVACMode.HEAT]
@overrides
async def start_cycle(
self,
hvac_mode: HVACMode,
_1,
_2,
_3,
force=False,
):
"""We use this function to change the on_percent"""
# if force:
await self.set_valve_open_percent()
@property
def is_device_active(self):
"""If the opening valve is open."""
@@ -1175,16 +1145,3 @@ class UnderlyingValveRegulation(UnderlyingValve):
return get_safe_float(self._hass, self._opening_degree_entity_id) > 0
except Exception: # pylint: disable=broad-exception-caught
return False
@property
def valve_entity_ids(self) -> [str]:
"""get an arrary with all entityd id of the valve"""
ret = []
for entity in [
self.opening_degree_entity_id,
self.closing_degree_entity_id,
self.offset_calibration_entity_id,
]:
if entity:
ret.append(entity)
return ret

View File

@@ -1,211 +0,0 @@
# Some Essential Add-Ons
- [Some Essential Add-Ons](#some-essential-add-ons)
- [the Versatile Thermostat UI Card](#the-versatile-thermostat-ui-card)
- [the Scheduler Component!](#the-scheduler-component)
- [Regulation curves with Plotly to Fine-Tune Your Thermostat](#regulation-curves-with-plotly-to-fine-tune-your-thermostat)
- [Event notification with the AppDaemon NOTIFIER](#event-notification-with-the-appdaemon-notifier)
## the Versatile Thermostat UI Card
A dedicated card for the Versatile Thermostat has been developed (based on Better Thermostat). It is available here: [Versatile Thermostat UI Card](https://github.com/jmcollin78/versatile-thermostat-ui-card) and offers a modern view of all the VTherm statuses:
![image](https://github.com/jmcollin78/versatile-thermostat-ui-card/blob/master/assets/1.png?raw=true)
## the Scheduler Component!
To make the most out of the Versatile Thermostat, I recommend using it with the [Scheduler Component](https://github.com/nielsfaber/scheduler-component). The scheduler component provides climate scheduling based on predefined modes. While this feature is somewhat limited with the generic thermostat, it becomes very powerful when paired with the Versatile Thermostat.
Assuming you have installed both the Versatile Thermostat and the Scheduler Component, heres an example:
In Scheduler, add a schedule:
![image](https://user-images.githubusercontent.com/1717155/119146454-ee1a9d80-ba4a-11eb-80ae-3074c3511830.png)
Choose the "Climate" group, select one (or more) entity, pick "MAKE SCHEME," and click next:
(You can also choose "SET PRESET," but I prefer "MAKE SCHEME.")
![image](https://user-images.githubusercontent.com/1717155/119147210-aa746380-ba4b-11eb-8def-479a741c0ba7.png)
Define your mode scheme and save:
![image](https://user-images.githubusercontent.com/1717155/119147784-2f5f7d00-ba4c-11eb-9de4-5e62ff5e71a8.png)
In this example, I set ECO mode during the night and when no one is home during the day, BOOST in the morning, and COMFORT in the evening.
I hope this example helps; feel free to share your feedback!
## Regulation curves with Plotly to Fine-Tune Your Thermostat
You can obtain a curve similar to the one shown in [some results](#some-results) using a Plotly graph configuration by leveraging the thermostat's custom attributes described [here](#custom-attributes):
Replace the values between `[[ ]]` with your own.
<details>
```yaml
- type: custom:plotly-graph
entities:
- entity: '[[climate]]'
attribute: temperature
yaxis: y1
name: Consigne
- entity: '[[climate]]'
attribute: current_temperature
yaxis: y1
name:
- entity: '[[climate]]'
attribute: ema_temp
yaxis: y1
name: Ema
- entity: '[[climate]]'
attribute: on_percent
yaxis: y2
name: Power percent
fill: tozeroy
fillcolor: rgba(200, 10, 10, 0.3)
line:
color: rgba(200, 10, 10, 0.9)
- entity: '[[slope]]'
name: Slope
fill: tozeroy
yaxis: y9
fillcolor: rgba(100, 100, 100, 0.3)
line:
color: rgba(100, 100, 100, 0.9)
hours_to_show: 4
refresh_interval: 10
height: 800
config:
scrollZoom: true
layout:
margin:
r: 50
legend:
x: 0
'y': 1.2
groupclick: togglegroup
title:
side: top right
yaxis:
visible: true
position: 0
yaxis2:
visible: true
position: 0
fixedrange: true
range:
- 0
- 1
yaxis9:
visible: true
fixedrange: false
range:
- -2
- 2
position: 1
xaxis:
rangeselector:
'y': 1.1
x: 0.7
buttons:
- count: 1
step: hour
- count: 12
step: hour
- count: 1
step: day
- count: 7
step: day
```
</details>
Example of curves obtained with Plotly:
![image](images/plotly-curves.png)
## Event notification with the AppDaemon NOTIFIER
This automation leverages the excellent AppDaemon app named NOTIFIER, developed by Horizon Domotique, demonstrated [here](https://www.youtube.com/watch?v=chJylIK0ASo&ab_channel=HorizonDomotique), and the code is available [here](https://github.com/jlpouffier/home-assistant-config/blob/master/appdaemon/apps/notifier.py). It allows users to be notified of security-related events occurring on any Versatile Thermostat.
This is a great example of using the notifications described here: [notification](#notifications).
<details>
```yaml
alias: Surveillance Mode Sécurité chauffage
description: Envoi une notification si un thermostat passe en mode sécurité ou power
trigger:
- platform: event
event_type: versatile_thermostat_security_event
id: versatile_thermostat_security_event
- platform: event
event_type: versatile_thermostat_power_event
id: versatile_thermostat_power_event
- platform: event
event_type: versatile_thermostat_temperature_event
id: versatile_thermostat_temperature_event
condition: []
action:
- choose:
- conditions:
- condition: trigger
id: versatile_thermostat_security_event
sequence:
- event: NOTIFIER
event_data:
action: send_to_jmc
title: >-
Radiateur {{ trigger.event.data.name }} - {{
trigger.event.data.type }} Sécurité
message: >-
Le radiateur {{ trigger.event.data.name }} est passé en {{
trigger.event.data.type }} sécurité car le thermomètre ne répond
plus.\n{{ trigger.event.data }}
callback:
- title: Stopper chauffage
event: stopper_chauffage
image_url: /media/local/alerte-securite.jpg
click_url: /lovelace-chauffage/4
icon: mdi:radiator-off
tag: radiateur_security_alerte
persistent: true
- conditions:
- condition: trigger
id: versatile_thermostat_power_event
sequence:
- event: NOTIFIER
event_data:
action: send_to_jmc
title: >-
Radiateur {{ trigger.event.data.name }} - {{
trigger.event.data.type }} Délestage
message: >-
Le radiateur {{ trigger.event.data.name }} est passé en {{
trigger.event.data.type }} délestage car la puissance max est
dépassée.\n{{ trigger.event.data }}
callback:
- title: Stopper chauffage
event: stopper_chauffage
image_url: /media/local/alerte-delestage.jpg
click_url: /lovelace-chauffage/4
icon: mdi:radiator-off
tag: radiateur_power_alerte
persistent: true
- conditions:
- condition: trigger
id: versatile_thermostat_temperature_event
sequence:
- event: NOTIFIER
event_data:
action: send_to_jmc
title: >-
Le thermomètre du radiateur {{ trigger.event.data.name }} ne
répond plus
message: >-
Le thermomètre du radiateur {{ trigger.event.data.name }} ne
répond plus depuis longtemps.\n{{ trigger.event.data }}
image_url: /media/local/thermometre-alerte.jpg
click_url: /lovelace-chauffage/4
icon: mdi:radiator-disabled
tag: radiateur_thermometre_alerte
persistent: true
mode: queued
max: 30
```
</details>

View File

@@ -1,67 +0,0 @@
# The Different Algorithms Used
- [The Different Algorithms Used](#the-different-algorithms-used)
- [The TPI Algorithm](#the-tpi-algorithm)
- [Configuring the TPI Algorithm Coefficients](#configuring-the-tpi-algorithm-coefficients)
- [Principle](#principle)
- [The Self-Regulation Algorithm (Without Valve Control)](#the-self-regulation-algorithm-without-valve-control)
- [The Auto-Start/Stop Function Algorithm](#the-auto-startstop-function-algorithm)
## The TPI Algorithm
### Configuring the TPI Algorithm Coefficients
If you have selected a thermostat of type `over_switch`, `over_valve`, or `over_climate` with self-regulation in `Direct Valve Control` mode and choose the "TPI" option in the menu, you will land on this page:
![image](images/config-tpi.png)
You need to provide:
1. the coefficient `coef_int` for the TPI algorithm,
2. the coefficient `coef_ext` for the TPI algorithm.
### Principle
The TPI algorithm calculates the On vs Off percentage for the radiator at each cycle, using the target temperature, the current room temperature, and the current outdoor temperature. This algorithm is only applicable for Versatile Thermostats operating in `over_switch` and `over_valve` modes.
The percentage is calculated using this formula:
on_percent = coef_int * (target_temperature - current_temperature) + coef_ext * (target_temperature - outdoor_temperature)
Then, the algorithm ensures that 0 <= on_percent <= 1.
The default values for `coef_int` and `coef_ext` are `0.6` and `0.01`, respectively. These default values are suitable for a standard well-insulated room.
When adjusting these coefficients, keep the following in mind:
1. **If the target temperature is not reached** after stabilization, increase `coef_ext` (the `on_percent` is too low),
2. **If the target temperature is exceeded** after stabilization, decrease `coef_ext` (the `on_percent` is too high),
3. **If reaching the target temperature is too slow**, increase `coef_int` to provide more power to the heater,
4. **If reaching the target temperature is too fast and oscillations occur** around the target, decrease `coef_int` to provide less power to the radiator.
In `over_valve` mode, the `on_percent` value is converted to a percentage (0 to 100%) and directly controls the valve's opening level.
## The Self-Regulation Algorithm (Without Valve Control)
The self-regulation algorithm can be summarized as follows:
1. Initialize the target temperature as the VTherm setpoint,
2. If self-regulation is enabled:
1. Calculate the regulated temperature (valid for a VTherm),
2. Use this temperature as the target,
3. For each underlying device of the VTherm:
1. If "Use Internal Temperature" is checked:
1. Calculate the compensation (`trv_internal_temp - room_temp`),
2. Add the offset to the target temperature,
3. Send the target temperature (= regulated_temp + (internal_temp - room_temp)) to the underlying device.
## The Auto-Start/Stop Function Algorithm
The algorithm used in the auto-start/stop function operates as follows:
1. If "Enable Auto-Start/Stop" is off, stop here.
2. If VTherm is on and in Heating mode, when `error_accumulated` < `-error_threshold` -> turn off and save HVAC mode.
3. If VTherm is on and in Cooling mode, when `error_accumulated` > `error_threshold` -> turn off and save HVAC mode.
4. If VTherm is off and the saved HVAC mode is Heating, and `current_temperature + slope * dt <= target_temperature`, turn on and set the HVAC mode to the saved mode.
5. If VTherm is off and the saved HVAC mode is Cooling, and `current_temperature + slope * dt >= target_temperature`, turn on and set the HVAC mode to the saved mode.
6. `error_threshold` is set to `10 (° * min)` for slow detection, `5` for medium, and `2` for fast.
`dt` is set to `30 min` for slow, `15 min` for medium, and `7 min` for fast detection levels.
The function is detailed [here](https://github.com/jmcollin78/versatile_thermostat/issues/585).

View File

@@ -1,45 +0,0 @@
- [Choosing Basic Attributes](#choosing-basic-attributes)
- [Choosing the features to Use](#choosing-the-features-to-use)
# Choosing Basic Attributes
Select the "Main Attributes" menu.
![image](images/config-main.png)
Provide the mandatory main attributes. These attributes are common to all VTherms:
1. A name (this will be both the integration's name and the `climate` entity name),
2. An entity ID of a temperature sensor that provides the room temperature where the radiator is installed,
3. An optional sensor entity providing the last seen date and time of the sensor (`last_seen`). If available, specify it here. It helps prevent safety shutdowns when the temperature is stable, and the sensor stops reporting for a long time (see [here](troubleshooting.md#why-does-my-versatile-thermostat-go-into-safety-mode)),
4. A cycle duration in minutes. At each cycle:
1. For `over_switch`: VTherm will turn the radiator on/off, modulating the proportion of time it is on,
2. For `over_valve`: VTherm will calculate a new valve opening level and send it if it has changed,
3. For `over_climate`: The cycle performs basic controls and recalculates the self-regulation coefficients. The cycle may result in a new setpoint sent to underlying devices or a valve opening adjustment in the case of a controllable TRV.
5. The equipment's power, which will activate power and energy consumption sensors for the device. If multiple devices are linked to the same VTherm, specify the total maximum power of all devices here,
6. The option to use additional parameters from centralized configuration:
1. Outdoor temperature sensor,
2. Minimum/maximum temperature and temperature step size,
7. The option to control the thermostat centrally. See [centralized control](#centralized-control),
8. A checkbox if this VTherm is used to trigger a central boiler.
> ![Tip](images/tips.png) _*Notes*_
> 1. With the `over_switch` and `over_valve` types, calculations are performed at each cycle. In case of changing conditions, you will need to wait for the next cycle to see a change. For this reason, the cycle should not be too long. **5 minutes is a good value**, but it should be adjusted to your heating type. The greater the inertia, the longer the cycle should be. See [Tuning examples](tuning-examples.md).
> 2. If the cycle is too short, the radiator may never reach the target temperature. For example, with a storage heater, it will be unnecessarily activated.
# Choosing the features to Use
Select the "Features" menu.
![image](images/config-features.png)
Choose the features you want to use for this VTherm:
1. **Opening detection** (doors, windows) stops heating when an opening is detected. (see [managing openings](feature-window.md)),
2. **Motion detection**: VTherm can adjust the target temperature when motion is detected in the room. (see [motion detection](feature-motion.md)),
3. **Power management**: VTherm can stop a device if the power consumption in your home exceeds a threshold. (see [load-shedding management](feature-power.md)),
4. **Presence detection**: If you have a sensor indicating presence or absence in your home, you can use it to change the target temperature. See [presence management](feature-presence.md). Note the difference between this function and motion detection: presence is typically used at the home level, while motion detection is more room-specific.
5. **Automatic start/stop**: For `over_climate` VTherms only. This function stops a device when VTherm detects it will not be needed for a while. It uses the temperature curve to predict when the device will be needed again and turns it back on at that time. See [automatic start/stop management](feature-auto-start-stop.md).
> ![Tip](images/tips.png) _*Notes*_
> 1. The list of available functions adapts to your VTherm type.
> 2. When you enable a function, a new menu entry is added to configure it.
> 3. You cannot validate the creation of a VTherm if all parameters for all enabled functions have not been configured.

View File

@@ -1,71 +0,0 @@
# Choosing a VTherm
- [Choosing a VTherm](#choosing-a-vtherm)
- [Creating a New Versatile Thermostat](#creating-a-new-versatile-thermostat)
- [Choosing a VTherm Type](#choosing-a-vtherm-type)
- [Centralized configuration](#centralized-configuration)
- [VTherm over a switch](#vtherm-over-a-switch)
- [VTherm over another thermostat](#vtherm-over-another-thermostat)
- [VTherm over a valve](#vtherm-over-a-valve)
- [Making the right choice](#making-the-right-choice)
- [Reference Article](#reference-article)
> ![Tip](images/tips.png) _*Notes*_
>
> There are three ways to work with VTherms:
> 1. Each Versatile Thermostat is fully configured independently. Choose this option if you do not want any centralized configuration or management.
> 2. Some aspects are configured centrally. For example, you can define the minimum/maximum temperatures, open window detection parameters, etc., at a single central instance. For each VTherm you configure, you can then choose to use the central configuration or override it with custom parameters.
> 3. In addition to centralized configuration, all VTherms can be controlled by a single `select` entity called `central_mode`. This feature allows you to stop/start/set frost protection/etc. for all VTherms at once. For each VTherm, you can specify if it is affected by this `central_mode`.
## Creating a New Versatile Thermostat
Click on "Add Integration" on the integration page (or click 'Add device' in the integration page)
![image](images/add-an-integration.png)
then:
![image](images/config-main0.png)
The configuration can be modified via the same interface. Simply select the thermostat to modify, press "Configure," and you will be able to change some parameters or settings.
Follow the configuration steps by selecting the menu option to configure.
# Choosing a VTherm Type
## Centralized configuration
This option allows you to configure certain repetitive aspects for all VTherms at once, such as:
1. Parameters for different algorithms (TPI, open window detection, motion detection, power sensors for your home, presence detection). These parameters apply across all VTherms. You only need to enter them once in `Centralized Configuration`. This configuration does not create a VTherm itself but centralizes parameters that would be tedious to re-enter for each VTherm. Note that you can override these parameters on individual VTherms to specialize them if needed.
2. Configuration for controlling a central heating system,
3. Certain advanced parameters, such as safety settings.
## VTherm over a switch
This VTherm type controls a switch that turns a radiator on or off. The switch can be a physical switch directly controlling a radiator (often electric) or a virtual switch that can perform any action when turned on or off. The latter type can, for example, control pilot wire switches or DIY pilot wire solutions with diodes. VTherm modulates the proportion of time the radiator is on (`on_percent`) to achieve the desired temperature. If it is cold, it turns on more frequently (up to 100%); if it is warm, it reduces the on time.
The underlying entities for this type are `switches` or `input_booleans`.
## VTherm over another thermostat
When your device is controlled by a `climate` entity in Home Assistant and you only have access to this, you should use this VTherm type. In this case, VTherm simply adjusts the target temperature of the underlying `climate` entity.
This type also includes advanced self-regulation features to adjust the setpoint sent to the underlying device, helping to achieve the target temperature faster and mitigating poor internal regulation. For example, if the device's internal thermometer is too close to the heating element, it may incorrectly assume the room is warm while the setpoint is far from being achieved in other areas.
Since version 6.8, this VTherm type can also regulate directly by controlling the valve. Ideal for controllable TRVs, this type is recommended if you have such devices.
The underlying entities for this VTherm type are exclusively `climate`.
## VTherm over a valve
If the only entity available to regulate your radiator's temperature is a `number` entity, you should use the `over_valve` type. VTherm adjusts the valve opening based on the difference between the target temperature and the actual room temperature (and the outdoor temperature, if available).
This type can be used for TRVs without an associated `climate` entity or other DIY solutions exposing a `number` entity.
# Making the right choice
> ![Tip](images/tips.png) _*How to Choose the Type*_
> Choosing the correct type is crucial. It cannot be changed later via the configuration interface. To make the right choice, consider the following questions:
> 1. **What type of equipment will I control?** Follow this order of preference:
> 1. If you have a controllable thermostatic valve (TRV) in Home Assistant through a `number` entity (e.g., a Shelly TRV), choose the `over_valve` type. This is the most direct type and ensures the best regulation.
> 2. If you have an electric radiator (with or without a pilot wire) controlled by a `switch` entity to turn it on/off, then the `over_switch` type is preferable. Regulation will be managed by the Versatile Thermostat based on the temperature measured by your thermometer at its placement location.
> 3. In all other cases, use the `over_climate` mode. You retain your original `climate` entity, and the Versatile Thermostat "only" controls the on/off state and target temperature of your original thermostat. Regulation is handled by your original thermostat in this case. This mode is particularly suited for all-in-one reversible air conditioning systems exposed as a `climate` entity in Home Assistant. Advanced self-regulation can achieve the setpoint faster by forcing the setpoint or directly controlling the valve when possible.
> 2. **What type of regulation do I want?** If the controlled equipment has its own built-in regulation mechanism (e.g., HVAC systems, certain TRVs) and it works well, choose `over_climate`. For TRVs with a controllable valve in Home Assistant, the `over_climate` type with `Direct Valve Control` self-regulation is the best choice.
# Reference Article
For more information on these concepts, refer to this article (in French): https://www.hacf.fr/optimisation-versatile-thermostat/#optimiser-vos-vtherm

View File

@@ -1,53 +0,0 @@
# Advanced Configuration
- [Advanced Configuration](#advanced-configuration)
- [Advanced Settings](#advanced-settings)
- [Minimum Activation Delay](#minimum-activation-delay)
- [Safety Mode](#safety-mode)
These settings refine the thermostat's operation, particularly the safety mechanism for a _VTherm_. Missing temperature sensors (room or outdoor) can pose a risk to your home. For instance, if the temperature sensor gets stuck at 10°C, the `over_climate` or `over_valve` _VTherm_ types will command maximum heating of the underlying devices, which could lead to room overheating or even property damage, at worst resulting in a fire hazard.
To prevent this, _VTherm_ ensures that thermometers report values regularly. If they don't, the _VTherm_ switches to a special mode called Safety Mode. This mode ensures minimal heating to prevent the opposite risk: a completely unheated home in the middle of winter, for example.
The challenge lies in that some thermometers—especially battery-operated ones—only send temperature updates when the value changes. It is entirely possible to receive no temperature updates for hours without the thermometer failing. The parameters below allow fine-tuning of the thresholds for activating Safety Mode.
If your thermometer has a `last seen` attribute indicating the last contact time, you can specify it in the _VTherm_'s main attributes to greatly reduce false Safety Mode activations. See [configuration](base-attributes.md#choosing-base-attributes) and [troubleshooting](troubleshooting.md#why-does-my-versatile-thermostat-switch-to-safety-mode).
For `over_climate` _VTherms_, which self-regulate, Safety Mode is disabled. In this case, there is no danger, only the risk of an incorrect temperature.
## Advanced Settings
The advanced configuration form looks like this:
![image](images/config-advanced.png)
### Minimum Activation Delay
The first delay (`minimal_activation_delay_sec`) in seconds is the minimum acceptable delay to turn on the heating. If the calculated activation time is shorter than this value, the heating remains off. This parameter only applies to _VTherm_ with cyclic triggering `over_switch`. If the activation time is too short, rapid switching will not allow the device to heat up properly.
### Safety Mode
The second delay (`security_delay_min`) is the maximum time between two temperature measurements before the _VTherm_ switches to Safety Mode.
The third parameter (`security_min_on_percent`) is the minimum `on_percent` below which Safety Mode will not be activated. This setting prevents activating Safety Mode if the controlled radiator does not heat sufficiently. In this case, there is no physical risk to the home, only the risk of overheating or underheating.
Setting this parameter to `0.00` will trigger Safety Mode regardless of the last heating setting, whereas `1.00` will never trigger Safety Mode (effectively disabling the feature). This can be useful to adapt the safety mechanism to your specific needs.
The fourth parameter (`security_default_on_percent`) defines the `on_percent` used when the thermostat switches to `security` mode. Setting it to `0` will turn off the thermostat in Safety Mode, while setting it to a value like `0.2` (20%) ensures some heating remains, avoiding a completely frozen home in case of a thermometer failure.
It is possible to disable Safety Mode triggered by missing data from the outdoor thermometer. Since the outdoor thermometer usually has a minor impact on regulation (depending on your configuration), it might not be critical if it's unavailable. To do this, add the following lines to your `configuration.yaml`:
```yaml
versatile_thermostat:
...
safety_mode:
check_outdoor_sensor: false
```
By default, the outdoor thermometer can trigger Safety Mode if it stops sending data. Remember that Home Assistant must be restarted for these changes to take effect. This setting applies to all _VTherms_ sharing the outdoor thermometer.
> ![Tip](images/tips.png) _*Notes*_
> 1. When the temperature sensor resumes reporting, the preset will be restored to its previous value.
> 2. Two temperature sources are required: the indoor and outdoor temperatures. Both must report values, or the thermostat will switch to "security" preset.
> 3. An action is available to adjust the three safety parameters. This can help adapt Safety Mode to your needs.
> 4. For normal use, `security_default_on_percent` should be lower than `security_min_on_percent`.
> 5. If you use the Versatile Thermostat UI card (see [here](additions.md#better-with-the-versatile-thermostat-ui-card)), a _VTherm_ in Safety Mode is indicated by a gray overlay showing the faulty thermometer and the time since its last value update: ![safety mode](images/safety-mode-icon.png).

View File

@@ -1,39 +0,0 @@
# Auto-start / Auto-stop
- [Auto-start / Auto-stop](#auto-start--auto-stop)
- [Configure Auto-start/stop](#configure-auto-startstop)
- [Usage](#usage)
This feature allows _VTherm_ to stop an appliance that doesn't need to be on and restart it when conditions require it. This function includes three settings that control how quickly the appliance is stopped and restarted.
Exclusively reserved for _VTherm_ of type `over_climate`, it applies to the following use case:
1. Your appliance is permanently powered on and consumes electricity even when heating (or cooling) is not needed. This is often the case with heat pumps (_PAC_) that consume power even in standby mode.
2. The temperature conditions are such that heating (or cooling) is not needed for a long period: the setpoint is higher (or lower) than the room temperature.
3. The temperature rises (or falls), remains stable, or falls (or rises) slowly.
In such cases, it is preferable to ask the appliance to turn off to avoid unnecessary power consumption in standby mode.
## Configure Auto-start/stop
To use this feature, you need to:
1. Add the `With auto-start and stop` function in the 'Functions' menu.
2. Set the detection level in the 'Auto-start/stop' option that appears when the function is activated. Choose the detection level between 'Slow', 'Medium', and 'Fast'. With the 'Fast' setting, stops and restarts will occur more frequently.
![image](images/config-auto-start-stop.png)
The 'Slow' setting allows about 30 minutes between a stop and a restart,
The 'Medium' setting sets the threshold to about 15 minutes, and the 'Fast' setting puts it at 7 minutes.
Note that these are not absolute settings since the algorithm takes into account the slope of the room temperature curve to respond accordingly. It is still possible that a restart occurs shortly after a stop if the temperature drops significantly.
## Usage
Once the function is configured, you will now have a new `switch` type entity that allows you to enable or disable auto-start/stop without modifying the configuration. This entity is available on the _VTherm_ device and is named `switch.<name>_enable_auto_start_stop`.
![image](images/enable-auto-start-stop-entity.png)
Check the box to allow auto-start and auto-stop, and leave it unchecked to disable the feature.
> ![Tip](images/tips.png) _*Notes*_
> 1. The detection algorithm is described [here](algorithms.md#auto-startstop-algorithm).
> 2. Some appliances (boilers, underfloor heating, _PAC_, etc.) may not like being started/stopped too frequently. If that's the case, it might be better to disable the function when you know the appliance will be used. For example, I disable this feature during the day when presence is detected because I know my _PAC_ will turn on often. I enable auto-start/stop at night or when no one is home, as the setpoint is lowered and it rarely triggers.
> 3. If you use the Versatile Thermostat UI card (see [here](additions.md#better-with-the-versatile-thermostat-ui-card)), a checkbox is directly visible on the card to disable auto-start/stop, and a _VTherm_ stopped by auto-start/stop is indicated by the icon: ![auto-start/stop icon](images/auto-start-stop-icon.png).

View File

@@ -1,123 +0,0 @@
# Le contrôle d'une chaudière centrale# Controlling a Central Boiler
- [Le contrôle d'une chaudière centrale# Controlling a Central Boiler](#le-contrôle-dune-chaudière-centrale-controlling-a-central-boiler)
- [Principle](#principle)
- [Configuration](#configuration)
- [How to Find the Right Action?](#how-to-find-the-right-action)
- [Events](#events)
- [Warning](#warning)
You can control a centralized boiler. As long as it's possible to trigger or stop the boiler from Home Assistant, Versatile Thermostat will be able to control it directly.
## Principle
The basic principle is as follows:
1. A new entity of type `binary_sensor`, named by default `binary_sensor.central_boiler`, is added.
2. In the configuration of the _VTherms_, you specify whether the _VTherm_ should control the boiler. In a heterogeneous installation, some _VTherms_ should control the boiler, and others should not. Therefore, you need to indicate in each _VTherm_ configuration whether it controls the boiler.
3. The `binary_sensor.central_boiler` listens for state changes in the equipment of the _VTherms_ marked as controlling the boiler.
4. When the number of devices controlled by the _VTherm_ requesting heating (i.e., when its `hvac_action` changes to `Heating`) exceeds a configurable threshold, the `binary_sensor.central_boiler` turns `on`, and **if an activation service has been configured, that service is called**.
5. If the number of devices requesting heating drops below the threshold, the `binary_sensor.central_boiler` turns `off`, and **if a deactivation service has been configured, that service is called**.
6. You have access to two entities:
- A `number` type entity, named by default `number.boiler_activation_threshold`, which gives the activation threshold. This threshold is the number of devices (radiators) requesting heating.
- A `sensor` type entity, named by default `sensor.nb_device_active_for_boiler`, which shows the number of devices requesting heating. For example, a _VTherm_ with 4 valves, 3 of which request heating, will make this sensor show 3. Only the devices from _VTherms_ marked to control the central boiler are counted.
You therefore always have the information to manage and adjust the triggering of the boiler.
All these entities are linked to the central configuration service:
![Boiler Control Entities](images/entitites-central-boiler.png)
## Configuration
To configure this feature, you need a centralized configuration (see [Configuration](#configuration)) and check the 'Add Central Boiler' box:
![Add a Central Boiler](images/config-central-boiler-1.png)
On the next page, you can provide the configuration for the actions (e.g., services) to be called when the boiler is turned on/off:
![Add a Central Boiler](images/config-central-boiler-2.png)
The actions (e.g., services) are configured as described on the page:
1. The general format is `entity_id/service_id[/attribute:value]` (where `/attribute:value` is optional).
2. `entity_id` is the name of the entity controlling the boiler in the form `domain.entity_name`. For example: `switch.chaudiere` for a boiler controlled by a switch, or `climate.chaudière` for a boiler controlled by a thermostat, or any other entity that allows boiler control (there is no limitation). You can also toggle inputs (`helpers`) such as `input_boolean` or `input_number`.
3. `service_id` is the name of the service to be called in the form `domain.service_name`. For example: `switch.turn_on`, `switch.turn_off`, `climate.set_temperature`, `climate.set_hvac_mode` are valid examples.
4. Some services require a parameter. This could be the 'HVAC Mode' for `climate.set_hvac_mode` or the target temperature for `climate.set_temperature`. This parameter should be configured in the format `attribute:value` at the end of the string.
Examples (to adjust to your case):
- `climate.chaudiere/climate.set_hvac_mode/hvac_mode:heat`: to turn the boiler thermostat on in heating mode.
- `climate.chaudiere/climate.set_hvac_mode/hvac_mode:off`: to turn off the boiler thermostat.
- `switch.pompe_chaudiere/switch.turn_on`: to turn on the switch powering the boiler pump.
- `switch.pompe_chaudiere/switch.turn_off`: to turn off the switch powering the boiler pump.
- ...
### How to Find the Right Action?
To find the correct action to use, it's best to go to "Developer Tools / Services", search for the action to call, the entity to control, and any required parameters.
Click 'Call Service'. If your boiler turns on, you have the correct configuration. Then switch to YAML mode and copy the parameters.
Example:
In "Developer Tools / Actions":
![Service Configuration](images/dev-tools-turnon-boiler-1.png)
In YAML mode:
![Service Configuration](images/dev-tools-turnon-boiler-2.png)
The service to configure will then be: `climate.sonoff/climate.set_hvac_mode/hvac_mode:heat` (note the removal of spaces in `hvac_mode:heat`).
Do the same for the off service, and youre ready to go.
## Events
Each successful boiler activation or deactivation sends an event from Versatile Thermostat. This can be captured by an automation, for example, to notify you of the change.
The events look like this:
An activation event:
```yaml
event_type: versatile_thermostat_central_boiler_event
data:
central_boiler: true
entity_id: binary_sensor.central_boiler
name: Central boiler
state_attributes: null
origin: LOCAL
time_fired: "2024-01-14T11:33:52.342026+00:00"
context:
id: 01HM3VZRJP3WYYWPNSDAFARW1T
parent_id: null
user_id: null
```yaml
event_type: versatile_thermostat_central_boiler_event
data:
central_boiler: true
entity_id: binary_sensor.central_boiler
name: Central boiler
state_attributes: null
origin: LOCAL
time_fired: "2024-01-14T11:33:52.342026+00:00"
context:
id: 01HM3VZRJP3WYYWPNSDAFARW1T
parent_id: null
user_id: null
```
Un évènement d'extinction :
```yaml
event_type: versatile_thermostat_central_boiler_event
data:
central_boiler: false
entity_id: binary_sensor.central_boiler
name: Central boiler
state_attributes: null
origin: LOCAL
time_fired: "2024-01-14T11:43:52.342026+00:00"
context:
id: 01HM3VZRJP3WYYWPNSDAFBRW1T
parent_id: null
user_id: null
```
## Warning
> ![Astuce](images/tips.png) _*Notes*_
>
> Software or home automation control of a central boiler may pose risks to its proper operation. Before using these functions, ensure that your boiler has proper safety features and that they are functioning correctly. For example, turning on a boiler with all valves closed can create excessive pressure.

View File

@@ -1,31 +0,0 @@
# Centralized Control
- [Centralized Control](#centralized-control)
- [Configuration of Centralized Control](#configuration-of-centralized-control)
- [Usage](#usage)
This feature allows you to control all your _VTherms_ from a single control point.
A typical use case is when you leave for an extended period and want to set all your _VTherms_ to frost protection, and when you return, you want to set them back to their initial state.
Centralized control is done from a special _VTherm_ called centralized configuration. See [here](creation.md#centralized-configuration) for more information.
## Configuration of Centralized Control
If you have set up a centralized configuration, you will have a new entity named `select.central_mode` that allows you to control all _VTherms_ with a single action.
![central_mode](images/central-mode.png)
This entity appears as a list of choices containing the following options:
1. `Auto`: the 'normal' mode where each _VTherm_ operates autonomously,
2. `Stopped`: all _VTherms_ are turned off (`hvac_off`),
3. `Heat only`: all _VTherms_ are set to heating mode if supported, otherwise they are stopped,
4. `Cool only`: all _VTherms_ are set to cooling mode if supported, otherwise they are stopped,
5. `Frost protection`: all _VTherms_ are set to frost protection mode if supported, otherwise they are stopped.
## Usage
For a _VTherm_ to be controllable centrally, its configuration attribute named `use_central_mode` must be true. This attribute is available in the configuration page `Main Attributes`.
![central_mode](images/use-central-mode.png)
This means you can control all _VTherms_ (those explicitly designated) with a single control.

View File

@@ -1,40 +0,0 @@
# Motion or Activity Detection
- [Motion or Activity Detection](#motion-or-activity-detection)
- [Configure Activity Mode or Motion Detection](#configure-activity-mode-or-motion-detection)
- [Usage](#usage)
This feature allows you to change presets when motion is detected in a room. If you don't want to heat your office when the room is occupied and only when the room is occupied, you need a motion (or presence) sensor in the room and configure this feature.
This function is often confused with the presence feature. They are complementary but not interchangeable. The 'motion' function is local to a room equipped with a motion sensor, while the 'presence' function is designed to be global to the entire home.
## Configure Activity Mode or Motion Detection
If you have chosen the `With motion detection` feature:
![image](images/config-motion.png)
What we need:
- a **motion sensor**. Entity ID of a motion sensor. The states of the motion sensor must be "on" (motion detected) or "off" (no motion detected),
- a **detection delay** (in seconds) defining how long we wait for confirmation of the motion before considering the motion. This parameter can be **greater than your motion sensor's delay**, otherwise, the detection will happen with every motion detected by the sensor,
- an **inactivity delay** (in seconds) defining how long we wait for confirmation of no motion before no longer considering the motion,
- a **"motion" preset**. We will use the temperature of this preset when activity is detected,
- a **"no motion" preset**. We will use the temperature of this second preset when no activity is detected.
## Usage
To tell a _VTherm_ that it should listen to the motion sensor, you must set it to the special 'Activity' preset. If you have installed the Versatile Thermostat UI card (see [here](additions.md#much-better-with-the-versatile-thermostat-ui-card)), this preset is displayed as follows: ![activity preset](images/activity-preset-icon.png).
You can then, upon request, set a _VTherm_ to motion detection mode.
The behavior will be as follows:
- we have a room with a thermostat set to activity mode, the "motion" mode chosen is comfort (21.5°C), the "no motion" mode chosen is Eco (18.5°C), and the motion delay is 30 seconds on detection and 5 minutes on the end of detection.
- the room has been empty for a while (no activity detected), the setpoint temperature in this room is 18.5°.
- someone enters the room, and activity is detected if the motion is present for at least 30 seconds. The temperature then goes up to 21.5°.
- if the motion is present for less than 30 seconds (quick passage), the temperature stays at 18.5°.
- imagine the temperature has gone up to 21.5°, when the person leaves the room, after 5 minutes the temperature is returned to 18.5°.
- if the person returns before the 5 minutes, the temperature stays at 21.5°.
> ![Tip](images/tips.png) _*Notes*_
> 1. As with other presets, `Activity` will only be offered if it is correctly configured. In other words, all 4 configuration keys must be set.
> 2. If you are using the Versatile Thermostat UI card (see [here](additions.md#much-better-with-the-versatile-thermostat-ui-card)), motion detection is represented as follows: ![motion](images/motion-detection-icon.png).

View File

@@ -1,46 +0,0 @@
# Power Management - Load Shedding
- [Power Management - Load Shedding](#power-management---load-shedding)
- [Configure Power Management](#configure-power-management)
This feature allows you to regulate the electricity consumption of your heaters. Known as load shedding, this feature enables you to limit the electrical consumption of your heating device if overcapacity conditions are detected.
You will need a **sensor for the total instantaneous power consumption** of your home, as well as a **sensor for the maximum allowed power**.
The behavior of this feature is basic:
1. when the _VTherm_ is about to turn on a device,
2. it compares the last known value of the power consumption sensor with the last value of the maximum allowed power. If there is a remaining margin greater than or equal to the declared power of the _VTherm_'s devices, then the _VTherm_ and its devices will be turned on. Otherwise, they will remain off until the next cycle.
WARNING: This very basic operation **is not a safety function** but more of an optimization feature to manage consumption at the cost of heating performance. Overloads may occur depending on the frequency of updates from your consumption sensors, and the actual power used by your devices. Therefore, you must always maintain a safety margin.
Typical use case:
1. you have an electricity meter limited to 11 kW,
2. you occasionally charge an electric vehicle at 5 kW,
3. that leaves 6 kW for everything else, including heating,
4. you have 1 kW of other equipment running,
5. you have declared a sensor (`input_number`) for the maximum allowed power at 9 kW (= 11 kW - the reserve for other devices - margin)
If the vehicle is charging, the total power consumed is 6 kW (5+1), and a _VTherm_ will only turn on if its declared power is 3 kW max (9 kW - 6 kW).
If the vehicle is charging and another _VTherm_ of 2 kW is running, the total power consumed is 8 kW (5+1+2), and a _VTherm_ will only turn on if its declared power is 1 kW max (9 kW - 8 kW). Otherwise, it will wait until the next cycle.
If the vehicle is not charging, the total power consumed is 1 kW, and a _VTherm_ will only turn on if its declared power is 8 kW max (9 kW - 1 kW).
## Configure Power Management
If you have chosen the `With power detection` feature, configure it as follows:
![image](images/config-power.png)
1. the entity ID of the **instantaneous power consumption sensor** for your home,
2. the entity ID of the **maximum allowed power sensor**,
3. the temperature to apply if load shedding is activated.
Note that all power values must have the same units (kW or W, for example).
Having a **maximum allowed power sensor** allows you to adjust the maximum power over time using a scheduler or automation.
> ![Tip](images/tips.png) _*Notes*_
>
> 1. In case of load shedding, the radiator is set to the preset named `power`. This is a hidden preset, and you cannot select it manually.
> 2. Always keep a margin, as the maximum power may briefly be exceeded while waiting for the next cycle calculation, or due to unregulated equipment.
> 3. If you don't want to use this feature, uncheck it in the 'Functions' menu.
> 4. If a _VTherm_ controls multiple devices, the **electrical consumption of your heating** must match the sum of the powers.
> 5. If you are using the Versatile Thermostat UI card (see [here](additions.md#much-better-with-the-versatile-thermostat-ui-card)), load shedding is represented as follows: ![load shedding](images/power-exceeded-icon.png).

View File

@@ -1,24 +0,0 @@
# Presence / Absence Management
- [Presence / Absence Management](#presence--absence-management)
- [Configure Presence (or Absence)](#configure-presence-or-absence)
## Configure Presence (or Absence)
If this feature is selected, it allows you to dynamically adjust the preset temperatures of the thermostat when presence (or absence) is detected. To do this, you need to configure the temperature to be used for each preset when presence is disabled. When the presence sensor turns off, these temperatures will be applied. When it turns back on, the "normal" temperature configured for the preset will be used. See [preset management](feature-presets.md).
To configure presence, fill out this form:
![image](images/config-presence.png)
For this, you simply need to configure an **occupancy sensor** whose state must be 'on' or 'home' if someone is present, or 'off' or 'not_home' otherwise.
Temperatures are configured in the entities of the device corresponding to your _VTherm_ (Settings/Integration/Versatile Thermostat/the vtherm).
WARNING: People groups do not work as a presence sensor. They are not recognized as a presence sensor. You need to use a template as described here [Using a People Group as a Presence Sensor](troubleshooting.md#using-a-people-group-as-a-presence-sensor).
> ![Tip](images/tips.png) _*Notes*_
>
> 1. The temperature change is immediate and is reflected on the front panel. The calculation will consider the new target temperature at the next cycle calculation.
> 2. You can use the direct person.xxxx sensor or a Home Assistant sensor group. The presence sensor handles the states `on` or `home` as present and `off` or `not_home` as absent.
> 3. To pre-heat your home when everyone is absent, you can add an `input_boolean` entity to your people group. If you set this `input_boolean` to 'On', the presence sensor will be forced to 'On' and the presets with presence will be used. You can also set this `input_boolean` to 'On' via an automation, for example, when you leave a zone to start preheating your home.

View File

@@ -1,30 +0,0 @@
# Presets (Pre-configured Settings)
- [Presets (Pre-configured Settings)](#presets-pre-configured-settings)
- [Configure Pre-configured Temperatures](#configure-pre-configured-temperatures)
## Configure Pre-configured Temperatures
The preset mode allows you to pre-configure the target temperature. Used in conjunction with Scheduler (see [scheduler](additions#the-scheduler-component)), you'll have a powerful and simple way to optimize the temperature relative to the electricity consumption in your home. The managed presets are as follows:
- **Eco**: the device is in energy-saving mode
- **Comfort**: the device is in comfort mode
- **Boost**: the device fully opens all valves
If the AC mode is used, you can also configure temperatures when the equipment is in air conditioning mode.
**None** is always added to the list of modes, as it is a way to not use presets but instead set a **manual temperature**.
The presets are configured directly from the _VTherm_ entities or the central configuration if you're using centralized control. Upon creating the _VTherm_, you will have different entities that will allow you to set the temperatures for each preset:
![presets](images/config-preset-temp.png).
The list of entities varies depending on your feature choices:
1. If the 'presence detection' function is activated, you will have the presets with an "absence" version prefixed with _abs_.
2. If you have selected the _AC_ option, you will also have presets for 'air conditioning' prefixed with _clim_.
> ![Tip](images/tips.png) _*Notes*_
>
> 1. When you manually change the target temperature, the preset switches to None (no preset).
> 2. The standard preset `Away` is a hidden preset that cannot be directly selected. Versatile Thermostat uses presence management or motion detection to automatically and dynamically adjust the target temperature based on presence in the home or activity in the room. See [presence management](feature-presence.md).
> 3. If you're using load shedding management, you will see a hidden preset named `power`. The heating element's preset is set to "power" when overload conditions are met and load shedding is active for that heating element. See [power management](feature-power.md).
> 4. If you're using advanced configuration, you will see the preset set to `safety` if the temperature could not be retrieved after a certain delay. See [Safety Mode](feature-advanced.md#safety-mode).

View File

@@ -1,64 +0,0 @@
# Door/Window Open Detection
- [Door/Window Open Detection](#doorwindow-open-detection)
- [Sensor Mode](#sensor-mode)
- [Auto Mode](#auto-mode)
You must have selected the `With Open Detection` feature on the first page to reach this page.
Open detection can be done in two ways:
1. By using a sensor placed on the opening (sensor mode),
2. By detecting a sudden temperature drop (auto mode)
## Sensor Mode
To switch to sensor mode, you need to provide an entity of type `binary_sensor` or `input_boolean`.
In this mode, you need to fill in the following information:
![mode window sensor](images/config-window-sensor.png)
1. A **delay in seconds** before any change. This allows you to open a window quickly without stopping the heating.
2. The action to take when the opening is detected as open. The possible actions are:
1. _Turn off_: the _VTherm_ will be turned off.
2. _Fan only_: heating or cooling will be turned off, but the equipment will continue to ventilate (for compatible equipment).
3. _Frost protection_: the "Frost Protection" preset temperature will be selected on the _VTherm_ without changing the current preset (see notes below).
4. _Eco_: the "Eco" preset temperature will be applied to the _VTherm_ without changing the current preset (see notes below).
When the detector switches to open:
1. _VTherm_ waits for the specified delay.
2. If the window is still open after the delay, the _VTherm_ state (Heating / Cooling / ..., current preset, current target temperature) is saved and the action is performed.
Similarly, when the detector switches to closed:
1. _VTherm_ waits for the specified delay.
2. If the window is still closed after the delay, the state before the window opening is restored.
## Auto Mode
In auto mode, the configuration is as follows:
![image](images/config-window-auto.png)
1. A **delay in seconds** before any change. This allows you to open a window quickly without stopping the heating.
2. A detection threshold in degrees per hour. When the temperature drops beyond this threshold, the thermostat will turn off. The lower this value, the faster the detection (with a higher risk of false positives).
3. A threshold for ending detection in degrees per hour. When the temperature drop exceeds this value, the thermostat will return to the previous mode (mode and preset).
4. A maximum detection duration. Beyond this duration, the thermostat will return to its previous mode and preset even if the temperature continues to drop.
5. The action to take when the opening is detected as open. The actions are the same as in sensor mode described above.
To adjust the thresholds, it is recommended to start with the reference values and adjust the detection thresholds. Some tests gave me the following values (for an office):
- Detection threshold: 3°C/hour
- No detection threshold: 0°C/hour
- Max duration: 30 min.
A new sensor called "slope" has been added for all thermostats. It provides the slope of the temperature curve in °C/hour (or °K/hour). This slope is smoothed and filtered to avoid aberrant thermometer values that could interfere with the measurement.
![image](images/temperature-slope.png)
To adjust it properly, it is recommended to display both the temperature curve and the slope of the curve ("slope") on the same historical graph:
![image](images/window-auto-tuning.png)
> ![Tip](images/tips.png) _*Notes*_
>
> 1. If you want to use **multiple door/window sensors** to automate your thermostat, simply create a group with the usual behavior (https://www.home-assistant.io/integrations/binary_sensor.group/)
> 2. If you don't have a door/window sensor in your room, simply leave the sensor entity ID empty.
> 3. **Only one mode is allowed**. You cannot configure a thermostat with both a sensor and auto detection. The two modes might contradict each other, so both modes cannot be active at the same time.
> 4. It is not recommended to use auto mode for equipment subjected to frequent and normal temperature variations (hallways, open areas, etc.).
> 5. To avoid interfering with your current preset settings, the actions _Frost protection_ and _Eco_ change the target temperature without changing the preset. So, you may notice a discrepancy between the selected preset and the setpoint.
> 6. If you use the Versatile Thermostat UI card (see [here](additions.md#even-better-with-the-versatile-thermostat-ui-card)), open detection is represented as follows: ![window](images/window-detection-icon.png).

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,19 +0,0 @@
# How to Install Versatile Thermostat?
## HACS Installation (Recommended)
1. Install [HACS](https://hacs.xyz/). This way, you will automatically receive updates.
2. The Versatile Thermostat integration is now available directly from the HACS interface (Integrations tab).
3. Search for and install "Versatile Thermostat" in HACS and click "Install".
4. Restart Home Assistant.
5. Then, you can add a Versatile Thermostat integration in the Settings / Integrations page. Add as many thermostats as needed (usually one per radiator or group of radiators that need to be controlled, or per pump in the case of a centralized heating system).
## Manual Installation
1. Using your tool of choice, open your Home Assistant configuration directory (where you will find `configuration.yaml`).
2. If you don't have a `custom_components` directory, you need to create one.
3. Inside the `custom_components` directory, create a new folder called `versatile_thermostat`.
4. Download _all_ files from the `custom_components/versatile_thermostat/` directory (folder) in this repository.
5. Place the downloaded files in the new folder you created.
6. Restart Home Assistant.
7. Configure the new Versatile Thermostat integration.

File diff suppressed because it is too large Load Diff

View File

@@ -1,101 +0,0 @@
# `over_climate` Type Thermostat
- [`over_climate` Type Thermostat](#over_climate-type-thermostat)
- [Prerequisites](#prerequisites)
- [Configuration](#configuration)
- [The Underlying Entities](#the-underlying-entities)
- [AC Mode](#ac-mode)
- [Self-Regulation](#self-regulation)
- [Auto-Fan (Auto Ventilation)](#auto-fan-auto-ventilation)
- [Compensating for the Internal Temperature of the Underlying Equipment](#compensating-for-the-internal-temperature-of-the-underlying-equipment)
- [Specific Functions](#specific-functions)
- [Follow Underlying Temperature Changes](#follow-underlying-temperature-changes)
## Prerequisites
The installation should look like this:
![installation `over_climate`](images/over-climate-schema.png)
1. The user or automation, or the Scheduler, sets a setpoint via a preset or directly using a temperature.
2. Periodically, the internal thermometer (2), external thermometer (2b), or equipment's internal thermometer (2c) sends the measured temperature. The internal thermometer should be placed in a relevant spot for the user's comfort: ideally in the middle of the living space. Avoid placing it too close to a window or equipment.
3. Based on the setpoint values, differences, and self-regulation parameters (see [auto-regulation](self-regulation.md)), VTherm will calculate a setpoint to send to the underlying `climate` entity.
4. The `climate` entity controls the equipment using its own protocol.
5. Depending on the chosen regulation options, VTherm may directly control the opening of a thermostatic valve or calibrate the equipment so that its internal temperature reflects the room temperature.
## Configuration
Click on the "Underlying Entities" option from the menu, and you will see this configuration page:
![image](images/config-linked-entity2.png)
### The Underlying Entities
In the "Equipment to Control" list, you should add the `climate` entities that will be controlled by VTherm. Only entities of type `climate` are accepted.
### AC Mode
You can choose an `over_climate` thermostat to control an air conditioner (reversible or not) by checking the "AC Mode" box. If the equipment allows it, both 'Heating' and 'Cooling' modes will be available.
### Self-Regulation
In `over_climate` mode, the device uses its own regulation algorithm: it turns on/off and pauses automatically based on the setpoint transmitted by VTherm through its `climate` entity. It uses its internal thermometer and the received setpoint.
Depending on the equipment, this internal regulation may vary in quality. It greatly depends on the quality of the equipment, the functionality of its internal thermometer, and its internal algorithm. To improve equipment that regulates poorly, VTherm offers a way to adjust the setpoint it sends by increasing or decreasing it based on the room temperature measured by VTherm, rather than the internal temperature.
The self-regulation options are described in detail [here](self-regulation.md).
To avoid overloading the underlying equipment (some may beep unpleasantly, others run on batteries, etc.), two thresholds are available to limit the number of requests:
1. Regulation Threshold: a threshold in ° below which a new setpoint will not be sent. If the last setpoint was 22°, the next one will be 22° ± regulation threshold.
2. Minimum Regulation Period (in minutes): a minimum time interval below which a new setpoint will not be sent. If the last setpoint was sent at 11:00, the next one cannot be sent before 11:00 + minimum regulation period.
Improperly setting these thresholds may prevent correct self-regulation as new setpoints won't be sent.
### Auto-Fan (Auto Ventilation)
This mode, introduced in version 4.3, forces the use of ventilation if the temperature difference is significant. By activating ventilation, heat distribution occurs more quickly, which helps achieve the target temperature faster.
You can choose which ventilation level to activate from the following options: Low, Medium, High, Turbo.
Of course, your underlying equipment must have ventilation, and it must be controllable for this to work. If your equipment doesn't include the Turbo mode, the High mode will be used instead. Once the temperature difference becomes small again, the ventilation will switch to a "normal" mode, which depends on your equipment (in order): `Mute`, `Auto`, `Low`. The first available mode for your equipment will be chosen.
### Compensating for the Internal Temperature of the Underlying Equipment
Sometimes, the internal thermometer of the underlying equipment (TRV, air conditioner, etc.) is inaccurate to the point that self-regulation is insufficient. This happens when the internal thermometer is placed too close to the heat source. The internal temperature rises much faster than the room temperature, leading to regulation failures.
Example:
1. Room temperature is 18°, setpoint is 20°.
2. The internal temperature of the equipment is 22°.
3. If VTherm sends a setpoint of 21° (= 20° + 1° of self-regulation), the equipment will not heat because its internal temperature (22°) is higher than the setpoint (21°).
To address this, a new optional feature has been added in version 5.4: ![Use of Internal Temperature](images/config-use-internal-temp.png)
When activated, this feature adds the difference between the internal temperature and the room temperature to the setpoint to force heating.
In the above example, the difference is +4° (22° - 18°), so VTherm will send 25° (21° + 4°) to the equipment, forcing it to heat.
This difference is calculated for each underlying equipment since each has its own internal temperature. For example, a VTherm connected to three TRVs, each with its own internal temperature.
This results in much more effective self-regulation that avoids issues with large internal temperature differences due to faulty sensors.
However, be aware that some internal temperatures fluctuate so quickly and inaccurately that they completely skew the calculation. In this case, its better to disable this option.
You will find advice on how to adjust these settings properly on the page [self-regulation](self-regulation.md).
## Specific Functions
Specific functions can be configured through a dedicated option in the menu.
The specific functions that require configuration for this type of VTherm are:
1. Auto-Start/Stop: Automatic start and stop of VTherm based on usage forecasts. This is described here: [auto-start/stop function](feature-auto-start-stop.md).
2. If valve regulation is chosen, the TPI algorithm configuration is accessible from the menu. See ([algorithms](algorithms.md)).
## Follow Underlying Temperature Changes
Some users want to continue using their equipment as before (without _VTherm_). For example, you might want to use the remote control of your _PAC_ or turn the knob on your _TRV_.
If you are in this case, an entity has been added to the _VTherm_ device called `Follow underlying temp changes`:
![Track temperature changes](images/entity-follow-under-temp-change.png)
When this entity is 'On', all temperature or state changes made directly on the underlying equipment are reflected in _VTherm_.
Be careful, if you use this feature, your equipment is now controlled in two ways: _VTherm_ and directly by you. The commands might be contradictory, which could lead to confusion about the equipment's state. _VTherm_ is equipped with a delay mechanism that prevents loops: the user gives a setpoint, which is captured by _VTherm_ and changes the setpoint, ... This delay may cause the change made directly on the equipment to be ignored if these changes are too close together in time.
Some equipment (like Daikin, for example) changes state by itself. If the checkbox is checked, it may turn off the _VTherm_ when that's not what you intended.
That's why it's better not to use it. It generates a lot of confusion and many support requests.

View File

@@ -1,55 +0,0 @@
# `over_switch` Type Thermostat
- [`over_switch` Type Thermostat](#over_switch-type-thermostat)
- [Prerequisites](#prerequisites)
- [Configuration](#configuration)
- [The Underlying Entities](#the-underlying-entities)
- [Keep-Alive](#keep-alive)
- [AC Mode](#ac-mode)
- [Command Inversion](#command-inversion)
## Prerequisites
The installation should look like this:
![installation `over_switch`](images/over-switch-schema.png)
1. The user or automation, or the Scheduler, sets a setpoint via a preset or directly using a temperature.
2. Periodically, the internal thermometer (2) or external thermometer (2b) sends the measured temperature. The internal thermometer should be placed in a relevant spot for the user's comfort: ideally in the middle of the living space. Avoid placing it too close to a window or too near the radiator.
3. Based on the setpoint values, the different temperatures, and the TPI algorithm parameters (see [TPI](algorithms.md#lalgorithme-tpi)), VTherm will calculate a percentage of the on-time.
4. It will then regularly command the turning on and off of the underlying `switch` entities.
5. These underlying switch entities will control the physical switch.
6. The physical switch will turn the radiator on or off.
> The on-time percentage is recalculated each cycle, which is what allows regulating the room temperature.
## Configuration
Click on the "Underlying Entities" option from the menu, and you will see this configuration page:
![image](images/config-linked-entity.png)
### The Underlying Entities
In the "Equipment to Control" list, you should add the switches that will be controlled by VTherm. Only `switch` or `input_boolean` entities are accepted.
The algorithm currently available is TPI. See [algorithm](#algorithm).
If multiple entities are configured, the thermostat staggers the activations to minimize the number of switches on at any given time. This allows for better power distribution, as each radiator will turn on in turn.
VTherm will smooth the consumed power as much as possible by alternating activations. Example of staggered activations:
![image](images/multi-switch-activation.png)
Of course, if the requested power (`on_percent`) is too high, there will be an overlap of activations.
### Keep-Alive
Some equipment requires periodic activation to prevent a safety shutdown. Known as "keep-alive," this function can be activated by entering a non-zero number of seconds in the thermostat's keep-alive interval field. To disable the function or if in doubt, leave it empty or enter zero (default value).
### AC Mode
It is possible to choose a `thermostat_over_switch` to control an air conditioner by checking the "AC Mode" box. In this case, only the cooling mode will be visible.
### Command Inversion
If your equipment is controlled by a pilot wire with a diode, you may need to check the "Invert the Command" box. This will set the switch to `On` when you need to turn off the equipment and to `Off` when you need to turn it on. The cycle times will be inverted with this option.

View File

@@ -1,30 +0,0 @@
# `thermostat_over_valve` Type Thermostat
> ![Attention](images/tips.png) _*Notes*_
> 1. The `over_valve` type is often confused with the `over_climate` type equipped with auto-regulation and direct valve control.
> 2. You should only choose this type when you do not have an associated `climate` entity for your _TRV_ in Home Assistant, and if you only have a `number` type entity to control the valve's opening percentage. The `over_climate` with auto-regulation on the valve is much more powerful than the `over_valve` type.
## Prerequisites
The installation should be similar to the `over_switch` VTherm setup, except that the controlled equipment is directly the valve of a _TRV_:
![installation `over_valve`](images/over-valve-schema.png)
1. The user or automation, or the Scheduler, sets a setpoint via a preset or directly using a temperature.
2. Periodically, the internal thermometer (2) or external thermometer (2b) or internal thermometer of the equipment (2c) sends the measured temperature. The internal thermometer should be placed in a relevant spot for the user's comfort: ideally in the middle of the living space. Avoid placing it too close to a window or too near the equipment.
3. Based on the setpoint values, the different temperatures, and the TPI algorithm parameters (see [TPI](algorithms.md#lalgorithme-tpi)), VTherm will calculate the valve's opening percentage.
4. It will then modify the value of the underlying `number` entities.
5. These underlying `number` entities will control the valve opening rate on the _TRV_.
6. This will regulate the radiator's heating.
> The opening rate is recalculated each cycle, which allows regulating the room temperature.
## Configuration
Click on the "Underlying Entities" option from the menu, and you will see this configuration page, you should add the `number` entities that will be controlled by VTherm. Only `number` or `input_number` entities are accepted.
![image](images/config-linked-entity3.png)
The algorithm currently available is TPI. See [algorithm](#algorithm).
It is possible to choose a `thermostat_over_valve` to control an air conditioner by checking the "AC Mode" box. In this case, only the cooling mode will be visible.

View File

@@ -1,43 +0,0 @@
# When to Use and Not Use It
This thermostat can control 3 types of equipment:
1. A radiator that only works in on/off mode (called `thermostat_over_switch`). The minimum configuration required to use this type of thermostat is:
1. An equipment like a radiator (a `switch` or equivalent),
2. A temperature sensor for the room (or an input_number),
3. An external temperature sensor (consider the weather integration if you don't have one).
2. Another thermostat that has its own modes of operation (called `thermostat_over_climate`). For this type of thermostat, the minimum configuration requires:
1. Equipment like air conditioning, a thermostatic valve controlled by its own `climate` entity.
3. Equipment that can take a value from 0 to 100% (called `thermostat_over_valve`). At 0, heating is off, and at 100% it is fully open. This type allows controlling a thermostatic valve (e.g., Shelly valve) that exposes a `number` type entity, enabling direct control of the valve's opening. Versatile Thermostat regulates the room temperature by adjusting the opening percentage, using both the internal and external temperature sensors, and utilizing the TPI algorithm described below.
The `over_climate` type allows you to add all the features offered by VersatileThermostat to your existing equipment. The VersatileThermostat `climate` entity will control your underlying `climate` entity, turn it off if windows are open, switch to Eco mode if no one is present, etc. See [here](#pourquoi-un-nouveau-thermostat-implémentation). For this type of thermostat, all heating cycles are controlled by the underlying `climate` entity and not by the Versatile Thermostat itself. An optional auto-regulation function allows Versatile Thermostat to adjust the setpoint temperature to the underlying entity in order to reach the setpoint.
Installations with a pilot wire and activation diode benefit from an option that allows inverting the on/off control of the underlying radiator. To do this, use the `over_switch` type and check the "Invert command" option.
# Why a New Thermostat Implementation?
This component, called __Versatile Thermostat__, manages the following use cases:
- Configuration via the standard integration graphical interface (using the Config Entry flow),
- Full use of **preset mode**,
- Disable preset mode when the temperature is **set manually** on a thermostat,
- Turn off/on a thermostat or change preset when a **door or windows are opened/closed** after a certain delay,
- Change preset when **activity is detected** or not in a room for a defined time,
- Use a **TPI (Time Proportional Interval)** algorithm thanks to [[Argonaute](https://forum.hacf.fr/u/argonaute/summary)],
- Add **load shedding** management or regulation to not exceed a defined total power. When the maximum power is exceeded, a hidden preset of "power" is set on the `climate` entity. When the power goes below the maximum, the previous preset is restored.
- **Presence management**. This feature allows dynamically modifying the preset temperature based on the presence sensor in your home.
- **Actions to interact with the thermostat** from other integrations: you can force presence/non-presence using a service, and you can dynamically change preset temperatures and modify security settings.
- Add sensors to view the thermostat's internal states,
- Centralized control of all Versatile Thermostats to stop them all, set them all to frost protection, force them all to heating mode (in winter), force them all to cooling mode (in summer).
- Control of a central heating boiler and VTherms that must control this boiler.
- Automatic start/stop based on usage prediction for `over_climate`.
All these functions are configurable either centrally or individually depending on your needs.
## Incompatibilities
Some TRV type thermostats are known to be incompatible with Versatile Thermostat. This includes the following valves:
1. Danfoss POPP valves with temperature feedback. It is impossible to turn off this valve as it auto-regulates itself, causing conflicts with VTherm.
2. "Homematic" thermostats (and possibly Homematic IP) are known to have issues with Versatile Thermostat due to the limitations of the underlying RF protocol. This problem particularly arises when trying to control multiple Homematic thermostats at once in a single VTherm instance. To reduce service cycle load, you can, for example, group thermostats using Homematic-specific procedures (e.g., using a wall-mounted thermostat) and let Versatile Thermostat control only the wall-mounted thermostat directly. Another option is to control a single thermostat and propagate mode and temperature changes via automation.
3. Heatzy type thermostats that do not support `set_temperature` commands.
4. Rointe type thermostats tend to wake up on their own. The rest works normally.
5. TRVs like Aqara SRTS-A01 and MOES TV01-ZB, which lack the `hvac_action` state feedback to determine whether they are heating or not. Therefore, state feedback is inaccurate, but the rest seems functional.
6. Airwell air conditioners with the "Midea AC LAN" integration. If two VTherm commands are too close together, the air conditioner stops itself.
7. Climates based on the Overkiz integration do not work. It seems impossible to turn off or even change the temperature on these systems.

View File

@@ -1,275 +0,0 @@
# Reference Documentation
- [Reference Documentation](#reference-documentation)
- [Parameter Summary](#parameter-summary)
- [Sensors](#sensors)
- [Actions (Services)](#actions-services)
- [Force Presence/Occupation](#force-presenceoccupation)
- [Modify the Preset Temperature](#modify-the-preset-temperature)
- [Modify Security Settings](#modify-security-settings)
- [ByPass Window Check](#bypass-window-check)
- [Events](#events)
- [Custom Attributes](#custom-attributes)
## Parameter Summary
| Parameter | Label | "over switch" | "over climate" | "over valve" | "central configuration" |
| ----------------------------------------- | ---------------------------------------------------------- | ------------- | ------------------- | ------------ | ----------------------- |
| ``name`` | Name | X | X | X | - |
| ``thermostat_type`` | Thermostat type | X | X | X | - |
| ``temperature_sensor_entity_id`` | Temperature sensor entity id | X | X (auto-regulation) | X | - |
| ``external_temperature_sensor_entity_id`` | External temperature sensor entity id | X | X (auto-regulation) | X | X |
| ``cycle_min`` | Cycle duration (minutes) | X | X | X | - |
| ``temp_min`` | Minimum allowed temperature | X | X | X | X |
| ``temp_max`` | Maximum allowed temperature | X | X | X | X |
| ``device_power`` | Device power | X | X | X | - |
| ``use_central_mode`` | Enable centralized control | X | X | X | - |
| ``use_window_feature`` | With window detection | X | X | X | - |
| ``use_motion_feature`` | With motion detection | X | X | X | - |
| ``use_power_feature`` | With power management | X | X | X | - |
| ``use_presence_feature`` | With presence detection | X | X | X | - |
| ``heater_entity1_id`` | 1st heater | X | - | - | - |
| ``heater_entity2_id`` | 2nd heater | X | - | - | - |
| ``heater_entity3_id`` | 3rd heater | X | - | - | - |
| ``heater_entity4_id`` | 4th heater | X | - | - | - |
| ``heater_keep_alive`` | Switch refresh interval | X | - | - | - |
| ``proportional_function`` | Algorithm | X | - | - | - |
| ``climate_entity1_id`` | Underlying thermostat | - | X | - | - |
| ``climate_entity2_id`` | 2nd underlying thermostat | - | X | - | - |
| ``climate_entity3_id`` | 3rd underlying thermostat | - | X | - | - |
| ``climate_entity4_id`` | 4th underlying thermostat | - | X | - | - |
| ``valve_entity1_id`` | Underlying valve | - | - | X | - |
| ``valve_entity2_id`` | 2nd underlying valve | - | - | X | - |
| ``valve_entity3_id`` | 3rd underlying valve | - | - | X | - |
| ``valve_entity4_id`` | 4th underlying valve | - | - | X | - |
| ``ac_mode`` | Use of air conditioning (AC)? | X | X | X | - |
| ``tpi_coef_int`` | Coefficient for internal temperature delta | X | - | X | X |
| ``tpi_coef_ext`` | Coefficient for external temperature delta | X | - | X | X |
| ``frost_temp`` | Frost preset temperature | X | X | X | X |
| ``window_sensor_entity_id`` | Window sensor (entity id) | X | X | X | - |
| ``window_delay`` | Delay before turn-off (seconds) | X | X | X | X |
| ``window_auto_open_threshold`` | High drop threshold for automatic detection (°/min) | X | X | X | X |
| ``window_auto_close_threshold`` | Low drop threshold for automatic closure detection (°/min) | X | X | X | X |
| ``window_auto_max_duration`` | Maximum duration of automatic turn-off (minutes) | X | X | X | X |
| ``motion_sensor_entity_id`` | Motion sensor entity id | X | X | X | - |
| ``motion_delay`` | Delay before motion is considered (seconds) | X | X | X | - |
| ``motion_off_delay`` | Delay before end of motion is considered (seconds) | X | X | X | X |
| ``motion_preset`` | Preset to use if motion is detected | X | X | X | X |
| ``no_motion_preset`` | Preset to use if no motion is detected | X | X | X | X |
| ``power_sensor_entity_id`` | Total power sensor (entity id) | X | X | X | X |
| ``max_power_sensor_entity_id`` | Max power sensor (entity id) | X | X | X | X |
| ``power_temp`` | Temperature during load shedding | X | X | X | X |
| ``presence_sensor_entity_id`` | Presence sensor entity id (true if someone is present) | X | X | X | - |
| ``minimal_activation_delay`` | Minimum activation delay | X | - | - | X |
| ``security_delay_min`` | Maximum delay between two temperature measurements | X | - | X | X |
| ``security_min_on_percent`` | Minimum power percentage to enter security mode | X | - | X | X |
| ``auto_regulation_mode`` | Auto-regulation mode | - | X | - | - |
| ``auto_regulation_dtemp`` | Auto-regulation threshold | - | X | - | - |
| ``auto_regulation_period_min`` | Minimum auto-regulation period | - | X | - | - |
| ``inverse_switch_command`` | Inverse the switch command (for switches with pilot wire) | X | - | - | - |
| ``auto_fan_mode`` | Automatic fan mode | - | X | - | - |
| ``auto_regulation_use_device_temp`` | Use of internal temperature of the underlying device | - | X | - | - |
| ``use_central_boiler_feature`` | Add central boiler control | - | - | - | X |
| ``central_boiler_activation_service`` | Boiler activation service | - | - | - | X |
| ``central_boiler_deactivation_service`` | Boiler deactivation service | - | - | - | X |
| ``used_by_controls_central_boiler`` | Indicates if the VTherm controls the central boiler | X | X | X | - |
| ``use_auto_start_stop_feature`` | Indicates if the auto start/stop feature is enabled | - | X | - | - |
| ``auto_start_stop_level`` | The detection level for auto start/stop | - | X | - | - |
# Sensors
With the thermostat, sensors are available to visualize alerts and the internal state of the thermostat. These are available in the entities of the device associated with the thermostat:
![image](images/thermostat-sensors.png)
In order, there are:
1. the main ``climate`` entity for thermostat control,
2. the entity allowing the auto-start/stop feature,
3. the entity allowing _VTherm_ to follow changes in the underlying device,
4. the energy consumed by the thermostat (value that increments continuously),
5. the time of receipt of the last external temperature,
6. the time of receipt of the last internal temperature,
7. the average power of the device during the cycle (for TPI only),
8. the time spent in the off state during the cycle (TPI only),
9. the time spent in the on state during the cycle (TPI only),
10. the load shedding state,
11. the power percentage during the cycle (TPI only),
12. the presence state (if presence management is configured),
13. the security state,
14. the window state (if window management is configured),
15. the motion state (if motion management is configured),
16. the valve opening percentage (for `over_valve` type),
The presence of these entities depends on whether the associated feature is enabled.
To color the sensors, add these lines and customize them as needed in your `configuration.yaml`:
```yaml
frontend:
themes:
versatile_thermostat_theme:
state-binary_sensor-safety-on-color: "#FF0B0B"
state-binary_sensor-power-on-color: "#FF0B0B"
state-binary_sensor-window-on-color: "rgb(156, 39, 176)"
state-binary_sensor-motion-on-color: "rgb(156, 39, 176)"
state-binary_sensor-presence-on-color: "lightgreen"
state-binary_sensor-running-on-color: "orange"
```
and choose the theme ```versatile_thermostat_theme``` in the panel configuration. You will get something like this:
![image](images/colored-thermostat-sensors.png)
# Actions (Services)
This custom implementation offers specific actions (services) to facilitate integration with other Home Assistant components.
## Force Presence/Occupation
This service allows you to force the presence state independently of the presence sensor. This can be useful if you want to manage presence via a service rather than a sensor. For example, you can use your alarm to force absence when it is turned on.
The code to call this service is as follows:
```yaml
service : versatile_thermostat.set_presence
Les données:
présence : "off"
cible:
entity_id : climate.my_thermostat
```
## Modify the Preset Temperature
This service is useful if you want to dynamically change the preset temperature. Instead of switching presets, some use cases require modifying the temperature of the preset. This way, you can keep the scheduler unchanged to manage the preset while adjusting the preset temperature.
If the modified preset is currently selected, the target temperature change is immediate and will be applied in the next calculation cycle.
You can modify one or both temperatures (when present or absent) of each preset.
Use the following code to set the preset temperature:
```yaml
service: versatile_thermostat.set_preset_temperature
data:
preset: boost
temperature: 17.8
temperature_away: 15
target:
entity_id: climate.my_thermostat
```
Or, to change the preset for the Air Conditioning (AC) mode, add the `_ac` prefix to the preset name like this:
```yaml
service: versatile_thermostat.set_preset_temperature
data:
preset: boost_ac
temperature: 25
temperature_away: 30
target:
entity_id: climate.my_thermostat
```
> ![Tip](images/tips.png) _*Notes*_
>
> - After a restart, presets are reset to the configured temperature. If you want your change to be permanent, you need to modify the preset temperature in the integration configuration.
## Modify Security Settings
This service allows you to dynamically modify the security settings described here [Advanced Configuration](#advanced-configuration).
If the thermostat is in ``security`` mode, the new settings are applied immediately.
To change the security settings, use the following code:
```yaml
service: versatile_thermostat.set_security
data:
min_on_percent: "0.5"
default_on_percent: "0.1"
delay_min: 60
target:
entity_id: climate.my_thermostat
```
## ByPass Window Check
This service allows you to enable or disable a bypass for the window check.
It allows the thermostat to continue heating even if the window is detected as open.
When set to ``true``, changes to the window's status will no longer affect the thermostat. When set to ``false``, the thermostat will be disabled if the window is still open.
To change the bypass setting, use the following code:
```yaml
service: versatile_thermostat.set_window_bypass
data:
bypass: true
target:
entity_id: climate.my_thermostat
```
# Events
The key events of the thermostat are notified via the message bus.
The following events are notified:
- ``versatile_thermostat_security_event``: the thermostat enters or exits the ``security`` preset
- ``versatile_thermostat_power_event``: the thermostat enters or exits the ``power`` preset
- ``versatile_thermostat_temperature_event``: one or both temperature measurements of the thermostat haven't been updated for more than `security_delay_min`` minutes
- ``versatile_thermostat_hvac_mode_event``: the thermostat is turned on or off. This event is also broadcast at the thermostat's startup
- ``versatile_thermostat_preset_event``: a new preset is selected on the thermostat. This event is also broadcast at the thermostat's startup
- ``versatile_thermostat_central_boiler_event``: an event indicating a change in the boiler's state
- ``versatile_thermostat_auto_start_stop_event``: an event indicating a stop or restart made by the auto-start/stop function
If you've followed along, when a thermostat switches to security mode, 3 events are triggered:
1. ``versatile_thermostat_temperature_event`` to indicate that a thermometer is no longer responding,
2. ``versatile_thermostat_preset_event`` to indicate the switch to the ``security`` preset,
3. ``versatile_thermostat_hvac_mode_event`` to indicate the potential shutdown of the thermostat
Each event carries the event's key values (temperatures, current preset, current power, ...) as well as the thermostat's states.
You can easily capture these events in an automation, for example, to notify users.
# Custom Attributes
To adjust the algorithm, you have access to the entire context seen and calculated by the thermostat via dedicated attributes. You can view (and use) these attributes in the "Developer Tools / States" section of HA. Enter your thermostat and you will see something like this:
![image](images/dev-tools-climate.png)
The custom attributes are as follows:
| Attribute | Meaning |
| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| ``hvac_modes`` | The list of modes supported by the thermostat |
| ``temp_min`` | The minimum temperature |
| ``temp_max`` | The maximum temperature |
| ``preset_modes`` | The presets visible for this thermostat. Hidden presets are not displayed here |
| ``temperature_actuelle`` | The current temperature as reported by the sensor |
| ``temperature`` | The target temperature |
| ``action_hvac`` | The action currently being executed by the heater. Can be idle, heating |
| ``preset_mode`` | The preset currently selected. Can be one of the 'preset_modes' or a hidden preset like power |
| ``[eco/confort/boost]_temp`` | The temperature configured for preset xxx |
| ``[eco/confort/boost]_away_temp`` | The temperature configured for preset xxx when presence is disabled or not_home |
| ``temp_power`` | The temperature used during loss detection |
| ``on_percent`` | The calculated on percentage by the TPI algorithm |
| ``on_time_sec`` | The on period in seconds. Should be ```on_percent * cycle_min``` |
| ``off_time_sec`` | The off period in seconds. Should be ```(1 - on_percent) * cycle_min``` |
| ``cycle_min`` | The calculation cycle in minutes |
| ``function`` | The algorithm used for the cycle calculation |
| ``tpi_coef_int`` | The ``coef_int`` of the TPI algorithm |
| ``tpi_coef_ext`` | The ``coef_ext`` of the TPI algorithm |
| ``saved_preset_mode`` | The last preset used before automatic preset switching |
| ``saved_target_temp`` | The last temperature used before automatic switching |
| ``window_state`` | The last known state of the window sensor. None if the window is not configured |
| ``window_bypass_state`` | True if the window open detection bypass is enabled |
| ``motion_state`` | The last known state of the motion sensor. None if motion detection is not configured |
| ``overpowering_state`` | The last known state of the overpower sensor. None if power management is not configured |
| ``presence_state`` | The last known state of the presence sensor. None if presence detection is not configured |
| ``security_delay_min`` | The delay before activating security mode when one of the two temperature sensors stops sending measurements |
| ``security_min_on_percent`` | The heating percentage below which the thermostat will not switch to security |
| ``security_default_on_percent`` | The heating percentage used when the thermostat is in security mode |
| ``last_temperature_datetime`` | The date and time in ISO8866 format of the last internal temperature reception |
| ``last_ext_temperature_datetime`` | The date and time in ISO8866 format of the last external temperature reception |
| ``security_state`` | The security state. True or false |
| ``minimal_activation_delay_sec`` | The minimal activation delay in seconds |
| ``last_update_datetime`` | The date and time in ISO8866 format of this state |
| ``friendly_name`` | The name of the thermostat |
| ``supported_features`` | A combination of all features supported by this thermostat. See the official climate integration documentation for more information |
| ``valve_open_percent`` | The valve opening percentage |
| ``regulated_target_temperature`` | The target temperature calculated by self-regulation |
| ``is_inversed`` | True if the control is inverted (pilot wire with diode) |
| ``is_controlled_by_central_mode`` | True if the VTherm can be centrally controlled |
| ``last_central_mode`` | The last central mode used (None if the VTherm is not centrally controlled) |
| ``is_used_by_central_boiler`` | Indicates if the VTherm can control the central boiler |
| ``auto_start_stop_enable`` | Indicates if the VTherm is allowed to auto start/stop |
| ``auto_start_stop_level`` | Indicates the auto start/stop level |
| ``hvac_off_reason`` | Indicates the reason for the thermostat's off state (hvac_off). It can be Window, Auto-start/stop, or Manual |
These attributes will be requested when you need assistance.

View File

@@ -1,50 +0,0 @@
# Release Notes
![New](images/new-icon.png)
> * **Release 6.8**:
> - Added a new regulation method for `over_climate` type Versatile Thermostats. This method, called 'Direct Valve Control', allows direct control of a TRV valve and possibly an offset to calibrate the internal thermometer of your TRV. This new method has been tested with Sonoff TRVZB and extended to other TRV types where the valve can be directly controlled via `number` entities. More information [here](over-climate.md#lauto-régulation) and [here](self-regulation.md#auto-régulation-par-contrôle-direct-de-la-vanne).
## **Release 6.5** :
- Added a new feature for the automatic stop and restart of a `VTherm over_climate` [585](https://github.com/jmcollin78/versatile_thermostat/issues/585)
- Improved handling of openings on startup. Allows to memorize and recalculate the state of an opening on Home Assistant restart [504](https://github.com/jmcollin78/versatile_thermostat/issues/504)
## **Release 6.0** :
- Added `number` domain entities to configure preset temperatures [354](https://github.com/jmcollin78/versatile_thermostat/issues/354)
- Complete redesign of the configuration menu to remove temperatures and use a menu instead of a configuration tunnel [354](https://github.com/jmcollin78/versatile_thermostat/issues/354)
## **Release 5.4** :
- Added temperature step [#311](https://github.com/jmcollin78/versatile_thermostat/issues/311),
- Added regulation thresholds for `over_valve` to prevent excessive battery drain for TRVs [#338](https://github.com/jmcollin78/versatile_thermostat/issues/338),
- Added an option to use the internal temperature of a TRV to force auto-regulation [#348](https://github.com/jmcollin78/versatile_thermostat/issues/348),
- Added a keep-alive function for `over_switch` VTherms [#345](https://github.com/jmcollin78/versatile_thermostat/issues/345)
<details>
<summary>Older releases</summary>
> * **Release 5.3** : Added a function to control a central boiler [#234](https://github.com/jmcollin78/versatile_thermostat/issues/234) - more info here: [Central Boiler Control](#le-contrôle-dune-chaudière-centrale). Added the ability to disable security mode for the external thermometer [#343](https://github.com/jmcollin78/versatile_thermostat/issues/343)
> * **Release 5.2** : Added a `central_mode` to control all VTherms centrally [#158](https://github.com/jmcollin78/versatile_thermostat/issues/158).
> * **Release 5.1** : Limitation of values sent to valves and to the underlying climate temperature.
> * **Release 5.0** : Added central configuration to combine configurable attributes [#239](https://github.com/jmcollin78/versatile_thermostat/issues/239).
> * **Release 4.3** : Added an auto-fan mode for `over_climate` type to activate ventilation if temperature difference is large [#223](https://github.com/jmcollin78/versatile_thermostat/issues/223).
> * **Release 4.2** : The temperature curve slope is now calculated in °/hour instead of °/min [#242](https://github.com/jmcollin78/versatile_thermostat/issues/242). Fixed automatic opening detection by adding temperature curve smoothing.
> * **Release 4.1** : Added an **Expert** regulation mode where users can specify their own auto-regulation parameters instead of using pre-programmed ones [#194](https://github.com/jmcollin78/versatile_thermostat/issues/194).
> * **Release 4.0** : Added support for **Versatile Thermostat UI Card**. See [Versatile Thermostat UI Card](https://github.com/jmcollin78/versatile-thermostat-ui-card). Added a **Slow** regulation mode for slow-latency heating devices [#168](https://github.com/jmcollin78/versatile_thermostat/issues/168). Changed how **power is calculated** for VTherms with multi-underlying equipment [#146](https://github.com/jmcollin78/versatile_thermostat/issues/146). Added support for AC and Heat for VTherms via a switch [#144](https://github.com/jmcollin78/versatile_thermostat/pull/144)
> * **Release 3.8**: Added an **auto-regulation** function for `over_climate` thermostats regulated by the underlying climate. See [Auto-regulation](#lauto-régulation) and [#129](https://github.com/jmcollin78/versatile_thermostat/issues/129). Added the **ability to invert control** for `over_switch` thermostats to address installations with pilot wire and diode [#124](https://github.com/jmcollin78/versatile_thermostat/issues/124).
> * **Release 3.7**: Added the `over_valve` Versatile Thermostat type to control a TRV valve directly or any other dimmer type equipment for heating. Regulation is done directly by adjusting the percentage of opening of the underlying entity: 0 means the valve is off, 100 means the valve is fully open. See [#131](https://github.com/jmcollin78/versatile_thermostat/issues/131). Added a bypass function for opening detection [#138](https://github.com/jmcollin78/versatile_thermostat/issues/138). Added Slovak language support.
> * **Release 3.6**: Added the `motion_off_delay` parameter to improve motion detection handling [#116](https://github.com/jmcollin78/versatile_thermostat/issues/116), [#128](https://github.com/jmcollin78/versatile_thermostat/issues/128). Added AC mode (air conditioning) for `over_switch` VTherm. Prepared the GitHub project to facilitate contributions [#127](https://github.com/jmcollin78/versatile_thermostat/issues/127)
> * **Release 3.5**: Multiple thermostats possible in "thermostat over climate" mode [#113](https://github.com/jmcollin78/versatile_thermostat/issues/113)
> * **Release 3.4**: Bug fix and exposure of preset temperatures for AC mode [#103](https://github.com/jmcollin78/versatile_thermostat/issues/103)
> * **Release 3.3**: Added Air Conditioning (AC) mode. This function allows you to use the AC mode of your underlying thermostat. To use it, you must check the "Use AC Mode" option and define temperature values for presets and away presets.
> * **Release 3.2** : Added the ability to control multiple switches from the same thermostat. In this mode, switches are triggered with a delay to minimize the power required at any given time (minimizing overlap periods). See [Configuration](#sélectionnez-des-entités-pilotées)
> * **Release 3.1** : Added window/door open detection by temperature drop. This new feature automatically stops a radiator when the temperature drops suddenly. See [Auto Mode](#le-mode-auto)
> * **Major Release 3.0** : Added thermostat equipment and associated sensors (binary and non-binary). Much closer to the Home Assistant philosophy, you now have direct access to the energy consumed by the radiator controlled by the thermostat and many other sensors useful for your automations and dashboards.
> * **Release 2.3** : Added measurement of power and energy for the radiator controlled by the thermostat.
> * **Release 2.2** : Added a safety function to prevent leaving a radiator heating indefinitely in case of thermometer failure.
> * **Major Release 2.0** : Added the "over climate" thermostat allowing any thermostat to be transformed into a Versatile Thermostat and gain all its functionalities.
</details>
> ![Tip](images/tips.png) _*Notes*_
>
> Complete release notes are available on the [GitHub of the integration](https://github.com/jmcollin78/versatile_thermostat/releases/).

View File

@@ -1,152 +0,0 @@
# Self-regulation
- [Self-regulation](#self-regulation)
- [Self-regulation in Expert Mode](#self-regulation-in-expert-mode)
- [Summary of the Self-regulation Algorithm](#summary-of-the-self-regulation-algorithm)
You have the option to activate the self-regulation feature only for _VTherms_ of type `over_climate`.
There are generally two cases:
1. If your underlying device is a _TRV_ and the valve is directly controllable in Home Assistant (e.g., Sonoff TRVZB), this function will allow _VTherm_ to directly manipulate the valve opening to regulate the temperature. The opening is then calculated by a _TPI_-type algorithm (see [here](algorithms.md)).
2. Otherwise, Versatile Thermostat will adjust the temperature setpoint given to the underlying climate to ensure the room temperature actually reaches the setpoint.
## Configuration
### Self-regulation by direct valve control
This type of self-regulation, named `Direct Valve Control`, requires:
1. An entity of type `climate` that is included in the _VTherm_'s underlying devices.
2. An entity of type `number` to control the valve opening rate of the _TRV_.
3. An optional entity of type `number` for calibrating the internal temperature of the underlying device.
4. An optional entity of type `number` to control the valve closure.
When the chosen self-regulation is `Direct Valve Control` on an _VTherm_ `over_climate`, a new configuration page named `Valve Regulation Configuration` appears:
![Configuration Menu](images/config-self-regulation-valve-1.png)
This allows you to configure the valve control entities:
![Configuration Entities](images/config-self-regulation-valve-2.png)
You need to provide:
1. As many valve opening control entities as there are underlying devices, and in the same order. These parameters are mandatory.
2. As many temperature calibration entities as there are underlying devices, and in the same order. These parameters are optional; they must either all be provided or none.
3. As many valve closure control entities as there are underlying devices, and in the same order. These parameters are optional; they must either all be provided or none.
The opening rate calculation algorithm is based on the _TPI_ algorithm described [here](algorithms.md). This is the same algorithm used for _VTherms_ `over_switch` and `over_valve`.
If a valve closure rate entity is configured, it will be set to 100 minus the opening rate to force the valve into a particular state.
### Other self-regulation
In the second case, Versatile Thermostat calculates an offset based on the following information:
1. The current difference between the actual temperature and the setpoint temperature, called the gross error.
2. The accumulation of past errors.
3. The difference between the outdoor temperature and the setpoint.
These three pieces of information are combined to calculate the offset, which will be added to the current setpoint and sent to the underlying climate.
Self-regulation is configured with:
1. A regulation degree:
1. Light - for small self-regulation needs. In this mode, the maximum offset will be 1.5°C.
2. Medium - for medium self-regulation needs. A maximum offset of 2°C is possible in this mode.
3. Strong - for high self-regulation needs. The maximum offset is 3°C in this mode, and the self-regulation will react strongly to temperature changes.
2. A self-regulation threshold: the value below which no new regulation will be applied. For example, if at time t the offset is 2°C, and at the next calculation, the offset is 2.4°C, the regulation will not be applied. It will only be applied when the difference between the two offsets is at least equal to this threshold.
3. Minimum period between two self-regulations: this number, expressed in minutes, indicates the duration between two regulation changes.
These three parameters allow you to adjust the regulation and avoid applying too many regulation changes. Some devices, like TRVs or boilers, don't like frequent setpoint changes.
> ![Tip](images/tips.png) _*Setup advice*_
> 1. Do not start self-regulation immediately. Observe how your equipment's natural regulation works. If you notice that the setpoint is not reached or takes too long to reach, start the regulation.
> 2. Start with light self-regulation and keep both parameters at their default values. Wait a few days and check if the situation improves.
> 3. If it's not enough, switch to medium self-regulation and wait for stabilization.
> 4. If it's still not enough, switch to strong self-regulation.
> 5. If it's still not correct, you will need to switch to expert mode to finely adjust the regulation parameters.
Self-regulation forces the equipment to push further by regularly adjusting its setpoint. This can increase both its consumption and wear.
#### Self-regulation in Expert Mode
In **Expert** mode, you can finely adjust the self-regulation parameters to meet your goals and optimize performance. The algorithm calculates the gap between the setpoint and the actual room temperature. This gap is called the error.
The adjustable parameters are as follows:
1. `kp`: the factor applied to the gross error,
2. `ki`: the factor applied to the accumulated errors,
3. `k_ext`: the factor applied to the difference between the indoor temperature and the outdoor temperature,
4. `offset_max`: the maximum correction (offset) that the regulation can apply,
5. `stabilization_threshold`: a stabilization threshold, which when reached by the error resets the accumulated errors to 0,
6. `accumulated_error_threshold`: the maximum for error accumulation.
For tuning, the following observations should be considered:
1. `kp * error` will give the offset related to the gross error. This offset is directly proportional to the error and will be 0 when the target is reached.
2. The accumulation of the error helps correct the stabilization curve even if there is still an error. The error accumulates and the offset increases progressively, which should stabilize the temperature around the target. To have a noticeable effect, this parameter should not be too small. A medium value is 30.
3. `ki * accumulated_error_threshold` will give the maximum offset related to the accumulated error.
4. `k_ext` allows immediate (without waiting for accumulated errors) correction when the outdoor temperature is much different from the target temperature. If the stabilization occurs too high when the temperature differences are large, this parameter might be too high. It should be adjustable to zero to allow the first two offsets to do the work.
The pre-programmed values are as follows:
**Slow regulation**:
kp: 0.2 # 20% of the current internal regulation offset are caused by the current difference of target temperature and room temperature
ki: 0.8 / 288.0 # 80% of the current internal regulation offset are caused by the average offset of the past 24 hours
k_ext: 1.0 / 25.0 # this will add 1°C to the offset when it's 25°C colder outdoor than indoor
offset_max: 2.0 # limit to a final offset of -2°C to +2°C
stabilization_threshold: 0.0 # this needs to be disabled as otherwise the long term accumulated error will always be reset when the temp briefly crosses from/to below/above the target
accumulated_error_threshold: 2.0 * 288 # this allows up to 2°C long term offset in both directions
**Light regulation**:
kp: 0.2
ki: 0.05
k_ext: 0.05
offset_max: 1.5
stabilization_threshold: 0.1
accumulated_error_threshold: 10
**Medium regulation**:
kp: 0.3
ki: 0.05
k_ext: 0.1
offset_max: 2
stabilization_threshold: 0.1
accumulated_error_threshold: 20
**Strong regulation**:
"""Strong parameters for regulation
A set of parameters which doesn't take into account the external temp
and concentrate on internal temp error + accumulated error.
This should work for cold external conditions which otherwise generate
high external_offset"""
kp: 0.4
ki: 0.08
k_ext: 0.0
offset_max: 5
stabilization_threshold: 0.1
accumulated_error_threshold: 50
To use Expert mode, you must declare the values you wish to use for each of these parameters in your `configuration.yaml` as follows. Example for 'Extreme regulation':
```yaml
versatile_thermostat:
auto_regulation_expert:
kp: 0.6
ki: 0.1
k_ext: 0.0
offset_max: 10
stabilization_threshold: 0.1
accumulated_error_threshold: 80
```
and of course, configure the auto-regulation mode of the VTherm to Expert mode. All _VTherms_ in **Expert** mode will use the same parameters, it is not possible to have different expert settings.
To apply the changes, you must either **restart Home Assistant completely** or just the Versatile Thermostat integration (Developer Tools / YAML / Reload Configuration / Versatile Thermostat).
> ![Tip](images/tips.png) _*Notes*_
>
> 1. In expert mode, it is rarely necessary to use the option [Compensate the internal temperature of the underlying](over-climate.md#compensate-the-internal-temperature-of-the-underlying). This could result in very high setpoints.
## Summary of the Auto-Regulation Algorithm
A summary of the auto-regulation algorithm is described [here](algorithms.md#the-auto-regulation-algorithm-without-valve-control)

View File

@@ -1,211 +0,0 @@
# Troubleshooting
- [Troubleshooting](#troubleshooting)
- [Using a Heatzy](#using-a-heatzy)
- [Using a radiator with a pilot wire (Nodon SIN-4-FP-21)](#using-a-radiator-with-a-pilot-wire-nodon-sin-4-fp-21)
- [Only the first radiator heats](#only-the-first-radiator-heats)
- [The radiator heats even though the setpoint temperature is exceeded, or it does not heat when the room temperature is well below the setpoint](#the-radiator-heats-even-though-the-setpoint-temperature-is-exceeded-or-it-does-not-heat-when-the-room-temperature-is-well-below-the-setpoint)
- [Type `over_switch` or `over_valve`](#type-over_switch-or-over_valve)
- [Type `over_climate`](#type-over_climate)
- [Adjust the window open detection parameters in auto mode](#adjust-the-window-open-detection-parameters-in-auto-mode)
- [Why is my Versatile Thermostat going into Safety Mode?](#why-is-my-versatile-thermostat-going-into-safety-mode)
- [How to detect Safety Mode?](#how-to-detect-safety-mode)
- [How to Be Notified When This Happens?](#how-to-be-notified-when-this-happens)
- [How to Fix It?](#how-to-fix-it)
- [Using a Group of People as a Presence Sensor](#using-a-group-of-people-as-a-presence-sensor)
- [Enable Logs for the Versatile Thermostat](#enable-logs-for-the-versatile-thermostat)
## Using a Heatzy
Using a Heatzy or Nodon is possible provided you use a virtual switch with this model:
```yaml
- platform: template
switches:
chauffage_sdb:
unique_id: chauffage_sdb
friendly_name: Bathroom heating
value_template: "{{ is_state_attr('climate.bathroom', 'preset_mode', 'comfort') }}"
icon_template: >-
{% if is_state_attr('climate.bathroom', 'preset_mode', 'comfort') %}
mdi:radiator
{% elif is_state_attr('climate.bathroom', 'preset_mode', 'away') %}
mdi:snowflake
{% else %}
mdi:radiator-disabled
{% endif %}
turn_on:
service: climate.set_preset_mode
entity_id: climate.bathroom
data:
preset_mode: "comfort"
turn_off:
service: climate.set_preset_mode
entity_id: climate.bathroom
data:
preset_mode: "eco"
```
Thanks to @gael for this example.
## Using a radiator with a pilot wire (Nodon SIN-4-FP-21)
As with the Heatzy above, you can use a virtual switch that will change the preset of your radiator based on the VTherms on/off state.
Example:
```yaml
- platform: template
switches:
chauffage_chb_parents:
unique_id: chauffage_chb_parents
friendly_name: Chauffage chambre parents
value_template: "{{ is_state('select.fp_chb_parents_pilot_wire_mode', 'comfort') }}"
icon_template: >-
{% if is_state('select.fp_chb_parents_pilot_wire_mode', 'comfort') %}
mdi:radiator
{% elif is_state('select.fp_chb_parents_pilot_wire_mode', 'frost_protection') %}
mdi:snowflake
{% else %}
mdi:radiator-disabled
{% endif %}
turn_on:
service: select.select_option
target:
entity_id: select.fp_chb_parents_pilot_wire_mode
data:
option: comfort
turn_off:
service: select.select_option
target:
entity_id: select.fp_chb_parents_pilot_wire_mode
data:
option: eco
```
Another more complex example is [here](https://github.com/jmcollin78/versatile_thermostat/discussions/431#discussioncomment-11393065)
## Only the first radiator heats
In `over_switch` mode, if multiple radiators are configured for the same VTherm, the heating will be triggered sequentially to smooth out the consumption peaks as much as possible.
This is completely normal and intentional. It is described here: [For a thermostat of type ```thermostat_over_switch```](#for-a-thermostat-of-type-thermostat_over_switch)
## The radiator heats even though the setpoint temperature is exceeded, or it does not heat when the room temperature is well below the setpoint
### Type `over_switch` or `over_valve`
With a VTherm of type `over_switch` or `over_valve`, this issue simply indicates that the TPI algorithm parameters are not properly configured. See [TPI Algorithm](#tpi-algorithm) to optimize the settings.
### Type `over_climate`
With a VTherm of type `over_climate`, the regulation is handled directly by the underlying `climate`, and VTherm simply transmits the setpoints to it. So if the radiator is heating even though the setpoint temperature is exceeded, it is likely that its internal temperature measurement is biased. This often happens with TRVs and reversible air conditioners that have an internal temperature sensor, either too close to the heating element (so it's too cold in winter).
Examples of discussions on these topics: [#348](https://github.com/jmcollin78/versatile_thermostat/issues/348), [#316](https://github.com/jmcollin78/versatile_thermostat/issues/316), [#312](https://github.com/jmcollin78/versatile_thermostat/discussions/312), [#278](https://github.com/jmcollin78/versatile_thermostat/discussions/278)
To resolve this, VTherm is equipped with a feature called self-regulation, which allows it to adjust the setpoint sent to the underlying device until the setpoint is met. This function compensates for the bias of internal temperature sensors. If the bias is significant, the regulation should also be significant. See [Self-regulation](self-regulation.md) for configuring self-regulation.
## Adjust the window open detection parameters in auto mode
If you are unable to configure the automatic window open detection function (see [auto](feature-window.md#auto-mode)), you can try modifying the temperature smoothing algorithm parameters.
Indeed, the automatic window open detection is based on calculating the temperature slope. To avoid artifacts caused by an imprecise temperature sensor, this slope is calculated using a temperature smoothed with an algorithm called Exponential Moving Average (EMA).
This algorithm has 3 parameters:
1. `lifecycle_sec`: the duration in seconds considered for smoothing. The higher it is, the smoother the temperature will be, but the detection delay will also increase.
2. `max_alpha`: if two temperature readings are far apart in time, the second one will carry much more weight. This parameter limits the weight of a reading that comes well after the previous one. This value must be between 0 and 1. The lower it is, the less distant readings are taken into account. The default value is 0.5, meaning that a new temperature reading will never weigh more than half of the moving average.
3. `precision`: the number of digits after the decimal point retained for calculating the moving average.
To change these parameters, you need to modify the `configuration.yaml` file and add the following section (the values below are the default values):
```yaml
versatile_thermostat:
short_ema_params:
max_alpha: 0.5
halflife_sec: 300
precision: 2
```
These parameters are sensitive and quite difficult to adjust. Please only use them if you know what youre doing and if your temperature readings are not already smoothed.
## Why is my Versatile Thermostat going into Safety Mode?
Safety mode is only available for VTherm types `over_switch` and `over_valve`. It occurs when one of the two thermometers (providing either the room temperature or the external temperature) has not sent a value for more than `security_delay_min` minutes, and the radiator had been heating at least `security_min_on_percent`. See [safety mode](feature-advanced.md#safety-mode)
Since the algorithm relies on temperature measurements, if they are no longer received by the VTherm, there is a risk of overheating and fire. To prevent this, when the above conditions are detected, heating is limited to the `security_default_on_percent` parameter. This value should therefore be reasonably low (10% is a good value). It helps avoid a fire while preventing the radiator from being completely turned off (risk of freezing).
All these parameters are configured on the last page of the VTherm configuration: "Advanced Settings".
### How to detect Safety Mode?
The first symptom is an unusually low temperature with a short and consistent heating time during each cycle.
Example:
[security mode](images/security-mode-symptome1.png)
If you have installed the [Versatile Thermostat UI Card](https://github.com/jmcollin78/versatile-thermostat-ui-card), the affected VTherm will appear like this:
[security mode UI Card](images/security-mode-symptome2.png)
You can also check the VTherm's attributes for the dates of the last received values. **The attributes are available in the Developer Tools / States**.
Example:
```yaml
security_state: true
last_temperature_datetime: "2023-12-06T18:43:28.346010+01:00"
last_ext_temperature_datetime: "2023-12-06T13:04:35.164367+01:00"
last_update_datetime: "2023-12-06T18:43:28.351103+01:00"
...
security_delay_min: 60
```
We can see that:
1. The VTherm is indeed in safety mode (`security_state: true`),
2. The current time is 06/12/2023 at 18:43:28 (`last_update_datetime: "2023-12-06T18:43:28.351103+01:00"`),
3. The last reception time of the room temperature is 06/12/2023 at 18:43:28 (`last_temperature_datetime: "2023-12-06T18:43:28.346010+01:00"`), so it's recent,
4. The last reception time of the external temperature is 06/12/2023 at 13:04:35 (`last_ext_temperature_datetime: "2023-12-06T13:04:35.164367+01:00"`). The external temperature is over 5 hours late, which triggered the safety mode, as the threshold is set to 60 minutes (`security_delay_min: 60`).
### How to Be Notified When This Happens?
The VTherm sends an event as soon as this happens and again at the end of the safety alert. You can capture these events in an automation and send a notification, blink a light, trigger a siren, etc. It's up to you.
For handling events generated by VTherm, see [Events](#events).
### How to Fix It?
It depends on the cause of the problem:
1. If a sensor is faulty, it should be repaired (replace batteries, change it, check the weather integration that provides the external temperature, etc.),
2. If the `security_delay_min` parameter is too small, it may generate many false alerts. A correct value is around 60 minutes, especially if you have battery-powered temperature sensors. See [my settings](tuning-examples.md#battery-powered-temperature-sensor),
3. Some temperature sensors don't send measurements if the temperature hasn't changed. So if the temperature stays very stable for a long time, safety mode can trigger. This is not a big issue since it will deactivate once the VTherm receives a new temperature. On some thermometers (e.g., TuYA or Zigbee), you can force a max delay between two measurements. The max delay should be set to a value lower than `security_delay_min`,
4. As soon as the temperature is received again, safety mode will turn off, and the previous preset, target temperature, and mode values will be restored.
5. If the external temperature sensor is faulty, you can disable safety mode triggering as it has a minimal impact on the results. To do so, see [here](feature-advanced.md#safety-mode).
## Using a Group of People as a Presence Sensor
Unfortunately, groups of people are not recognized as presence sensors. Therefore, you cannot use them directly in VTherm.
A workaround is to create a binary sensor template with the following code:
File `template.yaml`:
```yaml
- binary_sensor:
- name: maison_occupee
unique_id: maison_occupee
state: "{{is_state('person.person1', 'home') or is_state('person.person2', 'home') or is_state('input_boolean.force_presence', 'on')}}"
device_class: occupancy
```
In this example, note the use of an `input_boolean` called `force_presence`, which forces the sensor to `True`, thereby forcing any VTherm that uses it to have active presence. This can be used, for example, to trigger a pre-heating of the house when leaving work or when an unrecognized person is present in HA.
File `configuration.yaml`:
```yaml
...
template: !include templates.yaml
...
```
## Enable Logs for the Versatile Thermostat
Sometimes, you will need to enable logs to fine-tune your analysis. To do this, edit the `logger.yaml` file in your configuration and configure the logs as follows:
```yaml
default: xxxx
logs:
custom_components.versatile_thermostat: info
```
You must reload the YAML configuration (Developer Tools / YAML / Reload all YAML configuration) or restart Home Assistant for this change to take effect.
Be careful, in debug mode, Versatile Thermostat is very verbose and can quickly slow down Home Assistant or saturate your hard drive. If you switch to debug mode for anomaly analysis, do so only for the time needed to reproduce the bug and disable debug mode immediately afterward.

View File

@@ -1,60 +0,0 @@
# Tuning Examples
- [Tuning Examples](#tuning-examples)
- [Electric Heating](#electric-heating)
- [Central Heating (gas or oil heating)](#central-heating-gas-or-oil-heating)
- [Battery-Powered Temperature Sensor](#battery-powered-temperature-sensor)
- [Reactive Temperature Sensor (plugged in)](#reactive-temperature-sensor-plugged-in)
- [My Presets](#my-presets)
## Electric Heating
- Cycle: between 5 and 10 minutes,
- minimal_activation_delay_sec: 30 seconds
## Central Heating (gas or oil heating)
- Cycle: between 30 and 60 minutes,
- minimal_activation_delay_sec: 300 seconds (due to response time)
## Battery-Powered Temperature Sensor
These sensors are often sluggish and do not always send temperature readings when the temperature is stable. Therefore, the settings should be loose to avoid false positives.
- security_delay_min: 60 minutes (because these sensors are sluggish)
- security_min_on_percent: 0.7 (70% - the system goes into security mode if the heater was on more than 70% of the time)
- security_default_on_percent: 0.4 (40% - in security mode, we maintain 40% heating time to avoid getting too cold)
These settings should be understood as follows:
> If the thermometer stops sending temperature readings for 1 hour and the heating percentage (``on_percent``) was greater than 70%, then the heating percentage will be reduced to 40%.
Feel free to adjust these settings to your specific case!
The important thing is not to take too much risk with these parameters: assume you are absent for a long period, and the batteries of your thermometer are running low, your heater will run 40% of the time during the whole failure period.
Versatile Thermostat allows you to be notified when such an event occurs. Set up the appropriate alerts as soon as you start using this thermostat. See (#notifications).
## Reactive Temperature Sensor (plugged in)
A powered thermometer is supposed to be very regular in sending temperature readings. If it doesn't send anything for 15 minutes, it most likely has an issue, and we can react faster without the risk of a false positive.
- security_delay_min: 15 minutes
- security_min_on_percent: 0.5 (50% - the system goes into ``security`` preset if the heater was on more than 50% of the time)
- security_default_on_percent: 0.25 (25% - in ``security`` preset, we keep 25% heating time)
## My Presets
This is just an example of how I use the preset. You can adapt it to your configuration, but it may be useful to understand its functionality.
``Frost Protection``: 10°C
``Eco``: 17°C
``Comfort``: 19°C
``Boost``: 20°C
When presence is disabled:
``Frost Protection``: 10°C
``Eco``: 16.5°C
``Comfort``: 17°C
``Boost``: 17.5°C
The motion detector in my office is configured to use ``Boost`` when motion is detected and ``Eco`` otherwise.
The security mode is configured as follows:
![My settings](images/my-tuning.png)

View File

@@ -1,216 +0,0 @@
# Quelques compléments indispensables
- [Quelques compléments indispensables](#quelques-compléments-indispensables)
- [Versatile Thermostat UI Card](#versatile-thermostat-ui-card)
- [Composant Scheduler !](#composant-scheduler-)
- [Courbes de régulattion avec Plotly](#courbes-de-régulattion-avec-plotly)
- [Les notification avec l'AappDaemon NOTIFIER](#les-notification-avec-laappdaemon-notifier)
## Versatile Thermostat UI Card
Une carte spéciale pour le Versatile Thermostat a été développée (sur la base du Better Thermostat). Elle est dispo ici [Versatile Thermostat UI Card](https://github.com/jmcollin78/versatile-thermostat-ui-card) et propose une vision moderne de tous les status du VTherm :
![image](https://github.com/jmcollin78/versatile-thermostat-ui-card/blob/master/assets/1.png?raw=true)
## Composant Scheduler !
Afin de profiter de toute la puissance du Versatile Thermostat, je vous invite à l'utiliser avec https://github.com/nielsfaber/scheduler-component
En effet, le composant scheduler propose une gestion de la base climatique sur les modes prédéfinis. Cette fonctionnalité a un intérêt limité avec le thermostat générique mais elle devient très puissante avec le Versatile Thermostat :
À partir d'ici, je suppose que vous avez installé Versatile Thermostat et Scheduler Component.
Dans Scheduler, ajoutez un planning :
![image](https://user-images.githubusercontent.com/1717155/119146454-ee1a9d80-ba4a-11eb-80ae-3074c3511830.png)
Choisissez le groupe "climat", choisissez une (ou plusieurs) entité(s), sélectionnez "MAKE SCHEME" et cliquez sur suivant :
(il est possible de choisir "SET PRESET", mais je préfère utiliser "MAKE SCHEME")
![image](https://user-images.githubusercontent.com/1717155/119147210-aa746380-ba4b-11eb-8def-479a741c0ba7.png)
Définissez votre schéma de mode et enregistrez :
![image](https://user-images.githubusercontent.com/1717155/119147784-2f5f7d00-ba4c-11eb-9de4-5e62ff5e71a8.png)
Dans cet exemple, j'ai réglé le mode ECO pendant la nuit et le jour lorsqu'il n'y a personne à la maison BOOST le matin et CONFORT le soir.
J'espère que cet exemple vous aidera, n'hésitez pas à me faire part de vos retours !
## Courbes de régulattion avec Plotly
Vous pouvez obtenir une courbe comme celle présentée dans [some results](#some-results) avec une sorte de configuration de graphique Plotly uniquement en utilisant les attributs personnalisés du thermostat décrits [ici](#custom-attributes) :
Remplacez les valeurs entre [[ ]] par les votres.
<details>
```yaml
- type: custom:plotly-graph
entities:
- entity: '[[climate]]'
attribute: temperature
yaxis: y1
name: Consigne
- entity: '[[climate]]'
attribute: current_temperature
yaxis: y1
name:
- entity: '[[climate]]'
attribute: ema_temp
yaxis: y1
name: Ema
- entity: '[[climate]]'
attribute: on_percent
yaxis: y2
name: Power percent
fill: tozeroy
fillcolor: rgba(200, 10, 10, 0.3)
line:
color: rgba(200, 10, 10, 0.9)
- entity: '[[slope]]'
name: Slope
fill: tozeroy
yaxis: y9
fillcolor: rgba(100, 100, 100, 0.3)
line:
color: rgba(100, 100, 100, 0.9)
hours_to_show: 4
refresh_interval: 10
height: 800
config:
scrollZoom: true
layout:
margin:
r: 50
legend:
x: 0
'y': 1.2
groupclick: togglegroup
title:
side: top right
yaxis:
visible: true
position: 0
yaxis2:
visible: true
position: 0
fixedrange: true
range:
- 0
- 1
yaxis9:
visible: true
fixedrange: false
range:
- -2
- 2
position: 1
xaxis:
rangeselector:
'y': 1.1
x: 0.7
buttons:
- count: 1
step: hour
- count: 12
step: hour
- count: 1
step: day
- count: 7
step: day
```
</details>
Exemple de courbes obtenues avec Plotly :
![image](images/plotly-curves.png)
## Les notification avec l'AappDaemon NOTIFIER
Cette automatisation utilise l'excellente App Daemon nommée NOTIFIER développée par Horizon Domotique que vous trouverez en démonstration [ici](https://www.youtube.com/watch?v=chJylIK0ASo&ab_channel=HorizonDomotique) et le code est [ici](https://github.com/jlpouffier/home-assistant-config/blob/master/appdaemon/apps/notifier.py). Elle permet de notifier les utilisateurs du logement lorsqu'un des évènements touchant à la sécurité survient sur un des Versatile Thermostats.
C'est un excellent exemple de l'utilisation des notifications décrites ici [notification](#notifications).
<details>
```yaml
alias: Surveillance Mode Sécurité chauffage
description: Envoi une notification si un thermostat passe en mode sécurité ou power
trigger:
- platform: event
event_type: versatile_thermostat_security_event
id: versatile_thermostat_security_event
- platform: event
event_type: versatile_thermostat_power_event
id: versatile_thermostat_power_event
- platform: event
event_type: versatile_thermostat_temperature_event
id: versatile_thermostat_temperature_event
condition: []
action:
- choose:
- conditions:
- condition: trigger
id: versatile_thermostat_security_event
sequence:
- event: NOTIFIER
event_data:
action: send_to_jmc
title: >-
Radiateur {{ trigger.event.data.name }} - {{
trigger.event.data.type }} Sécurité
message: >-
Le radiateur {{ trigger.event.data.name }} est passé en {{
trigger.event.data.type }} sécurité car le thermomètre ne répond
plus.\n{{ trigger.event.data }}
callback:
- title: Stopper chauffage
event: stopper_chauffage
image_url: /media/local/alerte-securite.jpg
click_url: /lovelace-chauffage/4
icon: mdi:radiator-off
tag: radiateur_security_alerte
persistent: true
- conditions:
- condition: trigger
id: versatile_thermostat_power_event
sequence:
- event: NOTIFIER
event_data:
action: send_to_jmc
title: >-
Radiateur {{ trigger.event.data.name }} - {{
trigger.event.data.type }} Délestage
message: >-
Le radiateur {{ trigger.event.data.name }} est passé en {{
trigger.event.data.type }} délestage car la puissance max est
dépassée.\n{{ trigger.event.data }}
callback:
- title: Stopper chauffage
event: stopper_chauffage
image_url: /media/local/alerte-delestage.jpg
click_url: /lovelace-chauffage/4
icon: mdi:radiator-off
tag: radiateur_power_alerte
persistent: true
- conditions:
- condition: trigger
id: versatile_thermostat_temperature_event
sequence:
- event: NOTIFIER
event_data:
action: send_to_jmc
title: >-
Le thermomètre du radiateur {{ trigger.event.data.name }} ne
répond plus
message: >-
Le thermomètre du radiateur {{ trigger.event.data.name }} ne
répond plus depuis longtemps.\n{{ trigger.event.data }}
image_url: /media/local/thermometre-alerte.jpg
click_url: /lovelace-chauffage/4
icon: mdi:radiator-disabled
tag: radiateur_thermometre_alerte
persistent: true
mode: queued
max: 30
```
</details>

View File

@@ -1,69 +0,0 @@
# Les différents algorithmes utilisés
- [Les différents algorithmes utilisés](#les-différents-algorithmes-utilisés)
- [L'algorithme TPI](#lalgorithme-tpi)
- [Configurez les coefficients de l'algorithme TPI](#configurez-les-coefficients-de-lalgorithme-tpi)
- [Principe](#principe)
- [L'algorithme d'auto-régulation (sans contrôle de la vanne)](#lalgorithme-dauto-régulation-sans-contrôle-de-la-vanne)
- [L'algorithme de la fonction d'auto-start/stop](#lalgorithme-de-la-fonction-dauto-startstop)
## L'algorithme TPI
### Configurez les coefficients de l'algorithme TPI
Si vous avez choisi un thermostat de type ```over_switch``` ou ```over_valve``` ou `over_climate` avec l'auto-régulation `Controle direct de la vanne` et que vous sélectionnez l'option "TPI" vous menu, vous arriverez sur cette page :
![image](images/config-tpi.png)
Vous devez donner :
1. le coefficient coef_int de l'algorithme TPI,
2. le coefficient coef_ext de l'algorithme TPI
### Principe
L'algorithme TPI consiste à calculer à chaque cycle un pourcentage d'état On vs Off pour le radiateur en utilisant la température cible, la température actuelle dans la pièce et la température extérieure actuelle. Cet algorithme n'est donc valable que pour les Versatile Thermostat qui régulent : `over_switch` et `over_valve`.
Le pourcentage est calculé avec cette formule :
on_percent = coef_int * (température cible - température actuelle) + coef_ext * (température cible - température extérieure)
Ensuite, l'algo fait en sorte que 0 <= on_percent <= 1
Les valeurs par défaut pour coef_int et coef_ext sont respectivement : ``0.6`` et ``0.01``. Ces valeurs par défaut conviennent à une pièce standard bien isolée.
Pour régler ces coefficients, gardez à l'esprit que :
1. **si la température cible n'est pas atteinte** après une situation stable, vous devez augmenter le ``coef_ext`` (le ``on_percent`` est trop bas),
2. **si la température cible est dépassée** après une situation stable, vous devez diminuer le ``coef_ext`` (le ``on_percent`` est trop haut),
3. **si l'atteinte de la température cible est trop lente**, vous pouvez augmenter le ``coef_int`` pour donner plus de puissance au réchauffeur,
4. **si l'atteinte de la température cible est trop rapide et que des oscillations apparaissent** autour de la cible, vous pouvez diminuer le ``coef_int`` pour donner moins de puissance au radiateur.
En type `over_valve` le `on_percent` est ramené à une valeur entre 0 et 100% et sert directement à commander l'ouverture de la vanne.
## L'algorithme d'auto-régulation (sans contrôle de la vanne)
L'algorithme d'auto-régulation peut être synthétisé comme suit:
1. initialiser la température cible comme la consigne du VTherm,
1. Si l'auto-régulation est activée,
1. calcule de la température régulée (valable pour un VTherm),
2. prendre cette température comme cible,
2. Pour chaque sous-jacent du VTherm,
1. Si "utiliser la température interne" est cochée,
1. calcule de la compensation (trv internal temp - room temp),
2. ajout de l'écart à la température cible,
3. envoie de la température cible ( = temp regulee + (temp interne - temp pièce)) au sous-jacent
## L'algorithme de la fonction d'auto-start/stop
L'algorithme utilisé dans la fonction d'auto-start/stop est le suivant :
1. if enable aut-start/stop is off, stop here.
2. If VTherm is on and in heating mode, when error_accumulated is < -error_threshold -> turn off and save hvac mode,
3. If VTherm is on and in Cooling mode, when error_accumulated is > error_threshold -> turn off and save hvac mode,
4. If VTherm is off and saved hvac mode is Heating and current_temperature + slope x dt <= target_temperature then turn on and set havc mode to the saved hvac_mode,
5. If VTherm is off and saved hvac mode is Cooling and current_temperature + slope x dt >= target_temperature then turn on and set havc mode to the saved hvac_mode
6. error_threshold is set to respectively 10 (° * min) in slow, 5 in medium and 2 in fast.
dt is set to respectively 30 min in slow, 15 min in medium and 7 min in fast detection level.
La fonction est décrite dans le détail [ici](https://github.com/jmcollin78/versatile_thermostat/issues/585).

View File

@@ -1,46 +0,0 @@
- [Choix des attributs de base](#choix-des-attributs-de-base)
- [Choix des fonctions utilisées](#choix-des-fonctions-utilisées)
# Choix des attributs de base
Choisisez le menu "Principaux attributs".
![image](images/config-main.png)
Donnez les principaux attributs obligatoires. Ces attributs sont communs à tous les VTherms :
1. un nom (sera le nom de l'intégration et aussi le nom de l'entité `climate`)
4. un identifiant d'entité de capteur de température qui donne la température de la pièce dans laquelle le radiateur est installé,
5. une entité facultative de capteur de donnant la date et heure de dernière vue du capteur (`last_seen`). Si vous avez ce capteur donnez le ici, il permet d'éviter des mises en sécurité lorsque la température est stable et que le capteur ne remonte plus de température pendant longtemps. (cf. [ici](troubleshooting.md#pourquoi-mon-versatile-thermostat-se-met-en-securite-)),
6. une durée de cycle en minutes. A chaque cycle :
1. `over_switch` : VTherm allumera/éteindra le radiateur en modulant la proportion de temps allumé,
2. `over_valve` : VTherm calculera une nouvelle ouverture de la vanne et lui enverra si elle a changée,
3. `over_climate` : le cycle permet d'effectuer les contrôles de base et recalcule les coefficients de l'auto-régulation. Le cycle peut déboucher sur une nouvelle consigne envoyée au sous-jacents ou sur une modification d'ouverture de la vanne dans le cas d'un _TRV_ dont la vanne est commandable.
7. une puissance de l'équipement ce qui va activer les capteurs de puissance et énergie consommée par l'appareil. Si plusieurs équipements sont reliés au même VTherm, il faut indiquer ici le total des puissances max des équipements,
8. la possibilité d'utiliser des paramètres complémentaires venant de la configuration centralisée :
1. capteur de température extérieure,
2. température minimale / maximale et pas de température
9. la possibilité de controler le thermostat de façon centralisée. Cf [controle centralisé](#le-contrôle-centralisé),
10. une case à cocher si ce VTherm est utilisé pour déclencher une éventuelle chaudière centrale.
> ![Astuce](images/tips.png) _*Notes*_
> 1. avec les types ```over_switch``` et ```over_valve```, les calculs sont effectués à chaque cycle. Donc en cas de changement de conditions, il faudra attendre le prochain cycle pour voir un changement. Pour cette raison, le cycle ne doit pas être trop long. **5 min est une bonne valeur** mais doit être adapté à votre type de chauffage. Plus l'inertie est grande et plus le cycle doit être long. Cf. [Exemples de réglages](tuning-examples.md),
> 2. si le cycle est trop court, le radiateur ne pourra jamais atteindre la température cible. Pour le radiateur à accumulation par exemple il sera sollicité inutilement.
# Choix des fonctions utilisées
Choisissez le menu "Fonctions".
![image](images/config-features.png)
Les différentes fonctions que vous souhaitez utiliser pour ce VTherm :
1. la détection d'ouvertures (portes, fenêtres) permettant de stopper le chauffage lorsque l'ouverture est ouverte. (cf. [gestion des ouvertures](feature-window.md))
2. la détection de mouvement : VTherm peut adapter une consigne de température lorsqu'un mouvement est détecté dans la pièce. (cf. [détection du mouvement](feature-motion.md))
3. la gestion de la puissance : VTherm peut stopper un équipement si la puissance consommée dans votre habitation dépasse un seuil. (cf. [gestion du délestage](feature-power.md))
4. la détection de présence : si vous avez un capteur indiquant une présence ou non dans votre habitation, vous pouvez l'utiliser pour changer la température de consigne. Cf. [gestion de la présence](feature-presence.md). Attention de ne pas confondre cette fonction avec la détection de mouvement. La présence est plus faite pour être à l'échelle de l'habitation alors que le mouvement est plus fait pour être à l'échelle de la pièce.
5. l'arrêt/démarrage automatique : pour les VTherm de type `over_climate` uniquement. Cette fonction permet d'arrêter un équipement lorsque VTherm détete qu'il ne sera plus néessaire pendant un certain temps. Il utilise la courbe de température pour prévoir quand l'équipement sera de nouveau utile et le rallumera à ce moment là. Cf. [gestion de l'arrêt/démarrage automatique](feature-auto-start-stop.md)
> ![Astuce](images/tips.png) _*Notes*_
> 1. La liste des fonctions disponibles s'adapte à votre type de VTherm.
> 2. Lorsque vous cochez une fonction, une nouvelle entrée menu s'ajoute pour configurer la fonction.
> 3. Vous ne pourrez pas valider la création d'un VTherm si tous les paramètres de toutes les fonctions n'ont pas été saisis.

View File

@@ -1,72 +0,0 @@
# Choix du Vtherm
- [Choix du Vtherm](#choix-du-vtherm)
- [Création d'un nouveau Versatile Thermostat](#création-dun-nouveau-versatile-thermostat)
- [Choix d'un type de VTherm](#choix-dun-type-de-vtherm)
- [Configuration centralisée](#configuration-centralisée)
- [VTherm sur un switch](#vtherm-sur-un-switch)
- [Vtherm sur un autre thermostat](#vtherm-sur-un-autre-thermostat)
- [VTherm sur une vanne](#vtherm-sur-une-vanne)
- [Le bon choix](#le-bon-choix)
- [Article en référence](#article-en-référence)
> ![Astuce](images/tips.png) _*Notes*_
>
> Trois façons de travailler avec les VTherms sont disponibles :
> 1. Chaque Versatile Thermostat est entièrement configurée de manière indépendante. Choisissez cette option si vous ne souhaitez avoir aucune configuration ou gestion centrale.
> 2. Certains aspects peuvent être configurés de manière centralisée. Cela permet par ex. définir la température min/max, les paramètres de détection de fenêtre ouverte,… au niveau d'une instance centrale et unique. Pour chaque VTherm que vous configurez, vous pouvez alors choisir d'utiliser la configuration centrale ou de la remplacer par des paramètres personnalisés.
> 3. En plus de cette configuration centralisée, tous les VTherm peuvent être contrôlées par une seule entité de type `select`. Cette fonction est nommé `central_mode`. Cela permet de stopper / démarrer / mettre en hors gel / etc tous les VTherms en une seule fois. Pour chaque VTherm, l'utilisateur indique si il est concerné par ce `central_mode`.
## Création d'un nouveau Versatile Thermostat
Cliquez sur le bouton Ajouter une intégration dans la page d'intégration (ou cliquez directement sur 'Ajouter un appareil' depuis la page de configuration de l'intégration)
![image](images/add-an-integration.png)
puis
![image](images/config-main0.png)
La configuration peut être modifiée via la même interface. Sélectionnez simplement le thermostat à modifier, appuyez sur "Configurer" et vous pourrez modifier certains paramètres ou la configuration.
Suivez ensuite les étapes de configuration en sélectionnant dans le menu l'option à configurer.
# Choix d'un type de VTherm
## Configuration centralisée
Ce choix permet de configurer une fois pour tous les VTherms certains aspects qui peuvent être répétitifs comme :
1. les paramètres des différents algorithmes (TPI, détection d'ouvertures, détection de mouvements, capteurs de puissance de votre habitation, la détection de présence). Tous ces paramètres sont transverses à tous les VTherms. Vous pouvez donc ne les saisir qu'une seule fois dans la `Configuration centralisée`. Cette configuration ne créé pas de VTherm à proprement parler. Elle permet juste de mettre en commun des paramètres qu'il serait fastidieux de resaisir pour chaque VTherm. Noter que vous pouvez surcharger les paramètres sur les VTherms pour les spécialisés au besoin,
2. la configuration de la commande d'un chauffage central,
3. certains paramètre avancés comme la mise en sécurité
## VTherm sur un switch
Ce VTherm permet de contrôler un interrupteur qui allume ou étient un radiateur. Cet interrupteur peut être un interrupteur physique qui allume ou éteint directement un radiateur (souvent électrique) ou un interrupteur virtuel qui pourra effectuer les actions que vous voulez sur demande d'allumage ou extinction. Ce dernier type permet par exemple de commander des switchs avec fil pilote ou deu DIY avec diode pour fil pilote. VTherm va moduler la proportion de temps allumé vs éteint pour obtenir la température souhaitée. Si il fait froid, il allume plus souvent (jusqu'à 100%), si il fait chaud il baisse le pourcentage d'allumage. Ce pourcentage d'allumage en nommé `on_percent`.
Les entités sous-jacentes sont donc des `switchs` ou des `input_boolean`.
## Vtherm sur un autre thermostat
Lorsque votre équipement est contrôlé par une entité de type `climate` dans Home Assistant et que vous n'avez que ça à disposition, vous devez utiliser ce type de VTherm. Dans ce cas, le VTherm va simplement commander la température de consigne du `climate` sous-jacent.
Ce type est aussi équipé de fonction d' auto-régulations avancées permettant de moduler la consigne donnée aux sous-jacent pour atteindre plus vite la consigne et de s'affranchir de la régulation interne de ces équipements qui est parfois mauvaise. C'est le cas, si le thermomètre interne de l'équipement est trop proche du corps de chauffe. L'équipement peut croire qu'il fait chaud alors qu'au bout de la pièce, la consigne n'est pas du tout atteinte.
Depuis la version 6.8, ce type de VTherm permet aussi de réguler avec une action directe sur la vanne. Idéal pour les _TRV_ pour lesquels la vanne est commandable, ce type est recommandé si vous êtes équipés.
Les entités sous-jacentes de ce type de VTherm sont donc des `climate` exclusivement.
## VTherm sur une vanne
Lorsque tout ce que vous avez à disposition pour réguler la température de votre radiateur est une entité de type `number` vous devez utiliser le type `over_valve`. VTherm ouvre ou ferme la vanne en fonction de l'écart entre la consigne et la température réelle de la pièce (et de la température extérieure).
Ce type peut être utilisé pour les _TRV_ qui n'ont pas de `climate` associé ou tout autre solution type DIY qui expose une entité `number`.
# Le bon choix
> ![Astuce](images/tips.png) _*Comment choisir le type*_
> Le choix du type est important. Il n'est plus possible de le modifier via l'IHM de configuration. Pour bien chsoisir, il faut se poser les quelques questions suivantes :
> 1. **quel type d'équipement je vais piloter ?** Dans l'ordre voici ce qu'il faut faire :
> 1. si vous avez une vanne thermostatique (_TRV_) commandable dans Home Assistant via une entité de type ```number``` (par exemple une _Shelly TRV_), choisissez le type `over_valve`. C'est le type le plus direct et qui assure la meilleure régulation,
> 2. si vous avez un radiateur électrique (avec ou sans fil pilote) et qu'une entité de type ```switch``` permet de l'allumer ou de l'éteindre, alors le type ```over_switch``` est préférable. La régulation sera faite par le Versatile Thermostat en fonction de la température mesuré par votre thermomètre, à l'endroit ou vous l'avez placé,
> 3. dans tous les autres cas, utilisez le mode ```over_climate```. Vous gardez votre entité ```climate``` d'origine et le Versatile Thermostat "ne fait que" piloter le on/off et la température cible de votre thermostat d'origine. La régulation est faite par votre thermostat d'origine dans ce cas. Ce mode est particulièrement adapté aux climatisations réversible tout-en-un dont l'exposition dans Home Assistant se limite à une entité de type ```climate```. Une auto-régulation avancée permet d'atteindre la consigne en forçant la consigne ou un pilotant directement la vanne lorsque c'est possible.
> 2. **quelle type de régulation je veux ?** Si l'équipement piloté possède son propre mécanisme de régulation (clim, certaine vanne TRV) et que cette régulation fonctionne bien, optez pour un ```over_climate```. Si l'équipement est de type _TRV_ avec une vanne pilotable sous HA, alors le type `over_climate` avec une auto-régulation `Contrôle direct de la vanne` est le meilleur choix.
# Article en référence
Un article permettant d'aller plus loin sur les concepts est visible ici (en Français) : https://www.hacf.fr/optimisation-versatile-thermostat/#optimiser-vos-vtherm

View File

@@ -1,51 +0,0 @@
# La configuration avancée
- [La configuration avancée](#la-configuration-avancée)
- [Configuration avancée](#configuration-avancée)
- [Délai minimal d'activation](#délai-minimal-dactivation)
- [La mise en sécurité](#la-mise-en-sécurité)
Ces paramètres permettent d'affiner le fonctionnement du thermostat et notamment la mise en sécurité d'un _VTherm_. L'absence d'un capteur de température (pièce ou extérieur) peut être dangereux pour votre logement. Supposez que le capteur de température soit bloqué sur 10°. Le _VTherm_ de type `over_climate` ou `over_valve` va alors commander un chauffage maximal des équipements sous-jacents, ce qui peut conduire à une surchauffe de la pièce voire des dommages sur le logement avec au pire un début d'incendie.
Pour éviter cela, _VTherm_ s'assure que les thermomètres répondent bien de façon régulière et met le _VTherm_ dans un mode particuliers nommée le mode sécurité si ce n'est plus le cas. Le mode sécurité consiste à assurer un minimum de chauffe pour éviter l'effet inverse : une habitation qui ne serait plus chauffée du tout en plein hiver par exemple.
Là où le problème devient compliqué, c'est que certain thermomètre - notamment à pile - n'envoie leur température que si elle change. Il est donc tout à fait possible de ne plus recevoir de mises à jour de température pendant plusieurs heures sans que le thermomètre soit en défaut. Les différents paramètres ci-dessous vont permettre de régler finement les seuils de passage en mode sécurité.
Si votre thermomètre est muni d'un capteur nommé `last seen` qui donne l'heure de son dernier contact, il est possible de le spécifier dans les attributs principaux du _VTherm_ pour limiter grandement les fausses mises en sécurité. Cf. [configuration](base-attributes.md#choix-des-attributs-de-base) et [dépannage](troubleshooting.md#pourquoi-mon-versatile-thermostat-se-met-en-securite-).
Pour les _VTherm_ `over_climate` et donc qui se régule lui-même, le mode sécurité est désactivé. En effet il n'y a pas de risque de danger si l'équipement se régule lui-même mais juste un risque de mauvaise température.
## Configuration avancée
Le formulaire de configuration avancée est le suivant :
![image](images/config-advanced.png)
### Délai minimal d'activation
Le premier délai (`minimal_activation_delay_sec`) en secondes est le délai minimum acceptable pour allumer le chauffage. Lorsque le calcul donne un délai de mise sous tension inférieur à cette valeur, le chauffage reste éteint. Ce paramètre ne sert qu'au _VTherm_ avec un déclenchement cyclique `over_switch`. Si le temps d'allumage est trop court, la, commutation rapide ne permettra pas à l'équipement de monter en température.
### La mise en sécurité
Le deuxième délai (`security_delay_min`) est le délai maximal entre deux mesures de température avant de passer le _VTherm_ en mode sécurité.
Le troisième paramètre (`security_min_on_percent`) est la valeur minimal de `on_percent` en dessous de laquelle le préréglage sécurité ne sera pas activé. Ce paramètre permet de ne pas mettre en sécurité un thermostat, si le radiateur piloté ne chauffe pas suffisament. En effet, il n'y a pas de risque physique pour le logement dans ce cas mais juste un risque de surchauffe ou de sous-chauffe.
Mettre ce paramètre à ``0.00`` déclenchera le préréglage sécurité quelque soit la dernière consigne de chauffage, à l'inverse ``1.00`` ne déclenchera jamais le préréglage sécurité ( ce qui revient à désactiver la fonction). Ce peut ê
Le quatrième paramètre (`security_default_on_percent`) est la valeur de `on_percent` qui sera utilisée lorsque le thermostat passe en mode ``security``. Si vous mettez `0` alors le thermostat sera coupé lorsqu'il passe en mode `security`, mettre 0,2% par exemple permet de garder un peu de chauffage (20% dans ce cas), même en mode ``security``. Ca évite de retrouver son logement totalement gelé lors d'une panne de thermomètre.
Il est possible de désactiver la mise en sécurité suite à une absence de données du thermomètre extérieure. En effet, celui-ci ayant la plupart du temps un impact faible sur la régulation (dépendant de votre paramètrage), il est possible qu'il soit absent sans mettre en danger le logement. Pour cela, il faut ajouter les lignes suivantes dans votre `configuration.yaml` :
```yaml
versatile_thermostat:
...
safety_mode:
check_outdoor_sensor: false
```
Par défaut, le thermomètre extérieur peut déclencher une mise en sécurité si il n'envoit plus de valeur. N'oubliez pas que Home Assisstant doit être redémarré pour que ces modifications soient prises en compte. Ce réglage est commun à tous les _VTherm_ (qui devraient partager le thermomètre extérieur.
> ![Astuce](images/tips.png) _*Notes*_
> 1. Lorsque le capteur de température viendra à la vie et renverra les températures, le préréglage sera restauré à sa valeur précédente,
> 2. Attention, deux températures sont nécessaires : la température interne et la température externe et chacune doit donner la température, sinon le thermostat sera en préréglage "security",
> 3. Une action est disponible qui permet de régler les 3 paramètres de sécurité. Ca peut servir à adapter la fonction de sécurité à votre usage,
> 4. Pour un usage naturel, le ``security_default_on_percent`` doit être inférieur à ``security_min_on_percent``,
> 5. Si vous utilisez la carte Verstatile Thermostat UI (cf. [ici](additions.md#bien-mieux-avec-le-versatile-thermostat-ui-card)), un _Vtherm_ en mode sécurité est signalé par un voile grisatre qui donne le thermomètre en défaut et depuis combien de temps le thermomètre n'a pas remonté de valeur : ![mode sécurité](images/safety-mode-icon.png).

View File

@@ -1,41 +0,0 @@
# Le démarrage / arrêt automatique (auto-start/stop)
- [Le démarrage / arrêt automatique (auto-start/stop)](#le-démarrage--arrêt-automatique-auto-startstop)
- [Configurer l'auto-start/stop](#configurer-lauto-startstop)
- [Usage](#usage)
Cette fonction permet d'autoriser VTherm a stopper un équipement qui n'a pas besoin d'être allumé et de le redémarrer lorsque les conditions le réclame. Cette fonction est munie de 3 réglages qui permettent d'arrêter / relancer plus ou moins rapidement l'équipement.
Exclusiveme réservé au _VTherm_ de type `over_climate`, elle répond au cas d'usage suivant :
1. votre équipement est allumé électriquement en permanence et consomme de l'électricité même lorsqu'il n'y a pas besoin de chauffer (resp. refroidir). C'est souvent le cas sur les _PAC_ qui consomment même en veille,
2. les conditions de température font qu'il n'y a pas besoin de chauffer (resP. refroidir) pendant longtemps : la consigne est supérieure (resp. inférieur) à la température de la pièce,
3. la température monte (resp. descend), est stable ou descend (resp. monte) doucement
Dans ce cas, il est préférable de demander à l'équipement de s'éteindre pour éviter la consommation électrique en mode veille.
## Configurer l'auto-start/stop
Pour l'utiliser, vous devez :
1. Ajouter la fonction `Avec démmarrage et extinction automatique` dans le menu 'Fonctions',
2. Paramétrer le niveau de détection dans l'option 'Allumage/extinction automatique' qui s'affiche lorsque la fonction a été activée. Vous choisissez le niveau de détection entre 'Lent', 'Moyen' et 'Rapide'. Les arrêts/relances seront plus nombreux avec le niveau 'Rapide'.
![image](images/config-auto-start-stop.png)
Le réglage 'Lent' permet d'avoir environ 30 min entre un arrêt et une relance,
Le réglage 'Moyen' met le seuil a environ 15 min et le réglage rapide le met à 7 min.
Attention, ce ne sont pas des réglages absolus puisque l'algorithme tient compte de la pente de la courbe température de la pièce pour réagir. Il est toujours possible qu'un démarrage ait lieu peu après une extinction si la chute de température est importante.
## Usage
Une fois la fonction paramétrée, vous aurez maintenant une nouvelle entité de type `switch` qui vous permet d'autoriser ou non l'arrêt/relance automatique sans toucher à la configuration. Cette entité est disponible sur l'appareil VTherm et se nomme `switch.<name>_enable_auto_start_stop`.
![image](images/enable-auto-start-stop-entity.png)
Cochez la pour autoriser le démarrage et extinction automatique et laissez là décocher si vous voulez désactiver la fonction auto-start/stop.
> ![Astuce](images/tips.png) _*Notes*_
> 1. L'algorithme de détection est décrit [ici](algorithms.md#lalgorithme-de-la-fonction-dauto-startstop).
> 2. Certains équipements (chaudière, chauffage au sol, _PAC_, ...) n'aiment pas forcément être arrêtés / stoppés trop souvent. Si vous êtes dans ce cas, il peut être préférable de desactiver la fonction lorsque vous savez qu'il va être utilisé. Par exemple, je désactive cette fonction en journée si il y a une présence de détectée car je sais que ma _PAC_ va s'allumer souvent. J'autorise l'auto-start/stop la nuit ou en cas d'absence puisque la consigne est abaissée et qu'elle se déclenche peu voir pas du tout.
> 3. Si vous utilisez la carte Verstatile Thermostat UI (cf. [ici](additions.md#bien-mieux-avec-le-versatile-thermostat-ui-card)), une case à cocher est directement visible sur la carte pour désactiver l'auto-start/stop et un _Vtherm_ stoppé par l'auto-start/stop est signalé par l'icone : ![auto-start/stop icone](images/auto-start-stop-icon.png).

View File

@@ -1,110 +0,0 @@
# Le contrôle d'une chaudière centrale
- [Le contrôle d'une chaudière centrale](#le-contrôle-dune-chaudière-centrale)
- [Principe](#principe)
- [Configuration](#configuration)
- [Comment trouver la bonne action ?](#comment-trouver-la-bonne-action-)
- [Les évènements](#les-évènements)
- [Avertissement](#avertissement)
Vous avez la possibilité de contrôler une chaudière centralisée. A partir du moment où il est possible de déclencher ou stopper cette chaudière depuis Home Assistant, alors Versatile Thermostat va pouvoir la commander directement.
## Principe
Le principe mis en place est globalement le suivant :
1. une nouvelle entité de type `binary_sensor` et nommée par défaut `binary_sensor.central_boiler` est ajoutée,
2. dans la configuration des VTherms vous indiquez si le VTherm doit contrôler la chaudière. En effet, dans une installation hétérogène, certains VTherm doivent commander la chaudière et d'autres non. Vous devez donc indiquer dans chaque configuration de VTherm si il contrôle la chaudière ou pas,
3. le `binary_sensor.central_boiler` écoute les changements d'états des équipements des VTherm marqués comme contrôlant la chaudière,
4. dès que le nombre d'équipements pilotés par le VTherm demandant du chauffage (ie son `hvac_action` passe à `Heating`) dépasse un seuil paramétrable, alors le `binary_sensor.central_boiler` passe à `on` et **si un service d'activation a été configuré, alors ce service est appelé**,
5. si le nombre d'équipements nécessitant du chauffage repasse en dessous du seuil, alors le `binary_sensor.central_boiler` passe à `off` et si **un service de désactivation a été configuré, alors ce service est appelé**,
6. vous avez accès à deux entités :
- une de type `number` nommé par défaut `number.boiler_activation_threshold`, donne le seuil de déclenchement. Ce seuil est en nombre d'équipements (radiateurs) qui demande du chauffage.
- une de type `sensor` nommé par défaut `sensor.nb_device_active_for_boiler`, donne le nombre d'équipements qui demande du chauffage. Par exemple, un VTherm ayant 4 vannes dont 3 demandes du chauffage fera passé ce capteur à 3. Seuls les équipements des VTherms qui sont marqués pour contrôler la chaudière centrale sont comptabilisés.
Vous avez donc en permanence, les informations qui permettent de piloter et régler le déclenchement de la chaudière.
Toutes ces entités sont rattachés au service de configuration centrale :
![Les entités pilotant la chaudière](images/entitites-central-boiler.png)
## Configuration
Pour configurer cette fonction, vous devez avoir une configuration centralisée (cf. [Configuration](#configuration)) et cochez la case 'Ajouter une chaudière centrale' :
![Ajout d'une chaudière centrale](images/config-central-boiler-1.png)
Sur la page suivante vous pouvez donner la configuration des actions (ex services) à appeler lors de l'allumage / extinction de la chaudière :
![Ajout d'une chaudière centrale](images/config-central-boiler-2.png)
Les actions (ex services) se configurent comme indiqués dans la page :
1. le format général est `entity_id/service_id[/attribut:valeur]` (où `/attribut:valeur` est facultatif),
2. `entity_id` est le nom de l'entité qui commande la chaudière sous la forme `domain.entity_name`. Par exemple: `switch.chaudiere` pour les chaudière commandée par un switch ou `climate.chaudière` pour une chaudière commandée par un thermostat ou tout autre entité qui permet le contrôle de la chaudière (il n'y a pas de limitation). On peut aussi commuter des entrées (`helpers`) comme des `input_boolean` ou `input_number`.
3. `service_id` est le nom du service à appeler sous la forme `domain.service_name`. Par exemple: `switch.turn_on`, `switch.turn_off`, `climate.set_temperature`, `climate.set_hvac_mode` sont des exemples valides.
4. pour certain service vous aurez besoin d'un paramètre. Cela peut être le 'Mode CVC' `climate.set_hvac_mode` ou la température cible pour `climate.set_temperature`. Ce paramètre doit être configuré sous la forme `attribut:valeur` en fin de chaine.
Exemples (à ajuster à votre cas) :
- `climate.chaudiere/climate.set_hvac_mode/hvac_mode:heat` : pour allumer le thermostat de la chaudière en mode chauffage,
- `climate.chaudiere/climate.set_hvac_mode/hvac_mode:off` : pour stopper le thermostat de la chaudière,
- `switch.pompe_chaudiere/switch.turn_on` : pour allumer le swicth qui alimente la pompe de la chaudière,
- `switch.pompe_chaudiere/switch.turn_off` : pour allumer le swicth qui alimente la pompe de la chaudière,
- ...
### Comment trouver la bonne action ?
Pour trouver l'action à utiliser, le mieux est d'aller dans "Outils de développement / Actions", chercher l'action à appeler, l'entité à commander et l'éventuel paramètre à donner.
Cliquez sur 'Appeler l'action'. Si votre chaudière s'allume vous avez la bonne configuration. Passez alors en mode Yaml et recopiez les paramètres.
Exemple:
Sous "Outils de développement / Actions" :
![Configuration du service](images/dev-tools-turnon-boiler-1.png)
En mode yaml :
![Configuration du service](images/dev-tools-turnon-boiler-2.png)
Le service à configurer est alors le suivant: `climate.empty_thermostast/climate.set_hvac_mode/hvac_mode:heat` (notez la suppression du blanc dans `hvac_mode:heat`)
Faite alors de même pour le service d'extinction et vous êtes parés.
## Les évènements
A chaque allumage ou extinction réussie de la chaudière un évènement est envoyé par Versatile Thermostat. Il peut avantageusement être capté par une automatisation, par exemple pour notifier un changement.
Les évènements ressemblent à ça :
Un évènement d'allumage :
```yaml
event_type: versatile_thermostat_central_boiler_event
data:
central_boiler: true
entity_id: binary_sensor.central_boiler
name: Central boiler
state_attributes: null
origin: LOCAL
time_fired: "2024-01-14T11:33:52.342026+00:00"
context:
id: 01HM3VZRJP3WYYWPNSDAFARW1T
parent_id: null
user_id: null
```
Un évènement d'extinction :
```yaml
event_type: versatile_thermostat_central_boiler_event
data:
central_boiler: false
entity_id: binary_sensor.central_boiler
name: Central boiler
state_attributes: null
origin: LOCAL
time_fired: "2024-01-14T11:43:52.342026+00:00"
context:
id: 01HM3VZRJP3WYYWPNSDAFBRW1T
parent_id: null
user_id: null
```
## Avertissement
> ![Astuce](images/tips.png) _*Notes*_
>
> Le contrôle par du logiciel ou du matériel de type domotique d'une chaudière centrale peut induire des risques pour son bon fonctionnement. Assurez-vous avant d'utiliser ces fonctions, que votre chaudière possède bien des fonctions de sécurité et que celles-ci fonctionnent. Allumer une chaudière si tous les robinets sont fermés peut générer de la sur-pression par exemple.

View File

@@ -1,32 +0,0 @@
# Le contrôle centralisé
- [Le contrôle centralisé](#le-contrôle-centralisé)
- [Configuration du contrôle centralisée](#configuration-du-contrôle-centralisée)
- [Usage](#usage)
Cette fonction vous permet de contrôler tous vos _VTherm_ depuis un unique point de contrôle.
Le cas d'usage typique est lorsque vous partez pour une longue durée, vous voulez mettre tous vos _VTherm_ en Hors-gel et lorsque vous rentrez, vous voulez les remettre dans l'état initial.
Le contrôle centralisé se fait depuis un _Vtherm_ spécial nommé configuration centralisée. Cf. [ici](creation.md#configuration-centralisée) pour plus d'informations.
## Configuration du contrôle centralisée
Si vous avez défini une configuration centralisée, vous avez une nouvelle entité nommée `select.central_mode` qui permet de piloter tous les VTherms avec une seule action.
![central_mode](images/central-mode.png)
Cette entité se présente sous la forme d'une liste de choix qui contient les choix suivants :
1. `Auto` : le mode 'normal' dans lequel chaque VTherm se comporte de façon autonome,
2. `Stopped` : tous les VTherms sont mis à l'arrêt (`hvac_off`),
3. `Heat only` : tous les VTherms sont mis en mode chauffage lorsque ce mode est supporté par le VTherm, sinon il est stoppé,
4. `Cool only` : tous les VTherms sont mis en mode climatisation lorsque ce mode est supporté par le VTherm, sinon il est stoppé,
5. `Frost protection` : tous les VTherms sont mis en preset hors-gel lorsque ce preset est supporté par le VTherm, sinon il est stoppé.
## Usage
Pour qu'un VTherm soit contrôlable de façon centralisée, il faut que son attribut de configuration nommé `use_central_mode` soit vrai. Cet attribut est disponible dans la page de configuration `Principaux ttributs`
![central_mode](images/use-central-mode.png)
Il est donc possible de contrôler tous les VTherms (que ceux que l'on désigne explicitement) avec un seul contrôle.

View File

@@ -1,40 +0,0 @@
# La détection de mouvement ou d'activité
- [La détection de mouvement ou d'activité](#la-détection-de-mouvement-ou-dactivité)
- [Configurer le mode d'activité ou la détection de mouvement](#configurer-le-mode-dactivité-ou-la-détection-de-mouvement)
- [Usage](#usage)
Cette fonction vous permet de changer de preset lorsqu'un mouvement est détectée dans une pièce. Si vous ne souhaitez chauffer votre bureau, lorsque la pièce est occupée et uniquement si la pièce est occupée, il vous faut un capteur de mouvement (ou de présence) dans la pièce et configurer cette fonction.
Cette fonction est souvent confondue avec la fonction de présence. Elles sont complémentaires mais ne se remplace pas. La fonction 'mouvement' est locale à une pièce équipe d'un capteur de mouvement alors que la fonction 'présence' est prévue pour être globale à tout le logement.
## Configurer le mode d'activité ou la détection de mouvement
Si vous avez choisi la fonctionnalité `Avec détection de mouvement`, :
![image](images/config-motion.png)
Ce dont nous avons besoin:
- un **capteur de mouvement**. ID d'entité d'un capteur de mouvement. Les états du capteur de mouvement doivent être « on » (mouvement détecté) ou « off » (aucun mouvement détecté)
- une durée de **délai d'activation** (en secondes) définissant combien de temps nous attendons la confirmation du mouvement avant de considérer le mouvement. Ce paramètre peut être **supérieur à la temporisation de votre détecteur de mouvement**, sinon la détection se fera à chaque mouvement signalé par le détecteur,
- une durée de fin **délai de désactivation** (en secondes) définissant combien de temps nous attendons la confirmation d'une fin de mouvement avant de ne plus considérer le mouvement.
- un **préréglage de "mouvement"**. Nous utiliserons la température de ce préréglage lorsqu'une activité sera détectée.
- un **préréglage "pas de mouvement"**. Nous utiliserons la température de ce deuxième préréglage lorsqu'aucune activité n'est détectée.
## Usage
Pour indiquer à un _VTherm_ qu'il doit écouter le capteur de mouvement, vous devez le mettre dans le preset spécial 'Activité'. Si vous avez installé la carte Versatile Thermostat UI (cf. [ici](additions.md#bien-mieux-avec-le-versatile-thermostat-ui-card)), ce preset est représenté comme suit : ![preset Activité](images/activity-preset-icon.png).
Vous pouvez ainsi, sur demande, mettre un _VTherm_ en mode détection de mouvement.
Le comportement va être le suivant :
- nous avons une pièce avec un thermostat réglé en mode activité, le mode "mouvement" choisi est confort (21,5°C), le mode "pas de mouvement" choisi est Eco (18.5°C) et la temporisation du mouvement est de 30 sec lors de la détection et de 5 minutes sur fin de détection.
- la pièce est vide depuis un moment (aucune activité détectée), la température de consigne de cette pièce est de 18,5°
- quelqu'un entre dans la pièce, une activité est détectée si le mouvement est présent pendant au moins 30 sec. La température passe alors à 21,5°
- si le mouvement est présent pendant moins de 30 sec (passage rapide), la température reste sur 18,5°,
- imaginons que la température soit passée sur 21,5°, lorsque la personne quitte la pièce, au bout de 5 min la température est ramenée à 18,5°.
- si la personne revient avant les 5 minutes, la température reste sur 21,5°
> ![Astuce](images/tips.png) _*Notes*_
> 1. Sachez que comme pour les autres preset, `Activité` ne sera proposé que s'il est correctement configuré. En d'autres termes, les 4 clés de configuration doivent être définies
> 2. Si vous utilisez la carte Verstatile Thermostat UI (cf. [ici](additions.md#bien-mieux-avec-le-versatile-thermostat-ui-card)), une détection de mouvement est représenté comme suit : ![motion](images/motion-detection-icon.png).

View File

@@ -1,46 +0,0 @@
# Gestion de la puissance - délestage
- [Gestion de la puissance - délestage](#gestion-de-la-puissance---délestage)
- [Configurer la gestion de la puissance](#configurer-la-gestion-de-la-puissance)
Cette fonction vous permet de réguler la consommation électrique de vos radiateurs. Connue sous le nom de délestage, cette fonction vous permet de limiter la consommation électrique de votre appareil de chauffage si des conditions de surpuissance sont détectées.
Vous aurez besoin d'un **capteur de la puissance totale instantanée consommée** de votre logement ainsi que d'un **capteur donnant la puissance maximale autorisée**.
Le comportement de cette fonction est basique :
1. lorsque le _VTherm_ va allumer un équipement,
2. il compare la dernière valeur connue du capteur de puissance consommée avec la dernière valeur de la puissance maximale autorisée. Si il reste une marge supérieure égale à la puissance déclarée des équipements du _VTherm_ alors le VTherm et ses équipements seront allumés. Sinon ils resteront éteints jusqu'au prochain cycle.
ATTENTION: ce fonctionnement très basique **n'est pas une fonction de sécurité** mais plus une fonction permettant une optimisation de la consommation au prix d'une dégradation du chauffage. Des dépassements sont possibles selon la fréquence de remontée de vos capteurs de consommation, la puissance réellement utilisée par votre équipements. Vous devez donc toujours garder une marge de sécurité.
Cas d'usage type:
1. vous avez un compteur électrique limité à 11 kW,
2. vous chargez de temps en temps un véhicle électrique à 5 kW,
3. il reste donc 6 kW pour tout le reste y compris le chauffage,
4. vous avez 1 kW d'autres équipements en cours,
5. vous avez déclaré un capteur (`input_number`) de puissance max autorisée à 9 kW (= 11 kW - la réserve pour les autres équipements - marge)
Si la vehicle est en charge, la puissance totale consommé est de 6 kW (5+1) et un _VTherm_ ne s'allumera que si sa puissance déclarée est de 3 kW max (9 kW - 6 kW).
Si la vehicle est en charge et qu'un autre _VTherm_ de 2 kW est allumé, la puissance totale consommé est de 8 kW (5+1+2) et un _VTherm_ ne s'allumera que si sa puissance déclarée est de 1 kW max (9 kW - 8 kW). Sinon il passe son tour (cycle).
Si le vehicle n'est pas en charge, la puissance totale consommé est de 1 kW, un _VTherm_ ne s'allumera que si sa puissance déclarée est de 8 kW max (9 kW - 1 kW).
## Configurer la gestion de la puissance
Si vous avez choisi la fonctionnalité `Avec détection de la puissance`, vous la configurez de la façon suivante :
![image](images/config-power.png)
1. l'id d'entité du **capteur de puissance instantané consommé** de votre logement,
2. l'id d'entité du **capteur de puissance maximale autorisée**,
3. la température à appliquer si le délestage est appliqué.
Notez que toutes les valeurs de puissance doivent avoir les mêmes unités (kW ou W par exemple).
Le fait d'avoir un **capteur de puissance maximale autorisée**, vous permet de modifier la puissance maximale au fil du temps à l'aide d'un planificateur ou d'une automatisation.
> ![Astuce](images/tips.png) _*Notes*_
>
> 1. En cas de délestage, le radiateur est réglé sur le préréglage nommé `power`. Il s'agit d'un préréglage caché, vous ne pouvez pas le sélectionner manuellement.
> 2. Gardez toujours une marge, car la puissance max peut être brièvement dépassée en attendant le calcul du prochain cycle typiquement ou par des équipements non régulés.
> 3. Si vous ne souhaitez pas utiliser cette fonctionnalité, décochez la dans le menu 'Fonctions'.
> 4. Si une _VTherm_ controlez plusieurs équipements, la **consommation électrique de votre chauffage** renseigné doit correspondre à la somme des puissances.
> 5. Si vous utilisez la carte Verstatile Thermostat UI (cf. [ici](additions.md#bien-mieux-avec-le-versatile-thermostat-ui-card)), le délestage est représenté comme suit : ![délestage](images/power-exceeded-icon.png).

View File

@@ -1,25 +0,0 @@
# Gestion de la présence / absence
- [Gestion de la présence / absence](#gestion-de-la-présence--absence)
- [Configurer la présence (ou l'absence)](#configurer-la-présence-ou-labsence)
## Configurer la présence (ou l'absence)
Si cette fonction est sélectionnée, elle vous permet de modifier dynamiquement la température des préréglages du thermostat lorsqu'une présence (ou absence) est détectée. Pour cela, vous devez configurer la température qui sera utilisée pour chaque préréglage lorsque la présence est désactivée. Lorsque le capteur de présence s'éteint, ces températures seront utilisées. Lorsqu'il se rallume, la température "normale" configurée pour le préréglage est utilisée. Voir [gestion des préréglages](feature-presets.md).
Pour configurer la présence remplissez ce formulaire :
![image](images/config-presence.png)
Pour cela, vous devez simplement configurer un **capteur d'occupation** dont l'état doit être 'on' ou 'home' si quelqu'un est présent ou 'off' ou 'not_home' sinon,
Les températures sont configurées dans les entités de l'équipement correspondant à votre _VTherm_ (Paramètres/Intégration/Versatile Thermostat/le vtherm)
ATTENTION : les groupes de personnes ne fonctionnent pas en tant que capteur de présence. Ils ne sont pas reconnus comme un capteur de présence. Vous devez utiliser, un template comme décrit ici [Utilisation d'un groupe de personnes comme capteur de présence](troubleshooting.md#utilisation-dun-groupe-de-personnes-comme-capteur-de-présence).
> ![Astuce](images/tips.png) _*Notes*_
>
> 1. le changement de température est immédiat et se répercute sur le volet avant. Le calcul prendra en compte la nouvelle température cible au prochain calcul du cycle,
> 2. vous pouvez utiliser le capteur direct person.xxxx ou un groupe de capteurs de Home Assistant. Le capteur de présence gère les états ``on`` ou ``home`` comme présents et les états ``off`` ou ``not_home`` comme absents.
> 3. pour pré-chauffer votre logement alors que tout le monde est absent, vous pouvez ajouter une entité de type `input_boolean` dans votre groupe de personne. Si vous passez cet `input_boolean` sur 'On' alors le capteur de présence sera forcé sur 'On' et les presets avec présence seront utilisés. Vous pouvez aussi positionner cet `input_boolean` sur 'On' via une automatisation par exemple lorsque vous quittez une zone pour lancer le préchauffage de votre logement.

View File

@@ -1,31 +0,0 @@
# Les pre-réglages (preset)
- [Les pre-réglages (preset)](#les-pre-réglages-preset)
- [Configurer les températures préréglées](#configurer-les-températures-préréglées)
## Configurer les températures préréglées
Le mode préréglé (preset) vous permet de préconfigurer la température ciblée. Utilisé en conjonction avec Scheduler (voir [scheduler](additions#composant-scheduler-)) vous aurez un moyen puissant et simple d'optimiser la température par rapport à la consommation électrique de votre maison. Les préréglages gérés sont les suivants :
- **Eco** : l'appareil est en mode d'économie d'énergie
- **Confort** : l'appareil est en mode confort
- **Boost** : l'appareil tourne toutes les vannes à fond
Si le mode AC est utilisé, vous pourrez aussi configurer les températures lorsque l'équipement en mode climatisation.
**Aucun** est toujours ajouté dans la liste des modes, car c'est un moyen de ne pas utiliser les preset mais une **température manuelle** à la place.
Les pré-réglages se font directement depuis les entités du _VTherm_ ou de la configuration centrale si vous utilisez la configuration centrale. A la création du _VTherm_, vous aurez différentes entités qui vont vous permettre de fixer les températures de chaque preset :
![presets](images/config-preset-temp.png).
La liste des entités varient en fonction de vos choix de fonction :
1. si la fonction 'détection de présence' est activée vous aurez les presets en version absence préfixé par _abs_,
2. si vous avez choisi l'option _AC_, vous aurez en plus les presets en version 'climatisation' préfixé par _clim_
> ![Astuce](images/tips.png) _*Notes*_
>
> 1. Lorsque vous modifiez manuellement la température cible, le préréglage passe sur Aucun (pas de préréglage),
> 2. Le préréglage standard ``Away`` est un préréglage caché qui n'est pas directement sélectionnable. Versatile Thermostat utilise la gestion de présence ou la gestion de mouvement pour régler automatiquement et dynamiquement la température cible en fonction d'une présence dans le logement ou d'une activité dans la pièce. Voir [gestion de la présence](feature-presence.md).
> 3. Si vous utilisez la gestion du délestage, vous verrez un préréglage caché nommé ``power``. Le préréglage de l'élément chauffant est réglé sur « puissance » lorsque des conditions de surpuissance sont rencontrées et que le délestage est actif pour cet élément chauffant. Voir [gestion de l'alimentation](feature-power.md).
> 4. si vous utilisez la configuration avancée, vous verrez le préréglage défini sur ``sécurité`` si la température n'a pas pu être récupérée après un certain délai. Voir [Mise en sécurité](feature-advanced.md#la-mise-en-sécurité)

Some files were not shown because too many files have changed in this diff Show More