Auto start/stop alog and testu + ConfigFlow

This commit is contained in:
Jean-Marc Collin
2024-10-27 10:04:14 +00:00
parent 17ebf629e6
commit db3afdf887
8 changed files with 837 additions and 11 deletions

View File

@@ -0,0 +1,153 @@
# pylint: disable=line-too-long
""" This file implements the Auto start/stop algorithm as described here: https://github.com/jmcollin78/versatile_thermostat/issues/585
"""
import logging
from homeassistant.components.climate import HVACMode
from .const import (
AUTO_START_STOP_LEVEL_NONE,
AUTO_START_STOP_LEVEL_FAST,
AUTO_START_STOP_LEVEL_MEDIUM,
AUTO_START_STOP_LEVEL_SLOW,
CONF_AUTO_START_STOP_LEVELS,
)
_LOGGER = logging.getLogger(__name__)
# attribute name should be equal to AUTO_START_STOP_LEVEL_xxx constants (in const.yaml)
DTEMP = {
AUTO_START_STOP_LEVEL_NONE: 99,
AUTO_START_STOP_LEVEL_SLOW: 3,
AUTO_START_STOP_LEVEL_MEDIUM: 2,
AUTO_START_STOP_LEVEL_FAST: 1,
}
DT_MIN = {
AUTO_START_STOP_LEVEL_NONE: 99,
AUTO_START_STOP_LEVEL_SLOW: 30,
AUTO_START_STOP_LEVEL_MEDIUM: 15,
AUTO_START_STOP_LEVEL_FAST: 7,
}
AUTO_START_STOP_ACTION_OFF = "turnOff"
AUTO_START_STOP_ACTION_ON = "turnOn"
AUTO_START_STOP_ACTION_NOTHING = "nothing"
AUTO_START_STOP_ACTIONS = [
AUTO_START_STOP_ACTION_OFF,
AUTO_START_STOP_ACTION_ON,
AUTO_START_STOP_ACTION_NOTHING,
]
class AutoStartStopDetectionAlgorithm:
"""The class that implements the algorithm listed above"""
_dt: float
_dtemp: float
_level: str
def __init__(self, level: CONF_AUTO_START_STOP_LEVELS, vtherm_name) -> None:
"""Initalize a new algorithm with the right constants"""
self._level = level
self._dt = DT_MIN[level]
self._dtemp = DTEMP[level]
self._vtherm_name = vtherm_name
def calculate_action(
self,
hvac_mode: HVACMode | None,
saved_hvac_mode: HVACMode | None,
regulated_temp: float,
target_temp: float,
current_temp: float,
slope_min: float,
) -> AUTO_START_STOP_ACTIONS:
"""Calculate an eventual action to do depending of the value in parameter"""
if self._level == AUTO_START_STOP_LEVEL_NONE:
_LOGGER.debug(
"%s - auto-start/stop is disabled",
self,
)
return AUTO_START_STOP_ACTION_NOTHING
if (
hvac_mode is None
or regulated_temp is None
or target_temp is None
or current_temp is None
or slope_min is None
):
_LOGGER.debug(
"%s - No all mandatory parameters are set. Disable auto-start/stop",
self,
)
return AUTO_START_STOP_ACTION_NOTHING
_LOGGER.debug(
"%s - calculate_action: hvac_mode=%s, saved_hvac_mode=%s, regulated_temp=%s, target_temp=%s, current_temp=%s, slope_min=%s",
self,
hvac_mode,
saved_hvac_mode,
regulated_temp,
target_temp,
current_temp,
slope_min,
)
if hvac_mode == HVACMode.HEAT:
if regulated_temp + self._dtemp <= target_temp and slope_min >= 0:
_LOGGER.info(
"%s - We need to stop, there is no need for heating for a long time.",
)
return AUTO_START_STOP_ACTION_OFF
else:
_LOGGER.debug(
"%s - nothing to do, we are heating",
)
return AUTO_START_STOP_ACTION_NOTHING
if hvac_mode == HVACMode.COOL:
if regulated_temp - self._dtemp >= target_temp and slope_min <= 0:
_LOGGER.info(
"%s - We need to stop, there is no need for cooling for a long time.",
)
return AUTO_START_STOP_ACTION_OFF
else:
_LOGGER.debug(
"%s - nothing to do, we are cooling",
)
return AUTO_START_STOP_ACTION_NOTHING
if hvac_mode == HVACMode.OFF and saved_hvac_mode == HVACMode.HEAT:
if current_temp + slope_min * self._dt <= target_temp:
_LOGGER.info(
"%s - We need to start, because it will be time to heat",
)
return AUTO_START_STOP_ACTION_ON
else:
_LOGGER.debug(
"%s - nothing to do, we don't need to heat soon",
)
return AUTO_START_STOP_ACTION_NOTHING
if hvac_mode == HVACMode.OFF and saved_hvac_mode == HVACMode.COOL:
if current_temp + slope_min * self._dt >= target_temp:
_LOGGER.info(
"%s - We need to start, because it will be time to cool",
)
return AUTO_START_STOP_ACTION_ON
else:
_LOGGER.debug(
"%s - nothing to do, we don't need to cool soon",
)
return AUTO_START_STOP_ACTION_NOTHING
_LOGGER.debug(
"%s - nothing to do, no conditions applied",
)
return AUTO_START_STOP_ACTION_NOTHING
def __str__(self) -> str:
return f"AutoStartStopDetectionAlgorithm-{self._vtherm_name}"

View File

@@ -413,6 +413,11 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
]:
menu_options.append("presets")
if self._infos[CONF_THERMOSTAT_TYPE] in [
CONF_THERMOSTAT_CLIMATE,
]:
menu_options.append("auto_start_stop")
if (
is_central_config
and self._infos.get(CONF_USE_CENTRAL_BOILER_FEATURE) is True
@@ -520,17 +525,29 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
"""Handle the Type flow steps"""
_LOGGER.debug("Into ConfigFlow.async_step_features user_input=%s", user_input)
schema = STEP_FEATURES_DATA_SCHEMA
if self._infos[CONF_THERMOSTAT_TYPE] == CONF_THERMOSTAT_CENTRAL_CONFIG:
schema = STEP_CENTRAL_FEATURES_DATA_SCHEMA
elif self._infos[CONF_THERMOSTAT_TYPE] == CONF_THERMOSTAT_CLIMATE:
schema = STEP_CLIMATE_FEATURES_DATA_SCHEMA
return await self.generic_step(
"features",
(
STEP_CENTRAL_FEATURES_DATA_SCHEMA
if self._infos[CONF_THERMOSTAT_TYPE] == CONF_THERMOSTAT_CENTRAL_CONFIG
else STEP_FEATURES_DATA_SCHEMA
),
schema,
user_input,
self.async_step_menu,
)
async def async_step_auto_start_stop(self, user_input: dict | None = None) -> FlowResult:
""" Handle the Auto start stop step"""
_LOGGER.debug("Into ConfigFlow.async_step_auto_start_stop user_input=%s", user_input)
schema = STEP_AUTO_START_STOP
self._infos[COMES_FROM] = None
next_step = self.async_step_menu
return await self.generic_step("auto_start_stop", schema, user_input, next_step)
async def async_step_tpi(self, user_input: dict | None = None) -> FlowResult:
"""Handle the TPI flow steps"""
_LOGGER.debug("Into ConfigFlow.async_step_tpi user_input=%s", user_input)

View File

@@ -68,6 +68,16 @@ STEP_FEATURES_DATA_SCHEMA = vol.Schema( # pylint: disable=invalid-name
}
)
STEP_CLIMATE_FEATURES_DATA_SCHEMA = vol.Schema( # pylint: disable=invalid-name
{
vol.Optional(CONF_USE_WINDOW_FEATURE, default=False): cv.boolean,
vol.Optional(CONF_USE_MOTION_FEATURE, default=False): cv.boolean,
vol.Optional(CONF_USE_POWER_FEATURE, default=False): cv.boolean,
vol.Optional(CONF_USE_PRESENCE_FEATURE, default=False): cv.boolean,
vol.Optional(CONF_USE_AUTO_START_STOP_FEATURE, default=False): cv.boolean,
}
)
STEP_CENTRAL_FEATURES_DATA_SCHEMA = vol.Schema( # pylint: disable=invalid-name
{
vol.Optional(CONF_USE_WINDOW_FEATURE, default=False): cv.boolean,
@@ -196,6 +206,20 @@ STEP_THERMOSTAT_VALVE = vol.Schema( # pylint: disable=invalid-name
}
)
STEP_AUTO_START_STOP = vol.Schema( # pylint: disable=invalid-name
{
vol.Optional(
CONF_AUTO_START_STOP_LEVEL, default=AUTO_START_STOP_LEVEL_NONE
): selector.SelectSelector(
selector.SelectSelectorConfig(
options=CONF_AUTO_START_STOP_LEVELS,
translation_key="auto_start_stop",
mode="dropdown",
)
),
}
)
STEP_TPI_DATA_SCHEMA = vol.Schema( # pylint: disable=invalid-name
{
vol.Required(CONF_USE_TPI_CENTRAL_CONFIG, default=True): cv.boolean,

View File

@@ -97,6 +97,7 @@ CONF_USE_MOTION_FEATURE = "use_motion_feature"
CONF_USE_PRESENCE_FEATURE = "use_presence_feature"
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_WINDOW_AUTO_OPEN_THRESHOLD = "window_auto_open_threshold"
CONF_WINDOW_AUTO_CLOSE_THRESHOLD = "window_auto_close_threshold"
@@ -145,6 +146,18 @@ CONF_CENTRAL_BOILER_DEACTIVATION_SRV = "central_boiler_deactivation_service"
CONF_USED_BY_CENTRAL_BOILER = "used_by_controls_central_boiler"
CONF_WINDOW_ACTION = "window_action"
CONF_AUTO_START_STOP_LEVEL = "auto_start_stop_level"
AUTO_START_STOP_LEVEL_NONE = "none"
AUTO_START_STOP_LEVEL_SLOW = "slow"
AUTO_START_STOP_LEVEL_MEDIUM = "medium"
AUTO_START_STOP_LEVEL_FAST = "fast"
CONF_AUTO_START_STOP_LEVELS = [
AUTO_START_STOP_LEVEL_NONE,
AUTO_START_STOP_LEVEL_SLOW,
AUTO_START_STOP_LEVEL_MEDIUM,
AUTO_START_STOP_LEVEL_FAST,
]
DEFAULT_SHORT_EMA_PARAMS = {
"max_alpha": 0.5,
# In sec

View File

@@ -27,6 +27,7 @@
"power": "Power management",
"presence": "Presence detection",
"advanced": "Advanced parameters",
"auto_start_stop": "Auto start and stop",
"finalize": "All done",
"configuration_not_complete": "Configuration not complete"
}
@@ -63,7 +64,8 @@
"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 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_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"
}
},
"type": {
@@ -262,6 +264,7 @@
"power": "Power management",
"presence": "Presence detection",
"advanced": "Advanced parameters",
"auto_start_stop": "Auto start and stop",
"finalize": "All done",
"configuration_not_complete": "Configuration not complete"
}
@@ -298,7 +301,8 @@
"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 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_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"
}
},
"type": {
@@ -514,6 +518,14 @@
"comfort": "Comfort",
"boost": "Boost"
}
},
"auto_start_stop": {
"options": {
"none": "No auto start/stop",
"slow": "Slow detection",
"medium": "Medium detection",
"fast": "Fast detection"
}
}
},
"entity": {

View File

@@ -27,6 +27,7 @@
"power": "Power management",
"presence": "Presence detection",
"advanced": "Advanced parameters",
"auto_start_stop": "Auto start and stop",
"finalize": "All done",
"configuration_not_complete": "Configuration not complete"
}
@@ -63,7 +64,8 @@
"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 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_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"
}
},
"type": {
@@ -262,6 +264,7 @@
"power": "Power management",
"presence": "Presence detection",
"advanced": "Advanced parameters",
"auto_start_stop": "Auto start and stop",
"finalize": "All done",
"configuration_not_complete": "Configuration not complete"
}
@@ -298,7 +301,8 @@
"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 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_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"
}
},
"type": {
@@ -514,6 +518,14 @@
"comfort": "Comfort",
"boost": "Boost"
}
},
"auto_start_stop": {
"options": {
"none": "No auto start/stop",
"slow": "Slow detection",
"medium": "Medium detection",
"fast": "Fast detection"
}
}
},
"entity": {

View File

@@ -27,6 +27,7 @@
"power": "Gestion de la puissance",
"presence": "Détection de présence",
"advanced": "Paramètres avancés",
"auto_start_stop": "Allumage/extinction automatique",
"finalize": "Finaliser la création",
"configuration_not_complete": "Configuration incomplète"
}
@@ -63,7 +64,8 @@
"use_motion_feature": "Avec détection de mouvement",
"use_power_feature": "Avec gestion de la puissance",
"use_presence_feature": "Avec détection de présence",
"use_central_boiler_feature": "Ajouter une chaudière centrale. Cochez pour ajouter un controle sur une chaudière centrale. Vous devrez ensuite configurer les VTherms qui commande la chaudière centrale pour que cette option prenne effet. Si au moins un des VTherm a besoin de chauffer, la chaudière centrale sera activée. Si aucun VTherm n'a besoin de chauffer, elle sera éteinte. Les commandes pour allumer/éteindre la chaudière centrale sont données dans la page de configuration suivante."
"use_central_boiler_feature": "Ajouter une chaudière centrale. Cochez pour ajouter un controle sur une chaudière centrale. Vous devrez ensuite configurer les VTherms qui commande la chaudière centrale pour que cette option prenne effet. Si au moins un des VTherm a besoin de chauffer, la chaudière centrale sera activée. Si aucun VTherm n'a besoin de chauffer, elle sera éteinte. Les commandes pour allumer/éteindre la chaudière centrale sont données dans la page de configuration suivante.",
"use_auto_start_stop_feature": "Avec démarrage et extinction automatique"
}
},
"type": {
@@ -274,6 +276,7 @@
"power": "Gestion de la puissance",
"presence": "Détection de présence",
"advanced": "Paramètres avancés",
"auto_start_stop": "Allumage/extinction automatique",
"finalize": "Finaliser les modifications",
"configuration_not_complete": "Configuration incomplète"
}
@@ -310,7 +313,8 @@
"use_motion_feature": "Avec détection de mouvement",
"use_power_feature": "Avec gestion de la puissance",
"use_presence_feature": "Avec détection de présence",
"use_central_boiler_feature": "Ajouter une chaudière centrale. Cochez pour ajouter un controle sur une chaudière centrale. Vous devrez ensuite configurer les VTherms qui commande la chaudière centrale pour que cette option prenne effet. Si au moins un des VTherm a besoin de chauffer, la chaudière centrale sera activée. Si aucun VTherm n'a besoin de chauffer, elle sera éteinte. Les commandes pour allumer/éteindre la chaudière centrale sont données dans la page de configuration suivante."
"use_central_boiler_feature": "Ajouter une chaudière centrale. Cochez pour ajouter un controle sur une chaudière centrale. Vous devrez ensuite configurer les VTherms qui commande la chaudière centrale pour que cette option prenne effet. Si au moins un des VTherm a besoin de chauffer, la chaudière centrale sera activée. Si aucun VTherm n'a besoin de chauffer, elle sera éteinte. Les commandes pour allumer/éteindre la chaudière centrale sont données dans la page de configuration suivante.",
"use_auto_start_stop_feature": "Avec démarrage et extinction automatique"
}
},
"type": {
@@ -532,6 +536,14 @@
"comfort": "Confort",
"boost": "Renforcé (boost)"
}
},
"auto_start_stop": {
"options": {
"none": "No auto start/stop",
"slow": "Slow detection",
"medium": "Medium detection",
"fast": "Fast detection"
}
}
},
"entity": {