Missing translations for preset mode Power and Security #46

Set preset internal #45
Notify (send event messages) when something important happens #43
Enhancing Security mode #42
Rename None preset to Manual #3
This commit is contained in:
Jean-Marc Collin
2023-02-11 10:34:45 +01:00
parent 7b57f7da28
commit ade1ee4365
7 changed files with 250 additions and 105 deletions

View File

@@ -20,7 +20,6 @@ from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.util.unit_system import UnitOfTemperature
from homeassistant.helpers.event import (
async_track_state_change_event,
@@ -118,6 +117,9 @@ from .const import (
PRESET_AWAY_SUFFIX,
CONF_SECURITY_DELAY_MIN,
CONF_SECURITY_MIN_ON_PERCENT,
CONF_SECURITY_DEFAULT_ON_PERCENT,
DEFAULT_SECURITY_MIN_ON_PERCENT,
DEFAULT_SECURITY_DEFAULT_ON_PERCENT,
CONF_MINIMAL_ACTIVATION_DELAY,
CONF_TEMP_MAX,
CONF_TEMP_MIN,
@@ -127,6 +129,7 @@ from .const import (
CONF_THERMOSTAT_CLIMATE,
CONF_CLIMATE,
UnknownEntity,
EventType,
)
from .prop_algorithm import PropAlgorithm
@@ -183,7 +186,7 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
# No more needed
# _registry: dict[str, object] = {}
def __init__(self, hass, unique_id, name, entry_infos) -> None:
def __init__(self, hass: HomeAssistant, unique_id, name, entry_infos) -> None:
"""Initialize the thermostat."""
super().__init__()
@@ -218,9 +221,10 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
self._presence_state = None
self._overpowering_state = None
self._should_relaunch_control_heating = None
self._security_delay_min = None
self._security_min_on_percent= None
self._security_delay_min = None
self._security_min_on_percent = None
self._security_default_on_percent = None
self._security_state = None
self._thermostat_type = None
@@ -243,7 +247,7 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
)
# convert entry_infos into usable attributes
presets = {}
for (key, value) in CONF_PRESETS.items():
for key, value in CONF_PRESETS.items():
_LOGGER.debug("looking for key=%s, value=%s", key, value)
if value in entry_infos:
presets[key] = entry_infos.get(value)
@@ -251,7 +255,7 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
_LOGGER.debug("value %s not found in Entry", value)
presets_away = {}
for (key, value) in CONF_PRESETS_AWAY.items():
for key, value in CONF_PRESETS_AWAY.items():
_LOGGER.debug("looking for key=%s, value=%s", key, value)
if value in entry_infos:
presets_away[key] = entry_infos.get(value)
@@ -367,7 +371,14 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
self._tpi_coef_ext = 0
self._security_delay_min = entry_infos.get(CONF_SECURITY_DELAY_MIN)
self._security_min_on_percent = entry_infos.get(CONF_SECURITY_MIN_ON_PERCENT)
self._security_min_on_percent = (
entry_infos.get(CONF_SECURITY_MIN_ON_PERCENT)
or DEFAULT_SECURITY_MIN_ON_PERCENT
)
self._security_default_on_percent = (
entry_infos.get(CONF_SECURITY_DEFAULT_ON_PERCENT)
or DEFAULT_SECURITY_DEFAULT_ON_PERCENT
)
self._minimal_activation_delay = entry_infos.get(CONF_MINIMAL_ACTIVATION_DELAY)
self._last_temperature_mesure = datetime.now()
self._last_ext_temperature_mesure = datetime.now()
@@ -732,7 +743,12 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
float(old_state.attributes[ATTR_TEMPERATURE])
)
if old_state.attributes.get(ATTR_PRESET_MODE) in self._attr_preset_modes:
old_preset_mode = old_state.attributes.get(ATTR_PRESET_MODE)
# Never restore a Power or Security preset
if (
old_preset_mode in self._attr_preset_modes
and old_preset_mode not in HIDDEN_PRESETS
):
self._attr_preset_mode = old_state.attributes.get(ATTR_PRESET_MODE)
self.save_preset_mode()
@@ -756,6 +772,9 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
if not self._hvac_mode:
self._hvac_mode = HVACMode.OFF
self.send_event(EventType.PRESET_EVENT, {"preset": self._attr_preset_mode})
self.send_event(EventType.HVAC_MODE_EVENT, {"hvac_mode": self._hvac_mode})
_LOGGER.info(
"%s - restored state is target_temp=%.1f, preset_mode=%s, hvac_mode=%s",
self,
@@ -1011,12 +1030,11 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
_LOGGER.error("Unrecognized hvac mode: %s", hvac_mode)
return
# Ensure we update the current operation after changing the mode
self._last_temperature_mesure = (
self._last_ext_temperature_mesure
) = datetime.now()
self.reset_last_temperature_time()
self.update_custom_attributes()
self.async_write_ha_state()
self.send_event(EventType.HVAC_MODE_EVENT, {"hvac_mode": self._hvac_mode})
async def async_set_preset_mode(self, preset_mode):
"""Set new preset mode."""
@@ -1052,11 +1070,18 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
self.find_preset_temp(preset_mode)
)
self._last_temperature_mesure = (
self._last_ext_temperature_mesure
) = datetime.now()
self.reset_last_temperature_time()
self.save_preset_mode()
self.recalculate()
self.send_event(EventType.PRESET_EVENT, {"preset": self._attr_preset_mode})
def reset_last_temperature_time(self):
"""Reset to now the last temperature time if conditions are satisfied"""
if self._attr_preset_mode not in HIDDEN_PRESETS:
self._last_temperature_mesure = (
self._last_ext_temperature_mesure
) = datetime.now()
def find_preset_temp(self, preset_mode):
"""Find the right temperature of a preset considering the presence if configured"""
@@ -1623,6 +1648,15 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
self.save_preset_mode()
await self._async_underlying_entity_turn_off()
await self._async_set_preset_mode_internal(PRESET_POWER)
self.send_event(
EventType.POWER_EVENT,
{
"type": "start",
"current_power": self._current_power,
"device_power": self._device_power,
"current_power_max": self._current_power_max,
},
)
# Check if we need to remove the POWER preset
if (
@@ -1638,6 +1672,15 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
if self._is_over_climate:
await self.restore_hvac_mode()
await self.restore_preset_mode()
self.send_event(
EventType.POWER_EVENT,
{
"type": "end",
"current_power": self._current_power,
"device_power": self._device_power,
"current_power_max": self._current_power_max,
},
)
self._overpowering_state = ret
return self._overpowering_state
@@ -1649,12 +1692,6 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
delta_ext_temp = (
now - self._last_ext_temperature_mesure
).total_seconds() / 60.0
_LOGGER.debug(
"%s - checking security delta_temp=%.1f delta_ext_temp=%.1f",
self,
delta_temp,
delta_ext_temp,
)
temp_cond: bool = (
delta_temp > self._security_delay_min
@@ -1667,7 +1704,8 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
switch_cond: bool = (
not self._is_over_climate
and self._prop_algorithm is not None
and self._prop_algorithm.on_percent > self._security_min_on_percent
and self._prop_algorithm.calculated_on_percent
> self._security_min_on_percent
)
ret = False
@@ -1683,6 +1721,16 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
)
ret = True
_LOGGER.debug(
"%s - checking security delta_temp=%.1f delta_ext_temp=%.1f temp_cond=%s climate_cond=%s switch_cond=%s",
self,
delta_temp,
delta_ext_temp,
temp_cond,
climate_cond,
switch_cond,
)
if temp_cond and switch_cond:
if not self._security_state:
_LOGGER.warning(
@@ -1696,12 +1744,40 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
)
ret = True
if not self._security_state and temp_cond:
self.send_event(
EventType.TEMPERATURE_EVENT,
{
"last_temperature_mesure": self._last_temperature_mesure.isoformat(),
"last_ext_temperature_mesure": self._last_ext_temperature_mesure.isoformat(),
"current_temp": self._cur_temp,
"current_ext_temp": self._cur_ext_temp,
"target_temp": self.target_temperature,
},
)
if not self._security_state and ret:
self._security_state = ret
self.save_hvac_mode()
self.save_preset_mode()
await self._async_set_preset_mode_internal(PRESET_SECURITY)
await self.async_set_hvac_mode(HVACMode.OFF)
# Turn off the underlying climate or heater if security default on_percent is 0
if self._is_over_climate or self._security_default_on_percent <= 0.0:
await self.async_set_hvac_mode(HVACMode.OFF)
if self._prop_algorithm:
self._prop_algorithm.set_security(self._security_default_on_percent)
self.send_event(
EventType.SECURITY_EVENT,
{
"type": "start",
"last_temperature_mesure": self._last_temperature_mesure.isoformat(),
"last_ext_temperature_mesure": self._last_ext_temperature_mesure.isoformat(),
"current_temp": self._cur_temp,
"current_ext_temp": self._cur_ext_temp,
"target_temp": self.target_temperature,
},
)
if (
self._security_state
@@ -1715,15 +1791,30 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
self._saved_preset_mode,
)
self._security_state = ret
await self.restore_hvac_mode()
# Restore hvac_mode if previously saved
if self._is_over_climate or self._security_default_on_percent <= 0.0:
await self.restore_hvac_mode()
await self.restore_preset_mode()
if self._prop_algorithm:
self._prop_algorithm.unset_security()
self.send_event(
EventType.SECURITY_EVENT,
{
"type": "end",
"last_temperature_mesure": self._last_temperature_mesure.isoformat(),
"last_ext_temperature_mesure": self._last_ext_temperature_mesure.isoformat(),
"current_temp": self._cur_temp,
"current_ext_temp": self._cur_ext_temp,
"target_temp": self.target_temperature,
},
)
return ret
async def _async_control_heating(self, force=False, _=None):
"""The main function used to run the calculation at each cycle"""
_LOGGER.info(
_LOGGER.debug(
"%s - Checking new cycle. hvac_mode=%s, security_state=%s, preset_mode=%s",
self,
self._hvac_mode,
@@ -1738,8 +1829,8 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
return
security: bool = await self.check_security()
if security:
_LOGGER.debug("%s - End of cycle (security)", self)
if security and self._is_over_climate:
_LOGGER.debug("%s - End of cycle (security and over climate)", self)
return
# Stop here if we are off
@@ -1752,7 +1843,8 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
if not self._is_over_climate:
on_time_sec: int = self._prop_algorithm.on_time_sec
off_time_sec: int = self._prop_algorithm.off_time_sec
_LOGGER.info(
_LOGGER.debug(
"%s - Checking new cycle. on_time_sec=%.0f, off_time_sec=%.0f, security_state=%s, preset_mode=%s",
self,
on_time_sec,
@@ -1793,13 +1885,12 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
return
if on:
security = (
await self.check_security()
or await self.check_overpowering()
)
if security:
if await self.check_overpowering():
_LOGGER.debug("%s - End of cycle (3)", self)
return
# Security mode could have change the on_time percent
await self.check_security()
time = self._prop_algorithm.on_time_sec
action_label = "start" if on else "stop"
if self._should_relaunch_control_heating:
@@ -1814,7 +1905,7 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
if time > 0:
_LOGGER.info(
"%s - !!! %s heating for %d min %d sec",
"%s - %s heating for %d min %d sec",
self,
action_label,
time // 60,
@@ -1910,6 +2001,7 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
"presence_state": self._presence_state,
"security_delay_min": self._security_delay_min,
"security_min_on_percent": self._security_min_on_percent,
"security_default_on_percent": self._security_default_on_percent,
"last_temperature_datetime": self._last_temperature_mesure.isoformat(),
"last_ext_temperature_datetime": self._last_ext_temperature_mesure.isoformat(),
"security_state": self._security_state,
@@ -1999,3 +2091,11 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
if self._attr_preset_mode == preset:
await self._async_set_preset_mode_internal(preset, force=True)
await self._async_control_heating(force=True)
def send_event(self, event_type: EventType, data: dict):
"""Send an event"""
_LOGGER.info("%s - Sending event %s with data: %s", self, event_type, data)
data["entity_id"] = self.entity_id
data["name"] = self.name
data["state_attributes"] = self.state_attributes
self._hass.bus.fire(event_type.value, data)

View File

@@ -64,6 +64,9 @@ from .const import (
PROPORTIONAL_FUNCTION_TPI,
CONF_SECURITY_DELAY_MIN,
CONF_SECURITY_MIN_ON_PERCENT,
CONF_SECURITY_DEFAULT_ON_PERCENT,
DEFAULT_SECURITY_MIN_ON_PERCENT,
DEFAULT_SECURITY_DEFAULT_ON_PERCENT,
CONF_MINIMAL_ACTIVATION_DELAY,
CONF_TEMP_MAX,
CONF_TEMP_MIN,
@@ -177,53 +180,16 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
is_empty or self._infos.get(CONF_PRESENCE_SENSOR) is not None
)
# self.hass = async_get_hass()
# ent_reg = async_get(hass=self.hass)
# climates = []
# switches = []
# temp_sensors = []
# power_sensors = []
# window_sensors = []
# presence_sensors = []
#
# k: str
# for k in ent_reg.entities:
# v: RegistryEntry = ent_reg.entities[k]
# _LOGGER.debug("Looking entity: %s", k)
# # if k.startswith(CLIMATE_DOMAIN) and (
# # infos is None or k != infos.get("entity_id")
# # ):
# # _LOGGER.debug("Climate !")
# # climates.append(k)
# if k.startswith(SWITCH_DOMAIN) or k.startswith(INPUT_BOOLEAN_DOMAIN):
# _LOGGER.debug("Switch !")
# switches.append(k)
# elif is_temperature_sensor(v):
# _LOGGER.debug("Temperature sensor !")
# temp_sensors.append(k)
# elif is_power_sensor(v):
# _LOGGER.debug("Power sensor !")
# power_sensors.append(k)
# elif k.startswith(PERSON_DOMAIN):
# _LOGGER.debug("Presence sensor !")
# presence_sensors.append(k)
#
# # window sensor and presence
# if k.startswith(INPUT_BOOLEAN_DOMAIN) or k.startswith(BINARY_SENSOR_DOMAIN):
# _LOGGER.debug("Window or presence sensor !")
# window_sensors.append(k)
# presence_sensors.append(k)
#
# # Special case for climates which are not in EntityRegistry
# climates = self.find_all_climates()
self.STEP_USER_DATA_SCHEMA = vol.Schema(
{
vol.Required(CONF_NAME): cv.string,
vol.Required(
CONF_THERMOSTAT_TYPE, default=CONF_THERMOSTAT_SWITCH
): vol.In(CONF_THERMOSTAT_TYPES),
): selector.SelectSelector(
selector.SelectSelectorConfig(
options=CONF_THERMOSTAT_TYPES, translation_key="thermostat_type"
)
),
vol.Required(CONF_TEMP_SENSOR): selector.EntitySelector(
selector.EntitySelectorConfig(
domain=[SENSOR_DOMAIN, INPUT_NUMBER_DOMAIN]
@@ -350,9 +316,18 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
self.STEP_ADVANCED_DATA_SCHEMA = vol.Schema(
{
vol.Required(CONF_MINIMAL_ACTIVATION_DELAY, default=10): cv.positive_int,
vol.Required(
CONF_MINIMAL_ACTIVATION_DELAY, default=10
): cv.positive_int,
vol.Required(CONF_SECURITY_DELAY_MIN, default=60): cv.positive_int,
vol.Required(CONF_SECURITY_MIN_ON_PERCENT, default=0.75): vol.Coerce(float),
vol.Required(
CONF_SECURITY_MIN_ON_PERCENT,
default=DEFAULT_SECURITY_MIN_ON_PERCENT,
): vol.Coerce(float),
vol.Required(
CONF_SECURITY_DEFAULT_ON_PERCENT,
default=DEFAULT_SECURITY_DEFAULT_ON_PERCENT,
): vol.Coerce(float),
}
)

View File

@@ -1,5 +1,6 @@
"""Constants for the Versatile Thermostat integration."""
from enum import Enum
from homeassistant.const import CONF_NAME
from homeassistant.components.climate.const import (
# PRESET_ACTIVITY,
@@ -45,6 +46,7 @@ CONF_TEMP_MIN = "temp_min"
CONF_TEMP_MAX = "temp_max"
CONF_SECURITY_DELAY_MIN = "security_delay_min"
CONF_SECURITY_MIN_ON_PERCENT = "security_min_on_percent"
CONF_SECURITY_DEFAULT_ON_PERCENT = "security_default_on_percent"
CONF_THERMOSTAT_TYPE = "thermostat_type"
CONF_THERMOSTAT_SWITCH = "thermostat_over_switch"
CONF_THERMOSTAT_CLIMATE = "thermostat_over_climate"
@@ -104,6 +106,7 @@ ALL_CONF = (
CONF_TEMP_MAX,
CONF_SECURITY_DELAY_MIN,
CONF_SECURITY_MIN_ON_PERCENT,
CONF_SECURITY_DEFAULT_ON_PERCENT,
CONF_THERMOSTAT_TYPE,
CONF_THERMOSTAT_SWITCH,
CONF_THERMOSTAT_CLIMATE,
@@ -128,6 +131,17 @@ SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE
SERVICE_SET_PRESENCE = "set_presence"
SERVICE_SET_PRESET_TEMPERATURE = "set_preset_temperature"
DEFAULT_SECURITY_MIN_ON_PERCENT = 0.5
DEFAULT_SECURITY_DEFAULT_ON_PERCENT = 0.1
class EventType(Enum):
SECURITY_EVENT: str = "versatile_thermostat_security_event"
POWER_EVENT: str = "versatile_thermostat_power_event"
TEMPERATURE_EVENT: str = "versatile_thermostat_temperature_event"
HVAC_MODE_EVENT: str = "versatile_thermostat_hvac_mode_event"
PRESET_EVENT: str = "versatile_thermostat_preset_event"
class UnknownEntity(HomeAssistantError):
"""Error to indicate there is an unknown entity_id given."""

View File

@@ -37,8 +37,11 @@ class PropAlgorithm:
self._cycle_min = cycle_min
self._minimal_activation_delay = minimal_activation_delay
self._on_percent = 0
self._calculated_on_percent = 0
self._on_time_sec = 0
self._off_time_sec = self._cycle_min * 60
self._security = False
self._default_on_percent = 0
def calculate(
self, target_temp: float, current_temp: float, ext_current_temp: float
@@ -48,7 +51,7 @@ class PropAlgorithm:
_LOGGER.warning(
"Proportional algorithm: calculation is not possible cause target_temp or current_temp is null. Heating will be disabled" # pylint: disable=line-too-long
)
self._on_percent = 0
self._calculated_on_percent = 0
else:
delta_temp = target_temp - current_temp
delta_ext_temp = (
@@ -56,7 +59,7 @@ class PropAlgorithm:
)
if self._function == PROPORTIONAL_FUNCTION_TPI:
self._on_percent = (
self._calculated_on_percent = (
self._tpi_coef_int * delta_temp
+ self._tpi_coef_ext * delta_ext_temp
)
@@ -65,7 +68,35 @@ class PropAlgorithm:
"Proportional algorithm: unknown %s function. Heating will be disabled",
self._function,
)
self._on_percent = 0
self._calculated_on_percent = 0
self._calculate_internal()
_LOGGER.debug(
"heating percent calculated for current_temp %.1f, ext_current_temp %.1f and target_temp %.1f is %.2f, on_time is %d (sec), off_time is %d (sec)", # pylint: disable=line-too-long
current_temp if current_temp else -9999.0,
ext_current_temp if ext_current_temp else -9999.0,
target_temp if target_temp else -9999.0,
self._calculated_on_percent,
self.on_time_sec,
self.off_time_sec,
)
def _calculate_internal(self):
"""Finish the calculation to get the on_percent in seconds"""
if self._security:
_LOGGER.debug(
"Security is On using the default_on_percent %f",
self._default_on_percent,
)
self._on_percent = self._default_on_percent
else:
_LOGGER.debug(
"Security is Off using the calculated_on_percent %f",
self._calculated_on_percent,
)
self._on_percent = self._calculated_on_percent
# calculated on_time duration in seconds
if self._on_percent > 1:
@@ -92,21 +123,31 @@ class PropAlgorithm:
self._off_time_sec = self._cycle_min * 60 - self._on_time_sec
_LOGGER.debug(
"heating percent calculated for current_temp %.1f, ext_current_temp %.1f and target_temp %.1f is %.2f, on_time is %d (sec), off_time is %d (sec)", # pylint: disable=line-too-long
current_temp if current_temp else -9999.0,
ext_current_temp if ext_current_temp else -9999.0,
target_temp if target_temp else -9999.0,
self._on_percent,
self.on_time_sec,
self.off_time_sec,
)
def set_security(self, default_on_percent: float):
"""Set a default value for on_percent (used for security mode)"""
self._security = True
self._default_on_percent = default_on_percent
self._calculate_internal()
def unset_security(self):
"""Unset the security mode"""
self._security = False
self._calculate_internal()
@property
def on_percent(self) -> float:
"""Returns the percentage the heater must be ON (1 means the heater will be always on, 0 never on)""" # pylint: disable=line-too-long
"""Returns the percentage the heater must be ON
In security mode this value is overriden with the _default_on_percent
(1 means the heater will be always on, 0 never on)""" # pylint: disable=line-too-long
return round(self._on_percent, 2)
@property
def calculated_on_percent(self) -> float:
"""Returns the calculated percentage the heater must be ON
Calculated means NOT overriden even in security mode
(1 means the heater will be always on, 0 never on)""" # pylint: disable=line-too-long
return round(self._calculated_on_percent, 2)
@property
def on_time_sec(self) -> int:
"""Returns the calculated time in sec the heater must be ON"""

View File

@@ -90,7 +90,8 @@
"data": {
"minimal_activation_delay": "Delay in secondes under which the equipment will not be activated",
"security_delay_min": "Maximum allowed delay in minutes between two temperature mesures. Above this delay, the thermostat will turn to a sceurity off state",
"security_min_on_percent": "Minimal On-Percent value for security preset activation. Below this amount of on_percent the thermostat won't go into security preset"
"security_min_on_percent": "Minimal heating percent value for security preset activation. Below this amount of on_percent the thermostat won't go into security preset",
"security_default_on_percent": "The default heating percent value in security preset. Set to 0 to switch off heater in security present"
}
}
},
@@ -192,7 +193,8 @@
"data": {
"minimal_activation_delay": "Delay in secondes under which the equipment will not be activated",
"security_delay_min": "Maximum allowed delay in minutes between two temperature mesures. Above this delay, the thermostat will turn to a security off state",
"security_min_on_percent": "Minimal On-Percent value for security preset activation. Below this amount of on_percent the thermostat won't go into security preset"
"security_min_on_percent": "Minimal heating percent value for security preset activation. Below this amount of on_percent the thermostat won't go into security preset",
"security_default_on_percent": "The default heating percent value in security preset. Set to 0 to switch off heater in security present"
}
}
},
@@ -215,10 +217,13 @@
"entity": {
"climate": {
"versatile_thermostat": {
"states_attributes": {
"state_attributes": {
"preset_mode": {
"power": "Shedding",
"security": "Security"
"state": {
"power": "Shedding",
"security": "Security",
"none": "Manual"
}
}
}
}

View File

@@ -90,7 +90,8 @@
"data": {
"minimal_activation_delay": "Delay in secondes under which the equipment will not be activated",
"security_delay_min": "Maximum allowed delay in minutes between two temperature mesures. Above this delay, the thermostat will turn to a sceurity off state",
"security_min_on_percent": "Minimal On-Percent value for security preset activation. Below this amount of on_percent the thermostat won't go into security preset"
"security_min_on_percent": "Minimal heating percent value for security preset activation. Below this amount of on_percent the thermostat won't go into security preset",
"security_default_on_percent": "The default heating percent value in security preset. Set to 0 to switch off heater in security present"
}
}
},
@@ -192,7 +193,8 @@
"data": {
"minimal_activation_delay": "Delay in secondes under which the equipment will not be activated",
"security_delay_min": "Maximum allowed delay in minutes between two temperature mesures. Above this delay, the thermostat will turn to a sceurity off state",
"security_min_on_percent": "Minimal On-Percent value for security preset activation. Below this amount of on_percent the thermostat won't go into security preset"
"security_min_on_percent": "Minimal heating percent value for security preset activation. Below this amount of on_percent the thermostat won't go into security preset",
"security_default_on_percent": "The default heating percent value in security preset. Set to 0 to switch off heater in security present"
}
}
},
@@ -215,10 +217,13 @@
"entity": {
"climate": {
"versatile_thermostat": {
"states_attributes": {
"state_attributes": {
"preset_mode": {
"power": "Shedding",
"security": "Security"
"state": {
"power": "Shedding",
"security": "Security",
"none": "Manual"
}
}
}
}

View File

@@ -89,7 +89,8 @@
"data": {
"minimal_activation_delay": "Délai en secondes en-dessous duquel l'équipement ne sera pas activé",
"security_delay_min": "Délai maximal autorisé en minutes entre 2 mesures de températures. Au-dessus de ce délai, le thermostat se mettra en position éteinte de sécurité",
"security_min_on_percent": "Seuil de chauffage en-dessous duquel le préréglage sécurité ne sera jamais activé."
"security_min_on_percent": "Seuil minimal de pourcentage de chauffage en-dessous duquel le préréglage sécurité ne sera jamais activé",
"security_default_on_percent": "Valeur par défaut pour le pourcentage de chauffage en mode sécurité. Mettre 0 pour éteindre le radiateur en mode sécurité"
}
}
},
@@ -192,7 +193,8 @@
"data": {
"minimal_activation_delay": "Délai en seondes en-dessous duquel l'équipement ne sera pas activé",
"security_delay_min": "Délai maximal autorisé en minutes entre 2 mesures de températures. Au-dessus de ce délai, le thermostat se mettra en position éteinte de sécurité",
"security_min_on_percent": "Seuil de chauffage en-dessous duquel le préréglage sécurité ne sera jamais activé."
"security_min_on_percent": "Seuil minimal de pourcentage de chauffage en-dessous duquel le préréglage sécurité ne sera jamais activé",
"security_default_on_percent": "Valeur par défaut pour le pourcentage de chauffage en mode sécurité. Mettre 0 pour éteindre le radiateur en mode sécurité"
}
}
},
@@ -215,10 +217,13 @@
"entity": {
"climate": {
"versatile_thermostat": {
"states_attributes": {
"state_attributes": {
"preset_mode": {
"power": "Délestage",
"security": "Sécurité"
"state": {
"power": "Délestage",
"security": "Sécurité",
"none": "Manuel"
}
}
}
}