Compare commits
12 Commits
3.2.5
...
3.3.6.beta
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b38fbd9d78 | ||
|
|
6e8e72e343 | ||
|
|
2bebe3e210 | ||
|
|
aa3b87762d | ||
|
|
f4cabbf2c0 | ||
|
|
24b59e545b | ||
|
|
5997a26c73 | ||
|
|
fe4b9ced81 | ||
|
|
c4fc976007 | ||
|
|
31d862acab | ||
|
|
9709a9eed0 | ||
|
|
61eae8c066 |
@@ -141,9 +141,9 @@ template:
|
|||||||
device_class: energy
|
device_class: energy
|
||||||
state_class: total_increasing
|
state_class: total_increasing
|
||||||
state: >
|
state: >
|
||||||
{% set energy = state_attr('climate.thermostat_switch_1', 'total_energy') %}
|
{% set energy = state_attr('climate.thermostat_switch_1', 'total_energy') | float(default=-1) %}
|
||||||
{% if energy == 'unavailable' or energy is none%}unavailable{% else %}
|
{% if energy < 0 %}{{none}}{% else %}
|
||||||
{{ ((energy | float) / 1.0) | round(2, default=0) }}
|
{{ energy | round(2, default=0) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
- name: "Total énergie climate 2"
|
- name: "Total énergie climate 2"
|
||||||
unique_id: total_energie_climate2
|
unique_id: total_energie_climate2
|
||||||
@@ -151,9 +151,9 @@ template:
|
|||||||
device_class: energy
|
device_class: energy
|
||||||
state_class: total_increasing
|
state_class: total_increasing
|
||||||
state: >
|
state: >
|
||||||
{% set energy = state_attr('climate.thermostat_climate_2', 'total_energy') %}
|
{% set energy = state_attr('climate.thermostat_climate_2', 'total_energy') | float(default=-1) %}
|
||||||
{% if energy == 'unavailable' or energy is none%}unavailable{% else %}
|
{% if energy < 0 %}{{none}}{% else %}
|
||||||
{{ ((energy | float) / 1.0) | round(2, default=0) }}
|
{{ energy | round(2, default=0) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
- name: "Total énergie chambre"
|
- name: "Total énergie chambre"
|
||||||
unique_id: total_energie_chambre
|
unique_id: total_energie_chambre
|
||||||
@@ -161,9 +161,9 @@ template:
|
|||||||
device_class: energy
|
device_class: energy
|
||||||
state_class: total_increasing
|
state_class: total_increasing
|
||||||
state: >
|
state: >
|
||||||
{% set energy = state_attr('climate.thermostat_chambre', 'total_energy') %}
|
{% set energy = state_attr('climate.thermostat_chambre', 'total_energy') | float(default=-1) %}
|
||||||
{% if energy == 'unavailable' or energy is none%}unavailable{% else %}
|
{% if energy < 0 %}{{none}}{% else %}
|
||||||
{{ ((energy | float) / 1.0) | round(2, default=0) }}
|
{{ energy | round(2, default=0) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
switch:
|
switch:
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
>  Cette intégration de thermostat vise à simplifier considérablement vos automatisations autour de la gestion du chauffage. Parce que tous les événements autour du chauffage classiques sont gérés nativement par le thermostat (personne à la maison ?, activité détectée dans une pièce ?, fenêtre ouverte ?, délestage de courant ?), vous n'avez pas à vous encombrer de scripts et d'automatismes compliqués pour gérer vos climats. ;-).
|
>  Cette intégration de thermostat vise à simplifier considérablement vos automatisations autour de la gestion du chauffage. Parce que tous les événements autour du chauffage classiques sont gérés nativement par le thermostat (personne à la maison ?, activité détectée dans une pièce ?, fenêtre ouverte ?, délestage de courant ?), vous n'avez pas à vous encombrer de scripts et d'automatismes compliqués pour gérer vos climats. ;-).
|
||||||
|
|
||||||
- [Merci pour la bière buymecoffee: https://www.buymeacoffee.com/jmcollin78](#merci-pour-la-bière-buymecoffee-httpswwwbuymeacoffeecomjmcollin78)
|
- [Merci pour la bière buymecoffee](#merci-pour-la-bière-buymecoffee)
|
||||||
- [Quand l'utiliser et ne pas l'utiliser](#quand-lutiliser-et-ne-pas-lutiliser)
|
- [Quand l'utiliser et ne pas l'utiliser](#quand-lutiliser-et-ne-pas-lutiliser)
|
||||||
- [Pourquoi une nouvelle implémentation du thermostat ?](#pourquoi-une-nouvelle-implémentation-du-thermostat-)
|
- [Pourquoi une nouvelle implémentation du thermostat ?](#pourquoi-une-nouvelle-implémentation-du-thermostat-)
|
||||||
- [Comment installer cet incroyable Thermostat Versatile ?](#comment-installer-cet-incroyable-thermostat-versatile-)
|
- [Comment installer cet incroyable Thermostat Versatile ?](#comment-installer-cet-incroyable-thermostat-versatile-)
|
||||||
@@ -54,6 +54,7 @@ Ce composant personnalisé pour Home Assistant est une mise à niveau et est une
|
|||||||
|
|
||||||
|
|
||||||
>  _*Nouveautés*_
|
>  _*Nouveautés*_
|
||||||
|
> > * **Release 3.3**: ajout du mode Air Conditionné (AC). Cette fonction vous permet d'utiliser le mode AC de votre thermostat sous-jacent. Pour l'utiliser, vous devez cocher l'option "Uitliser le mode AC" et définir les valeurs de température pour les presets et pour les presets en cas d'absence
|
||||||
> * **Release 3.2** : ajout de la possibilité de commander plusieurs switch à partir du même thermostat. Dans ce mode, les switchs sont déclenchés avec un délai pour minimiser la puissance nécessaire à un instant (on minimise les périodes de recouvrement). Voir [Configuration](#sélectionnez-des-entités-pilotées)
|
> * **Release 3.2** : ajout de la possibilité de commander plusieurs switch à partir du même thermostat. Dans ce mode, les switchs sont déclenchés avec un délai pour minimiser la puissance nécessaire à un instant (on minimise les périodes de recouvrement). Voir [Configuration](#sélectionnez-des-entités-pilotées)
|
||||||
> * **Release 3.1** : ajout d'une détection de fenêtres/portes ouvertes par chute de température. Cette nouvelle fonction permet de stopper automatiquement un radiateur lorsque la température chute brutalement. Voir [Le mode auto](#le-mode-auto)
|
> * **Release 3.1** : ajout d'une détection de fenêtres/portes ouvertes par chute de température. Cette nouvelle fonction permet de stopper automatiquement un radiateur lorsque la température chute brutalement. Voir [Le mode auto](#le-mode-auto)
|
||||||
> * **Release majeure 3.0** : ajout d'un équipement thermostat et de capteurs (binaires et non binaires) associés. Beaucoup plus proche de la philosphie Home Assistant, vous avez maintenant un accès direct à l'énergie consommée par le radiateur piloté par le thermostat et à plein d'autres capteurs qui seront utiles dans vos automatisations et dashboard.
|
> * **Release majeure 3.0** : ajout d'un équipement thermostat et de capteurs (binaires et non binaires) associés. Beaucoup plus proche de la philosphie Home Assistant, vous avez maintenant un accès direct à l'énergie consommée par le radiateur piloté par le thermostat et à plein d'autres capteurs qui seront utiles dans vos automatisations et dashboard.
|
||||||
|
|||||||
@@ -53,7 +53,8 @@
|
|||||||
This custom component for Home Assistant is an upgrade and is a complete rewrite of the component "Awesome thermostat" (see [Github](https://github.com/dadge/awesome_thermostat)) with addition of features.
|
This custom component for Home Assistant is an upgrade and is a complete rewrite of the component "Awesome thermostat" (see [Github](https://github.com/dadge/awesome_thermostat)) with addition of features.
|
||||||
|
|
||||||
> _*News*_
|
> _*News*_
|
||||||
> * **Release 3.2**: added the ability to control multiple switches from the same thermostat. In this mode, the switches are triggered with a delay to minimize the power required at one time (we minimize the recovery periods). See [Configuration](#select-the-driven-entity)
|
> * **Release 3.3**: add the Air Conditionned mode (AC). This feature allow to use the eventual AC mode of your underlying climate entity. You have to check the "Use AC mode" checkbox in configuration and give preset temperature value for AC mode and AC mode when absent if absence is configured
|
||||||
|
> * **Release 3.2**: add the ability to control multiple switches from the same thermostat. In this mode, the switches are triggered with a delay to minimize the power required at one time (we minimize the recovery periods). See [Configuration](#select-the-driven-entity)
|
||||||
> * **Release 3.1**: added detection of open windows/doors by temperature drop. This new function makes it possible to automatically stop a radiator when the temperature drops suddenly. See [Auto mode](#auto-mode)
|
> * **Release 3.1**: added detection of open windows/doors by temperature drop. This new function makes it possible to automatically stop a radiator when the temperature drops suddenly. See [Auto mode](#auto-mode)
|
||||||
> * **Major release 3.0**: addition of 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 that will be useful in your automations and dashboard.
|
> * **Major release 3.0**: addition of 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 that will be useful in your automations and dashboard.
|
||||||
> * **release 2.3**: addition of the power and energy measurement of the radiator controlled by the thermostat.
|
> * **release 2.3**: addition of the power and energy measurement of the radiator controlled by the thermostat.
|
||||||
|
|||||||
@@ -100,6 +100,8 @@ from .const import (
|
|||||||
CONF_DEVICE_POWER,
|
CONF_DEVICE_POWER,
|
||||||
CONF_PRESETS,
|
CONF_PRESETS,
|
||||||
CONF_PRESETS_AWAY,
|
CONF_PRESETS_AWAY,
|
||||||
|
CONF_PRESETS_WITH_AC,
|
||||||
|
CONF_PRESETS_AWAY_WITH_AC,
|
||||||
CONF_CYCLE_MIN,
|
CONF_CYCLE_MIN,
|
||||||
CONF_PROP_FUNCTION,
|
CONF_PROP_FUNCTION,
|
||||||
CONF_TPI_COEF_INT,
|
CONF_TPI_COEF_INT,
|
||||||
@@ -127,10 +129,12 @@ from .const import (
|
|||||||
# CONF_THERMOSTAT_SWITCH,
|
# CONF_THERMOSTAT_SWITCH,
|
||||||
CONF_THERMOSTAT_CLIMATE,
|
CONF_THERMOSTAT_CLIMATE,
|
||||||
CONF_CLIMATE,
|
CONF_CLIMATE,
|
||||||
|
CONF_AC_MODE,
|
||||||
UnknownEntity,
|
UnknownEntity,
|
||||||
EventType,
|
EventType,
|
||||||
ATTR_MEAN_POWER_CYCLE,
|
ATTR_MEAN_POWER_CYCLE,
|
||||||
ATTR_TOTAL_ENERGY,
|
ATTR_TOTAL_ENERGY,
|
||||||
|
PRESET_AC_SUFFIX,
|
||||||
)
|
)
|
||||||
|
|
||||||
from .underlyings import UnderlyingSwitch, UnderlyingClimate, UnderlyingEntity
|
from .underlyings import UnderlyingSwitch, UnderlyingClimate, UnderlyingEntity
|
||||||
@@ -289,9 +293,12 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
self,
|
self,
|
||||||
entry_infos,
|
entry_infos,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self._ac_mode = entry_infos.get(CONF_AC_MODE) == True
|
||||||
# convert entry_infos into usable attributes
|
# convert entry_infos into usable attributes
|
||||||
presets = {}
|
presets = {}
|
||||||
for key, value in CONF_PRESETS.items():
|
items = CONF_PRESETS_WITH_AC.items() if self._ac_mode else CONF_PRESETS.items()
|
||||||
|
for key, value in items:
|
||||||
_LOGGER.debug("looking for key=%s, value=%s", key, value)
|
_LOGGER.debug("looking for key=%s, value=%s", key, value)
|
||||||
if value in entry_infos:
|
if value in entry_infos:
|
||||||
presets[key] = entry_infos.get(value)
|
presets[key] = entry_infos.get(value)
|
||||||
@@ -299,7 +306,12 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
_LOGGER.debug("value %s not found in Entry", value)
|
_LOGGER.debug("value %s not found in Entry", value)
|
||||||
|
|
||||||
presets_away = {}
|
presets_away = {}
|
||||||
for key, value in CONF_PRESETS_AWAY.items():
|
items = (
|
||||||
|
CONF_PRESETS_AWAY_WITH_AC.items()
|
||||||
|
if self._ac_mode
|
||||||
|
else CONF_PRESETS_AWAY.items()
|
||||||
|
)
|
||||||
|
for key, value in items:
|
||||||
_LOGGER.debug("looking for key=%s, value=%s", key, value)
|
_LOGGER.debug("looking for key=%s, value=%s", key, value)
|
||||||
if value in entry_infos:
|
if value in entry_infos:
|
||||||
presets_away[key] = entry_infos.get(value)
|
presets_away[key] = entry_infos.get(value)
|
||||||
@@ -394,9 +406,9 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
|
|
||||||
self._presence_on = self._presence_sensor_entity_id is not None
|
self._presence_on = self._presence_sensor_entity_id is not None
|
||||||
|
|
||||||
# if self.ac_mode: -> MODE_COOL should be better to use thermostat_over_climate type
|
if self._ac_mode:
|
||||||
# self.hvac_list = [HVAC_MODE_COOL, HVAC_MODE_OFF]
|
self._hvac_list = [HVACMode.HEAT, HVACMode.COOL, HVACMode.OFF]
|
||||||
# else:
|
else:
|
||||||
self._hvac_list = [HVACMode.HEAT, HVACMode.OFF]
|
self._hvac_list = [HVACMode.HEAT, HVACMode.OFF]
|
||||||
|
|
||||||
self._unit = self._hass.config.units.temperature_unit
|
self._unit = self._hass.config.units.temperature_unit
|
||||||
@@ -437,7 +449,6 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
self._target_temp = None
|
self._target_temp = None
|
||||||
self._saved_target_temp = PRESET_NONE
|
self._saved_target_temp = PRESET_NONE
|
||||||
self._humidity = None
|
self._humidity = None
|
||||||
self._ac_mode = False
|
|
||||||
self._fan_mode = None
|
self._fan_mode = None
|
||||||
self._swing_mode = None
|
self._swing_mode = None
|
||||||
self._cur_temp = None
|
self._cur_temp = None
|
||||||
@@ -494,13 +505,10 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
if len(presets):
|
if len(presets):
|
||||||
self._support_flags = SUPPORT_FLAGS | ClimateEntityFeature.PRESET_MODE
|
self._support_flags = SUPPORT_FLAGS | ClimateEntityFeature.PRESET_MODE
|
||||||
|
|
||||||
for key, val in presets.items():
|
for key, val in CONF_PRESETS.items(): # TODO before presets.items():
|
||||||
if val != 0.0:
|
if val != 0.0:
|
||||||
self._attr_preset_modes.append(key)
|
self._attr_preset_modes.append(key)
|
||||||
|
|
||||||
# self._attr_preset_modes = (
|
|
||||||
# [PRESET_NONE] + list(presets.keys()) + [PRESET_ACTIVITY]
|
|
||||||
# )
|
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
"After adding presets, preset_modes to %s", self._attr_preset_modes
|
"After adding presets, preset_modes to %s", self._attr_preset_modes
|
||||||
)
|
)
|
||||||
@@ -609,11 +617,11 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
# Ingore this error which is possible if underlying climate is not found temporary
|
# Ingore this error which is possible if underlying climate is not found temporary
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def remove_thermostat(self):
|
def remove_thermostat(self):
|
||||||
"""Called when the thermostat will be removed"""
|
"""Called when the thermostat will be removed"""
|
||||||
_LOGGER.info("%s - Removing thermostat", self)
|
_LOGGER.info("%s - Removing thermostat", self)
|
||||||
for under in self._underlyings:
|
for under in self._underlyings:
|
||||||
await under.remove_entity()
|
under.remove_entity()
|
||||||
|
|
||||||
async def async_startup(self):
|
async def async_startup(self):
|
||||||
"""Triggered on startup, used to get old state and set internal states accordingly"""
|
"""Triggered on startup, used to get old state and set internal states accordingly"""
|
||||||
@@ -1207,6 +1215,10 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
await under.set_hvac_mode(hvac_mode) or need_control_heating
|
await under.set_hvac_mode(hvac_mode) or need_control_heating
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# If AC is on maybe we have to change the temperature in force mode
|
||||||
|
if self._ac_mode:
|
||||||
|
await self._async_set_preset_mode_internal(self._attr_preset_mode, True)
|
||||||
|
|
||||||
if need_control_heating and sub_need_control_heating:
|
if need_control_heating and sub_need_control_heating:
|
||||||
await self._async_control_heating(force=True)
|
await self._async_control_heating(force=True)
|
||||||
|
|
||||||
@@ -1286,7 +1298,12 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
) # in security just keep the current target temperature, the thermostat should be off
|
) # in security just keep the current target temperature, the thermostat should be off
|
||||||
if preset_mode == PRESET_POWER:
|
if preset_mode == PRESET_POWER:
|
||||||
return self._power_temp
|
return self._power_temp
|
||||||
elif self._presence_on is False or self._presence_state in [
|
else:
|
||||||
|
# Select _ac presets if in COOL Mode
|
||||||
|
if self._ac_mode and self._hvac_mode == HVACMode.COOL:
|
||||||
|
preset_mode = preset_mode + PRESET_AC_SUFFIX
|
||||||
|
|
||||||
|
if self._presence_on is False or self._presence_state in [
|
||||||
STATE_ON,
|
STATE_ON,
|
||||||
STATE_HOME,
|
STATE_HOME,
|
||||||
]:
|
]:
|
||||||
@@ -1565,6 +1582,8 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
if not new_state:
|
if not new_state:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
new_hvac_mode = new_state.state
|
||||||
|
|
||||||
old_state = event.data.get("old_state")
|
old_state = event.data.get("old_state")
|
||||||
old_hvac_action = (
|
old_hvac_action = (
|
||||||
old_state.attributes.get("hvac_action")
|
old_state.attributes.get("hvac_action")
|
||||||
@@ -1577,16 +1596,21 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
else None
|
else None
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Issue 99 - some AC turn hvac_mode=cool and hvac_action=idle when sending a HVACMode_OFF command
|
||||||
|
if self._hvac_mode == HVACMode.OFF and new_hvac_action == HVACAction.IDLE:
|
||||||
|
_LOGGER.debug("The underlying switch to idle instead of OFF. We will consider it as OFF")
|
||||||
|
new_hvac_mode = HVACMode.OFF
|
||||||
|
|
||||||
_LOGGER.info(
|
_LOGGER.info(
|
||||||
"%s - Underlying climate changed. Event.new_state is %s, current_hvac_mode=%s, new_hvac_action=%s, old_hvac_action=%s",
|
"%s - Underlying climate changed. Event.new_hvac_mode is %s, current_hvac_mode=%s, new_hvac_action=%s, old_hvac_action=%s",
|
||||||
self,
|
self,
|
||||||
new_state,
|
new_hvac_mode,
|
||||||
self._hvac_mode,
|
self._hvac_mode,
|
||||||
new_hvac_action,
|
new_hvac_action,
|
||||||
old_hvac_action,
|
old_hvac_action,
|
||||||
)
|
)
|
||||||
|
|
||||||
if new_state.state in [
|
if new_hvac_mode in [
|
||||||
HVACMode.OFF,
|
HVACMode.OFF,
|
||||||
HVACMode.HEAT,
|
HVACMode.HEAT,
|
||||||
HVACMode.COOL,
|
HVACMode.COOL,
|
||||||
@@ -1594,8 +1618,9 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
HVACMode.DRY,
|
HVACMode.DRY,
|
||||||
HVACMode.AUTO,
|
HVACMode.AUTO,
|
||||||
HVACMode.FAN_ONLY,
|
HVACMode.FAN_ONLY,
|
||||||
|
None
|
||||||
]:
|
]:
|
||||||
self._hvac_mode = new_state.state
|
self._hvac_mode = new_hvac_mode
|
||||||
|
|
||||||
# Interpretation of hvac
|
# Interpretation of hvac
|
||||||
HVAC_ACTION_ON = [ # pylint: disable=invalid-name
|
HVAC_ACTION_ON = [ # pylint: disable=invalid-name
|
||||||
@@ -2050,7 +2075,10 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
now - self._last_ext_temperature_mesure.replace(tzinfo=self._current_tz)
|
now - self._last_ext_temperature_mesure.replace(tzinfo=self._current_tz)
|
||||||
).total_seconds() / 60.0
|
).total_seconds() / 60.0
|
||||||
|
|
||||||
mode_cond = self._is_over_climate or self._hvac_mode != HVACMode.OFF
|
# TODO before change:
|
||||||
|
# mode_cond = self._is_over_climate or self._hvac_mode != HVACMode.OFF
|
||||||
|
# fixed into this. Why if _is_over_climate we could into security even if HVACMode is OFF ?
|
||||||
|
mode_cond = self._hvac_mode != HVACMode.OFF
|
||||||
|
|
||||||
temp_cond: bool = (
|
temp_cond: bool = (
|
||||||
delta_temp > self._security_delay_min
|
delta_temp > self._security_delay_min
|
||||||
@@ -2078,9 +2106,17 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
switch_cond,
|
switch_cond,
|
||||||
)
|
)
|
||||||
|
|
||||||
ret = False
|
shouldClimateBeInSecurity = temp_cond and climate_cond
|
||||||
if mode_cond and temp_cond and climate_cond:
|
shouldSwitchBeInSecurity = temp_cond and switch_cond
|
||||||
if not self._security_state:
|
shouldBeInSecurity = shouldClimateBeInSecurity or shouldSwitchBeInSecurity
|
||||||
|
|
||||||
|
shouldStartSecurity = mode_cond and not self._security_state and shouldBeInSecurity
|
||||||
|
# attr_preset_mode is not necessary normaly. It is just here to be sure
|
||||||
|
shouldStopSecurity = self._security_state and not shouldBeInSecurity and self._attr_preset_mode == PRESET_SECURITY
|
||||||
|
|
||||||
|
# Logging and event
|
||||||
|
if shouldStartSecurity:
|
||||||
|
if shouldClimateBeInSecurity:
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
"%s - No temperature received for more than %.1f minutes (dt=%.1f, dext=%.1f) and underlying climate is %s. Set it into security mode",
|
"%s - No temperature received for more than %.1f minutes (dt=%.1f, dext=%.1f) and underlying climate is %s. Set it into security mode",
|
||||||
self,
|
self,
|
||||||
@@ -2089,10 +2125,7 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
delta_ext_temp,
|
delta_ext_temp,
|
||||||
self.hvac_action,
|
self.hvac_action,
|
||||||
)
|
)
|
||||||
ret = True
|
elif shouldSwitchBeInSecurity:
|
||||||
|
|
||||||
if mode_cond and temp_cond and switch_cond:
|
|
||||||
if not self._security_state:
|
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
"%s - No temperature received for more than %.1f minutes (dt=%.1f, dext=%.1f) and on_percent (%.2f) is over defined value (%.2f). Set it into security mode",
|
"%s - No temperature received for more than %.1f minutes (dt=%.1f, dext=%.1f) and on_percent (%.2f) is over defined value (%.2f). Set it into security mode",
|
||||||
self,
|
self,
|
||||||
@@ -2102,9 +2135,7 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
self._prop_algorithm.on_percent,
|
self._prop_algorithm.on_percent,
|
||||||
self._security_min_on_percent,
|
self._security_min_on_percent,
|
||||||
)
|
)
|
||||||
ret = True
|
|
||||||
|
|
||||||
if mode_cond and temp_cond and not self._security_state:
|
|
||||||
self.send_event(
|
self.send_event(
|
||||||
EventType.TEMPERATURE_EVENT,
|
EventType.TEMPERATURE_EVENT,
|
||||||
{
|
{
|
||||||
@@ -2120,8 +2151,8 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
if not self._security_state and ret:
|
if shouldStartSecurity:
|
||||||
self._security_state = ret
|
self._security_state = True
|
||||||
self.save_hvac_mode()
|
self.save_hvac_mode()
|
||||||
self.save_preset_mode()
|
self.save_preset_mode()
|
||||||
await self._async_set_preset_mode_internal(PRESET_SECURITY)
|
await self._async_set_preset_mode_internal(PRESET_SECURITY)
|
||||||
@@ -2147,18 +2178,14 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
if (
|
if shouldStopSecurity:
|
||||||
self._security_state
|
|
||||||
and self._attr_preset_mode == PRESET_SECURITY
|
|
||||||
and not ret
|
|
||||||
):
|
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
"%s - End of security mode. restoring hvac_mode to %s and preset_mode to %s",
|
"%s - End of security mode. restoring hvac_mode to %s and preset_mode to %s",
|
||||||
self,
|
self,
|
||||||
self._saved_hvac_mode,
|
self._saved_hvac_mode,
|
||||||
self._saved_preset_mode,
|
self._saved_preset_mode,
|
||||||
)
|
)
|
||||||
self._security_state = ret
|
self._security_state = False
|
||||||
# Restore hvac_mode if previously saved
|
# Restore hvac_mode if previously saved
|
||||||
if self._is_over_climate or self._security_default_on_percent <= 0.0:
|
if self._is_over_climate or self._security_default_on_percent <= 0.0:
|
||||||
await self.restore_hvac_mode(False)
|
await self.restore_hvac_mode(False)
|
||||||
@@ -2181,7 +2208,7 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
return ret
|
return shouldBeInSecurity
|
||||||
|
|
||||||
async def _async_control_heating(self, force=False, _=None):
|
async def _async_control_heating(self, force=False, _=None):
|
||||||
"""The main function used to run the calculation at each cycle"""
|
"""The main function used to run the calculation at each cycle"""
|
||||||
|
|||||||
@@ -61,7 +61,9 @@ from .const import (
|
|||||||
CONF_CYCLE_MIN,
|
CONF_CYCLE_MIN,
|
||||||
CONF_PRESET_POWER,
|
CONF_PRESET_POWER,
|
||||||
CONF_PRESETS,
|
CONF_PRESETS,
|
||||||
|
CONF_PRESETS_WITH_AC,
|
||||||
CONF_PRESETS_AWAY,
|
CONF_PRESETS_AWAY,
|
||||||
|
CONF_PRESETS_AWAY_WITH_AC,
|
||||||
CONF_PRESETS_SELECTIONABLE,
|
CONF_PRESETS_SELECTIONABLE,
|
||||||
CONF_PROP_FUNCTION,
|
CONF_PROP_FUNCTION,
|
||||||
CONF_TPI_COEF_EXT,
|
CONF_TPI_COEF_EXT,
|
||||||
@@ -83,6 +85,7 @@ from .const import (
|
|||||||
CONF_USE_MOTION_FEATURE,
|
CONF_USE_MOTION_FEATURE,
|
||||||
CONF_USE_PRESENCE_FEATURE,
|
CONF_USE_PRESENCE_FEATURE,
|
||||||
CONF_USE_POWER_FEATURE,
|
CONF_USE_POWER_FEATURE,
|
||||||
|
CONF_AC_MODE,
|
||||||
CONF_THERMOSTAT_TYPES,
|
CONF_THERMOSTAT_TYPES,
|
||||||
UnknownEntity,
|
UnknownEntity,
|
||||||
WindowOpenDetectionMethod,
|
WindowOpenDetectionMethod,
|
||||||
@@ -132,35 +135,6 @@ def add_suggested_values_to_schema(
|
|||||||
return vol.Schema(schema)
|
return vol.Schema(schema)
|
||||||
|
|
||||||
|
|
||||||
# def is_temperature_sensor(sensor: RegistryEntry):
|
|
||||||
# """Check if a registryEntry is a temperature sensor or assimilable to a temperature sensor"""
|
|
||||||
# if not sensor.entity_id.startswith(
|
|
||||||
# INPUT_NUMBER_DOMAIN
|
|
||||||
# ) and not sensor.entity_id.startswith(SENSOR_DOMAIN):
|
|
||||||
# return False
|
|
||||||
# return (
|
|
||||||
# sensor.device_class == TEMPERATURE
|
|
||||||
# or sensor.original_device_class == TEMPERATURE
|
|
||||||
# or sensor.unit_of_measurement in TEMPERATURE_UNITS
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# def is_power_sensor(sensor: RegistryEntry):
|
|
||||||
# """Check if a registryEntry is a power sensor or assimilable to a temperature sensor"""
|
|
||||||
# if not sensor.entity_id.startswith(
|
|
||||||
# INPUT_NUMBER_DOMAIN
|
|
||||||
# ) and not sensor.entity_id.startswith(SENSOR_DOMAIN):
|
|
||||||
# return False
|
|
||||||
# return (
|
|
||||||
# sensor.unit_of_measurement
|
|
||||||
# in [
|
|
||||||
# UnitOfPower.KILO_WATT,
|
|
||||||
# UnitOfPower.WATT,
|
|
||||||
# UnitOfPower.BTU_PER_HOUR,
|
|
||||||
# ]
|
|
||||||
# )
|
|
||||||
|
|
||||||
|
|
||||||
class VersatileThermostatBaseConfigFlow(FlowHandler):
|
class VersatileThermostatBaseConfigFlow(FlowHandler):
|
||||||
"""The base Config flow class. Used to put some code in commons."""
|
"""The base Config flow class. Used to put some code in commons."""
|
||||||
|
|
||||||
@@ -257,6 +231,7 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
|
|||||||
vol.Required(CONF_CLIMATE): selector.EntitySelector(
|
vol.Required(CONF_CLIMATE): selector.EntitySelector(
|
||||||
selector.EntitySelectorConfig(domain=CLIMATE_DOMAIN),
|
selector.EntitySelectorConfig(domain=CLIMATE_DOMAIN),
|
||||||
),
|
),
|
||||||
|
vol.Optional(CONF_AC_MODE, default=False): cv.boolean,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -274,6 +249,15 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.STEP_PRESETS_WITH_AC_DATA_SCHEMA = ( # pylint: disable=invalid-name
|
||||||
|
vol.Schema( # pylint: disable=invalid-name
|
||||||
|
{
|
||||||
|
vol.Optional(v, default=0.0): vol.Coerce(float)
|
||||||
|
for (k, v) in CONF_PRESETS_WITH_AC.items()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
self.STEP_WINDOW_DATA_SCHEMA = vol.Schema( # pylint: disable=invalid-name
|
self.STEP_WINDOW_DATA_SCHEMA = vol.Schema( # pylint: disable=invalid-name
|
||||||
{
|
{
|
||||||
vol.Optional(CONF_WINDOW_SENSOR): selector.EntitySelector(
|
vol.Optional(CONF_WINDOW_SENSOR): selector.EntitySelector(
|
||||||
@@ -340,6 +324,27 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.STEP_PRESENCE_WITH_AC_DATA_SCHEMA = ( # pylint: disable=invalid-name
|
||||||
|
vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Optional(CONF_PRESENCE_SENSOR): selector.EntitySelector(
|
||||||
|
selector.EntitySelectorConfig(
|
||||||
|
domain=[
|
||||||
|
PERSON_DOMAIN,
|
||||||
|
BINARY_SENSOR_DOMAIN,
|
||||||
|
INPUT_BOOLEAN_DOMAIN,
|
||||||
|
]
|
||||||
|
),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
).extend(
|
||||||
|
{
|
||||||
|
vol.Optional(v, default=17): vol.Coerce(float)
|
||||||
|
for (k, v) in CONF_PRESETS_AWAY_WITH_AC.items()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
self.STEP_ADVANCED_DATA_SCHEMA = vol.Schema( # pylint: disable=invalid-name
|
self.STEP_ADVANCED_DATA_SCHEMA = vol.Schema( # pylint: disable=invalid-name
|
||||||
{
|
{
|
||||||
vol.Required(
|
vol.Required(
|
||||||
@@ -489,9 +494,12 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
|
|||||||
elif self._infos[CONF_USE_PRESENCE_FEATURE]:
|
elif self._infos[CONF_USE_PRESENCE_FEATURE]:
|
||||||
next_step = self.async_step_presence
|
next_step = self.async_step_presence
|
||||||
|
|
||||||
return await self.generic_step(
|
if self._infos.get(CONF_AC_MODE) == True:
|
||||||
"presets", self.STEP_PRESETS_DATA_SCHEMA, user_input, next_step
|
schema = self.STEP_PRESETS_WITH_AC_DATA_SCHEMA
|
||||||
)
|
else:
|
||||||
|
schema = self.STEP_PRESETS_DATA_SCHEMA
|
||||||
|
|
||||||
|
return await self.generic_step("presets", schema, user_input, next_step)
|
||||||
|
|
||||||
async def async_step_window(self, user_input: dict | None = None) -> FlowResult:
|
async def async_step_window(self, user_input: dict | None = None) -> FlowResult:
|
||||||
"""Handle the window sensor flow steps"""
|
"""Handle the window sensor flow steps"""
|
||||||
@@ -542,9 +550,14 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
|
|||||||
"""Handle the presence management flow steps"""
|
"""Handle the presence management flow steps"""
|
||||||
_LOGGER.debug("Into ConfigFlow.async_step_presence user_input=%s", user_input)
|
_LOGGER.debug("Into ConfigFlow.async_step_presence user_input=%s", user_input)
|
||||||
|
|
||||||
|
if self._infos.get(CONF_AC_MODE) == True:
|
||||||
|
schema = self.STEP_PRESENCE_WITH_AC_DATA_SCHEMA
|
||||||
|
else:
|
||||||
|
schema = self.STEP_PRESENCE_DATA_SCHEMA
|
||||||
|
|
||||||
return await self.generic_step(
|
return await self.generic_step(
|
||||||
"presence",
|
"presence",
|
||||||
self.STEP_PRESENCE_DATA_SCHEMA,
|
schema,
|
||||||
user_input,
|
user_input,
|
||||||
self.async_step_advanced,
|
self.async_step_advanced,
|
||||||
)
|
)
|
||||||
@@ -676,9 +689,12 @@ class VersatileThermostatOptionsFlowHandler(
|
|||||||
elif self._infos[CONF_USE_PRESENCE_FEATURE]:
|
elif self._infos[CONF_USE_PRESENCE_FEATURE]:
|
||||||
next_step = self.async_step_presence
|
next_step = self.async_step_presence
|
||||||
|
|
||||||
return await self.generic_step(
|
if self._infos.get(CONF_AC_MODE) == True:
|
||||||
"presets", self.STEP_PRESETS_DATA_SCHEMA, user_input, next_step
|
schema = self.STEP_PRESETS_WITH_AC_DATA_SCHEMA
|
||||||
)
|
else:
|
||||||
|
schema = self.STEP_PRESETS_DATA_SCHEMA
|
||||||
|
|
||||||
|
return await self.generic_step("presets", schema, user_input, next_step)
|
||||||
|
|
||||||
async def async_step_window(self, user_input: dict | None = None) -> FlowResult:
|
async def async_step_window(self, user_input: dict | None = None) -> FlowResult:
|
||||||
"""Handle the window sensor flow steps"""
|
"""Handle the window sensor flow steps"""
|
||||||
@@ -736,9 +752,14 @@ class VersatileThermostatOptionsFlowHandler(
|
|||||||
"Into OptionsFlowHandler.async_step_presence user_input=%s", user_input
|
"Into OptionsFlowHandler.async_step_presence user_input=%s", user_input
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if self._infos.get(CONF_AC_MODE) == True:
|
||||||
|
schema = self.STEP_PRESENCE_WITH_AC_DATA_SCHEMA
|
||||||
|
else:
|
||||||
|
schema = self.STEP_PRESENCE_DATA_SCHEMA
|
||||||
|
|
||||||
return await self.generic_step(
|
return await self.generic_step(
|
||||||
"presence",
|
"presence",
|
||||||
self.STEP_PRESENCE_DATA_SCHEMA,
|
schema,
|
||||||
user_input,
|
user_input,
|
||||||
self.async_step_advanced,
|
self.async_step_advanced,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ from homeassistant.components.climate import (
|
|||||||
ClimateEntityFeature,
|
ClimateEntityFeature,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
PRESET_AC_SUFFIX = "_ac"
|
||||||
|
PRESET_ECO_AC = PRESET_ECO + PRESET_AC_SUFFIX
|
||||||
|
PRESET_COMFORT_AC = PRESET_COMFORT + PRESET_AC_SUFFIX
|
||||||
|
PRESET_BOOST_AC = PRESET_BOOST + PRESET_AC_SUFFIX
|
||||||
|
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
|
|
||||||
from .prop_algorithm import (
|
from .prop_algorithm import (
|
||||||
@@ -64,6 +69,7 @@ CONF_USE_WINDOW_FEATURE = "use_window_feature"
|
|||||||
CONF_USE_MOTION_FEATURE = "use_motion_feature"
|
CONF_USE_MOTION_FEATURE = "use_motion_feature"
|
||||||
CONF_USE_PRESENCE_FEATURE = "use_presence_feature"
|
CONF_USE_PRESENCE_FEATURE = "use_presence_feature"
|
||||||
CONF_USE_POWER_FEATURE = "use_power_feature"
|
CONF_USE_POWER_FEATURE = "use_power_feature"
|
||||||
|
CONF_AC_MODE = "ac_mode"
|
||||||
CONF_WINDOW_AUTO_OPEN_THRESHOLD = "window_auto_open_threshold"
|
CONF_WINDOW_AUTO_OPEN_THRESHOLD = "window_auto_open_threshold"
|
||||||
CONF_WINDOW_AUTO_CLOSE_THRESHOLD = "window_auto_close_threshold"
|
CONF_WINDOW_AUTO_CLOSE_THRESHOLD = "window_auto_close_threshold"
|
||||||
CONF_WINDOW_AUTO_MAX_DURATION = "window_auto_max_duration"
|
CONF_WINDOW_AUTO_MAX_DURATION = "window_auto_max_duration"
|
||||||
@@ -77,14 +83,39 @@ CONF_PRESETS = {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CONF_PRESETS_WITH_AC = {
|
||||||
|
p: f"{p}_temp"
|
||||||
|
for p in (
|
||||||
|
PRESET_ECO,
|
||||||
|
PRESET_COMFORT,
|
||||||
|
PRESET_BOOST,
|
||||||
|
PRESET_ECO_AC,
|
||||||
|
PRESET_COMFORT_AC,
|
||||||
|
PRESET_BOOST_AC,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PRESET_AWAY_SUFFIX = "_away"
|
PRESET_AWAY_SUFFIX = "_away"
|
||||||
|
|
||||||
CONF_PRESETS_AWAY = {
|
CONF_PRESETS_AWAY = {
|
||||||
p: f"{p}_temp"
|
p: f"{p}_temp"
|
||||||
for p in (
|
for p in (
|
||||||
PRESET_ECO + PRESET_AWAY_SUFFIX,
|
PRESET_ECO + PRESET_AWAY_SUFFIX,
|
||||||
PRESET_BOOST + PRESET_AWAY_SUFFIX,
|
|
||||||
PRESET_COMFORT + PRESET_AWAY_SUFFIX,
|
PRESET_COMFORT + PRESET_AWAY_SUFFIX,
|
||||||
|
PRESET_BOOST + PRESET_AWAY_SUFFIX,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
CONF_PRESETS_AWAY_WITH_AC = {
|
||||||
|
p: f"{p}_temp"
|
||||||
|
for p in (
|
||||||
|
PRESET_ECO + PRESET_AWAY_SUFFIX,
|
||||||
|
PRESET_COMFORT + PRESET_AWAY_SUFFIX,
|
||||||
|
PRESET_BOOST + PRESET_AWAY_SUFFIX,
|
||||||
|
PRESET_ECO_AC + PRESET_AWAY_SUFFIX,
|
||||||
|
PRESET_COMFORT_AC + PRESET_AWAY_SUFFIX,
|
||||||
|
PRESET_BOOST_AC + PRESET_AWAY_SUFFIX,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,6 +123,8 @@ CONF_PRESETS_SELECTIONABLE = [PRESET_ECO, PRESET_COMFORT, PRESET_BOOST]
|
|||||||
|
|
||||||
CONF_PRESETS_VALUES = list(CONF_PRESETS.values())
|
CONF_PRESETS_VALUES = list(CONF_PRESETS.values())
|
||||||
CONF_PRESETS_AWAY_VALUES = list(CONF_PRESETS_AWAY.values())
|
CONF_PRESETS_AWAY_VALUES = list(CONF_PRESETS_AWAY.values())
|
||||||
|
CONF_PRESETS_WITH_AC_VALUES = list(CONF_PRESETS_WITH_AC.values())
|
||||||
|
CONF_PRESETS_AWAY_WITH_AC_VALUES = list(CONF_PRESETS_AWAY_WITH_AC.values())
|
||||||
|
|
||||||
ALL_CONF = (
|
ALL_CONF = (
|
||||||
[
|
[
|
||||||
@@ -130,9 +163,12 @@ ALL_CONF = (
|
|||||||
CONF_USE_MOTION_FEATURE,
|
CONF_USE_MOTION_FEATURE,
|
||||||
CONF_USE_PRESENCE_FEATURE,
|
CONF_USE_PRESENCE_FEATURE,
|
||||||
CONF_USE_POWER_FEATURE,
|
CONF_USE_POWER_FEATURE,
|
||||||
|
CONF_AC_MODE,
|
||||||
]
|
]
|
||||||
+ CONF_PRESETS_VALUES
|
+ CONF_PRESETS_VALUES
|
||||||
+ CONF_PRESETS_AWAY_VALUES,
|
+ CONF_PRESETS_AWAY_VALUES
|
||||||
|
+ CONF_PRESETS_WITH_AC_VALUES
|
||||||
|
+ CONF_PRESETS_AWAY_WITH_AC_VALUES,
|
||||||
)
|
)
|
||||||
|
|
||||||
CONF_FUNCTIONS = [
|
CONF_FUNCTIONS = [
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
reload:
|
reload:
|
||||||
|
name: Reload
|
||||||
description: Reload all Versatile Thermostat entities.
|
description: Reload all Versatile Thermostat entities.
|
||||||
|
|
||||||
set_presence:
|
set_presence:
|
||||||
|
|||||||
@@ -30,7 +30,8 @@
|
|||||||
"heater_entity3_id": "3rd Heater switch",
|
"heater_entity3_id": "3rd Heater switch",
|
||||||
"heater_entity4_id": "4th Heater switch",
|
"heater_entity4_id": "4th Heater switch",
|
||||||
"proportional_function": "Algorithm",
|
"proportional_function": "Algorithm",
|
||||||
"climate_entity_id": "Underlying thermostat"
|
"climate_entity_id": "Underlying thermostat",
|
||||||
|
"ac_mode": "AC mode"
|
||||||
},
|
},
|
||||||
"data_description": {
|
"data_description": {
|
||||||
"heater_entity_id": "Mandatory heater entity id",
|
"heater_entity_id": "Mandatory heater entity id",
|
||||||
@@ -38,7 +39,8 @@
|
|||||||
"heater_entity3_id": "Optional 3rd Heater entity id. Leave empty if not used",
|
"heater_entity3_id": "Optional 3rd Heater entity id. Leave empty if not used",
|
||||||
"heater_entity4_id": "Optional 4th Heater entity id. Leave empty if not used",
|
"heater_entity4_id": "Optional 4th Heater entity id. Leave empty if not used",
|
||||||
"proportional_function": "Algorithm to use (TPI is the only one for now)",
|
"proportional_function": "Algorithm to use (TPI is the only one for now)",
|
||||||
"climate_entity_id": "Underlying climate entity id"
|
"climate_entity_id": "Underlying climate entity id",
|
||||||
|
"ac_mode": "Use the Air Conditioning (AC) mode"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tpi": {
|
"tpi": {
|
||||||
@@ -55,7 +57,10 @@
|
|||||||
"data": {
|
"data": {
|
||||||
"eco_temp": "Temperature in Eco preset",
|
"eco_temp": "Temperature in Eco preset",
|
||||||
"comfort_temp": "Temperature in Comfort preset",
|
"comfort_temp": "Temperature in Comfort preset",
|
||||||
"boost_temp": "Temperature in Boost preset"
|
"boost_temp": "Temperature in Boost preset",
|
||||||
|
"eco_ac_temp": "Temperature in Eco preset for AC mode",
|
||||||
|
"comfort_ac_temp": "Temperature in Comfort preset for AC mode",
|
||||||
|
"boost_ac_temp": "Temperature in Boost preset for AC mode"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"window": {
|
"window": {
|
||||||
@@ -102,7 +107,10 @@
|
|||||||
"presence_sensor_entity_id": "Presence sensor entity id (true is present)",
|
"presence_sensor_entity_id": "Presence sensor entity id (true is present)",
|
||||||
"eco_away_temp": "Temperature in Eco preset when no presence",
|
"eco_away_temp": "Temperature in Eco preset when no presence",
|
||||||
"comfort_away_temp": "Temperature in Comfort preset when no presence",
|
"comfort_away_temp": "Temperature in Comfort preset when no presence",
|
||||||
"boost_away_temp": "Temperature in Boost preset when no presence"
|
"boost_away_temp": "Temperature in Boost preset when no presence",
|
||||||
|
"eco_ac_away_temp": "Temperature in Eco preset when no presence in AC mode",
|
||||||
|
"comfort_ac_away_temp": "Temperature in Comfort preset when no presence in AC mode",
|
||||||
|
"boost_ac_away_temp": "Temperature in Boost preset when no presence in AC mode"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"advanced": {
|
"advanced": {
|
||||||
@@ -161,7 +169,8 @@
|
|||||||
"heater_entity3_id": "3rd Heater switch",
|
"heater_entity3_id": "3rd Heater switch",
|
||||||
"heater_entity4_id": "4th Heater switch",
|
"heater_entity4_id": "4th Heater switch",
|
||||||
"proportional_function": "Algorithm",
|
"proportional_function": "Algorithm",
|
||||||
"climate_entity_id": "Underlying thermostat"
|
"climate_entity_id": "Underlying thermostat",
|
||||||
|
"ac_mode": "AC mode"
|
||||||
},
|
},
|
||||||
"data_description": {
|
"data_description": {
|
||||||
"heater_entity_id": "Mandatory heater entity id",
|
"heater_entity_id": "Mandatory heater entity id",
|
||||||
@@ -169,7 +178,8 @@
|
|||||||
"heater_entity3_id": "Optional 3rd Heater entity id. Leave empty if not used",
|
"heater_entity3_id": "Optional 3rd Heater entity id. Leave empty if not used",
|
||||||
"heater_entity4_id": "Optional 4th Heater entity id. Leave empty if not used",
|
"heater_entity4_id": "Optional 4th Heater entity id. Leave empty if not used",
|
||||||
"proportional_function": "Algorithm to use (TPI is the only one for now)",
|
"proportional_function": "Algorithm to use (TPI is the only one for now)",
|
||||||
"climate_entity_id": "Underlying climate entity id"
|
"climate_entity_id": "Underlying climate entity id",
|
||||||
|
"ac_mode": "Use the Air Conditioning (AC) mode"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tpi": {
|
"tpi": {
|
||||||
@@ -186,7 +196,10 @@
|
|||||||
"data": {
|
"data": {
|
||||||
"eco_temp": "Temperature in Eco preset",
|
"eco_temp": "Temperature in Eco preset",
|
||||||
"comfort_temp": "Temperature in Comfort preset",
|
"comfort_temp": "Temperature in Comfort preset",
|
||||||
"boost_temp": "Temperature in Boost preset"
|
"boost_temp": "Temperature in Boost preset",
|
||||||
|
"eco_ac_temp": "Temperature in Eco preset for AC mode",
|
||||||
|
"comfort_ac_temp": "Temperature in Comfort preset for AC mode",
|
||||||
|
"boost_ac_temp": "Temperature in Boost preset for AC mode"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"window": {
|
"window": {
|
||||||
@@ -233,7 +246,10 @@
|
|||||||
"presence_sensor_entity_id": "Presence sensor entity id (true is present)",
|
"presence_sensor_entity_id": "Presence sensor entity id (true is present)",
|
||||||
"eco_away_temp": "Temperature in Eco preset when no presence",
|
"eco_away_temp": "Temperature in Eco preset when no presence",
|
||||||
"comfort_away_temp": "Temperature in Comfort preset when no presence",
|
"comfort_away_temp": "Temperature in Comfort preset when no presence",
|
||||||
"boost_away_temp": "Temperature in Boost preset when no presence"
|
"boost_away_temp": "Temperature in Boost preset when no presence",
|
||||||
|
"eco_ac_away_temp": "Temperature in Eco preset when no presence in AC mode",
|
||||||
|
"comfort_ac_away_temp": "Temperature in Comfort preset when no presence in AC mode",
|
||||||
|
"boost_ac_away_temp": "Temperature in Boost preset when no presence in AC mode"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"advanced": {
|
"advanced": {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ from custom_components.versatile_thermostat.const import (
|
|||||||
CONF_THERMOSTAT_CLIMATE,
|
CONF_THERMOSTAT_CLIMATE,
|
||||||
CONF_THERMOSTAT_SWITCH,
|
CONF_THERMOSTAT_SWITCH,
|
||||||
CONF_THERMOSTAT_TYPE,
|
CONF_THERMOSTAT_TYPE,
|
||||||
|
CONF_AC_MODE,
|
||||||
CONF_TEMP_SENSOR,
|
CONF_TEMP_SENSOR,
|
||||||
CONF_EXTERNAL_TEMP_SENSOR,
|
CONF_EXTERNAL_TEMP_SENSOR,
|
||||||
CONF_CYCLE_MIN,
|
CONF_CYCLE_MIN,
|
||||||
@@ -112,6 +113,7 @@ MOCK_TH_OVER_SWITCH_TPI_CONFIG = {
|
|||||||
|
|
||||||
MOCK_TH_OVER_CLIMATE_TYPE_CONFIG = {
|
MOCK_TH_OVER_CLIMATE_TYPE_CONFIG = {
|
||||||
CONF_CLIMATE: "climate.mock_climate",
|
CONF_CLIMATE: "climate.mock_climate",
|
||||||
|
CONF_AC_MODE: False,
|
||||||
}
|
}
|
||||||
|
|
||||||
MOCK_PRESETS_CONFIG = {
|
MOCK_PRESETS_CONFIG = {
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ async def test_window_management_time_not_enough(
|
|||||||
await try_window_condition(None)
|
await try_window_condition(None)
|
||||||
assert entity.window_state == STATE_OFF
|
assert entity.window_state == STATE_OFF
|
||||||
|
|
||||||
await entity.remove_thermostat()
|
entity.remove_thermostat()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("expected_lingering_tasks", [True])
|
@pytest.mark.parametrize("expected_lingering_tasks", [True])
|
||||||
@@ -234,7 +234,7 @@ async def test_window_management_time_enough(
|
|||||||
assert entity.preset_mode is PRESET_BOOST
|
assert entity.preset_mode is PRESET_BOOST
|
||||||
|
|
||||||
# Clean the entity
|
# Clean the entity
|
||||||
await entity.remove_thermostat()
|
entity.remove_thermostat()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("expected_lingering_tasks", [True])
|
@pytest.mark.parametrize("expected_lingering_tasks", [True])
|
||||||
@@ -418,7 +418,7 @@ async def test_window_auto_fast(hass: HomeAssistant, skip_hass_states_is_state):
|
|||||||
assert entity.hvac_mode is HVACMode.HEAT
|
assert entity.hvac_mode is HVACMode.HEAT
|
||||||
|
|
||||||
# Clean the entity
|
# Clean the entity
|
||||||
await entity.remove_thermostat()
|
entity.remove_thermostat()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("expected_lingering_tasks", [True])
|
@pytest.mark.parametrize("expected_lingering_tasks", [True])
|
||||||
@@ -561,7 +561,7 @@ async def test_window_auto_auto_stop(hass: HomeAssistant, skip_hass_states_is_st
|
|||||||
assert entity.preset_mode is PRESET_BOOST
|
assert entity.preset_mode is PRESET_BOOST
|
||||||
|
|
||||||
# Clean the entity
|
# Clean the entity
|
||||||
await entity.remove_thermostat()
|
entity.remove_thermostat()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("expected_lingering_tasks", [True])
|
@pytest.mark.parametrize("expected_lingering_tasks", [True])
|
||||||
@@ -670,4 +670,4 @@ async def test_window_auto_no_on_percent(
|
|||||||
assert entity.hvac_mode is HVACMode.HEAT
|
assert entity.hvac_mode is HVACMode.HEAT
|
||||||
|
|
||||||
# Clean the entity
|
# Clean the entity
|
||||||
await entity.remove_thermostat()
|
entity.remove_thermostat()
|
||||||
|
|||||||
@@ -30,7 +30,8 @@
|
|||||||
"heater_entity3_id": "3rd Heater switch",
|
"heater_entity3_id": "3rd Heater switch",
|
||||||
"heater_entity4_id": "4th Heater switch",
|
"heater_entity4_id": "4th Heater switch",
|
||||||
"proportional_function": "Algorithm",
|
"proportional_function": "Algorithm",
|
||||||
"climate_entity_id": "Underlying thermostat"
|
"climate_entity_id": "Underlying thermostat",
|
||||||
|
"ac_mode": "AC mode"
|
||||||
},
|
},
|
||||||
"data_description": {
|
"data_description": {
|
||||||
"heater_entity_id": "Mandatory heater entity id",
|
"heater_entity_id": "Mandatory heater entity id",
|
||||||
@@ -38,7 +39,8 @@
|
|||||||
"heater_entity3_id": "Optional 3rd Heater entity id. Leave empty if not used",
|
"heater_entity3_id": "Optional 3rd Heater entity id. Leave empty if not used",
|
||||||
"heater_entity4_id": "Optional 4th Heater entity id. Leave empty if not used",
|
"heater_entity4_id": "Optional 4th Heater entity id. Leave empty if not used",
|
||||||
"proportional_function": "Algorithm to use (TPI is the only one for now)",
|
"proportional_function": "Algorithm to use (TPI is the only one for now)",
|
||||||
"climate_entity_id": "Underlying climate entity id"
|
"climate_entity_id": "Underlying climate entity id",
|
||||||
|
"ac_mode": "Use the Air Conditioning (AC) mode"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tpi": {
|
"tpi": {
|
||||||
@@ -55,7 +57,10 @@
|
|||||||
"data": {
|
"data": {
|
||||||
"eco_temp": "Temperature in Eco preset",
|
"eco_temp": "Temperature in Eco preset",
|
||||||
"comfort_temp": "Temperature in Comfort preset",
|
"comfort_temp": "Temperature in Comfort preset",
|
||||||
"boost_temp": "Temperature in Boost preset"
|
"boost_temp": "Temperature in Boost preset",
|
||||||
|
"eco_ac_temp": "Temperature in Eco preset for AC mode",
|
||||||
|
"comfort_ac_temp": "Temperature in Comfort preset for AC mode",
|
||||||
|
"boost_ac_temp": "Temperature in Boost preset for AC mode"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"window": {
|
"window": {
|
||||||
@@ -102,7 +107,10 @@
|
|||||||
"presence_sensor_entity_id": "Presence sensor entity id (true is present)",
|
"presence_sensor_entity_id": "Presence sensor entity id (true is present)",
|
||||||
"eco_away_temp": "Temperature in Eco preset when no presence",
|
"eco_away_temp": "Temperature in Eco preset when no presence",
|
||||||
"comfort_away_temp": "Temperature in Comfort preset when no presence",
|
"comfort_away_temp": "Temperature in Comfort preset when no presence",
|
||||||
"boost_away_temp": "Temperature in Boost preset when no presence"
|
"boost_away_temp": "Temperature in Boost preset when no presence",
|
||||||
|
"eco_ac_away_temp": "Temperature in Eco preset when no presence in AC mode",
|
||||||
|
"comfort_ac_away_temp": "Temperature in Comfort preset when no presence in AC mode",
|
||||||
|
"boost_ac_away_temp": "Temperature in Boost preset when no presence in AC mode"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"advanced": {
|
"advanced": {
|
||||||
@@ -161,7 +169,8 @@
|
|||||||
"heater_entity3_id": "3rd Heater switch",
|
"heater_entity3_id": "3rd Heater switch",
|
||||||
"heater_entity4_id": "4th Heater switch",
|
"heater_entity4_id": "4th Heater switch",
|
||||||
"proportional_function": "Algorithm",
|
"proportional_function": "Algorithm",
|
||||||
"climate_entity_id": "Underlying thermostat"
|
"climate_entity_id": "Underlying thermostat",
|
||||||
|
"ac_mode": "AC mode"
|
||||||
},
|
},
|
||||||
"data_description": {
|
"data_description": {
|
||||||
"heater_entity_id": "Mandatory heater entity id",
|
"heater_entity_id": "Mandatory heater entity id",
|
||||||
@@ -169,7 +178,8 @@
|
|||||||
"heater_entity3_id": "Optional 3rd Heater entity id. Leave empty if not used",
|
"heater_entity3_id": "Optional 3rd Heater entity id. Leave empty if not used",
|
||||||
"heater_entity4_id": "Optional 4th Heater entity id. Leave empty if not used",
|
"heater_entity4_id": "Optional 4th Heater entity id. Leave empty if not used",
|
||||||
"proportional_function": "Algorithm to use (TPI is the only one for now)",
|
"proportional_function": "Algorithm to use (TPI is the only one for now)",
|
||||||
"climate_entity_id": "Underlying climate entity id"
|
"climate_entity_id": "Underlying climate entity id",
|
||||||
|
"ac_mode": "Use the Air Conditioning (AC) mode"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tpi": {
|
"tpi": {
|
||||||
@@ -186,7 +196,10 @@
|
|||||||
"data": {
|
"data": {
|
||||||
"eco_temp": "Temperature in Eco preset",
|
"eco_temp": "Temperature in Eco preset",
|
||||||
"comfort_temp": "Temperature in Comfort preset",
|
"comfort_temp": "Temperature in Comfort preset",
|
||||||
"boost_temp": "Temperature in Boost preset"
|
"boost_temp": "Temperature in Boost preset",
|
||||||
|
"eco_ac_temp": "Temperature in Eco preset for AC mode",
|
||||||
|
"comfort_ac_temp": "Temperature in Comfort preset for AC mode",
|
||||||
|
"boost_ac_temp": "Temperature in Boost preset for AC mode"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"window": {
|
"window": {
|
||||||
@@ -233,7 +246,10 @@
|
|||||||
"presence_sensor_entity_id": "Presence sensor entity id (true is present)",
|
"presence_sensor_entity_id": "Presence sensor entity id (true is present)",
|
||||||
"eco_away_temp": "Temperature in Eco preset when no presence",
|
"eco_away_temp": "Temperature in Eco preset when no presence",
|
||||||
"comfort_away_temp": "Temperature in Comfort preset when no presence",
|
"comfort_away_temp": "Temperature in Comfort preset when no presence",
|
||||||
"boost_away_temp": "Temperature in Boost preset when no presence"
|
"boost_away_temp": "Temperature in Boost preset when no presence",
|
||||||
|
"eco_ac_away_temp": "Temperature in Eco preset when no presence in AC mode",
|
||||||
|
"comfort_ac_away_temp": "Temperature in Comfort preset when no presence in AC mode",
|
||||||
|
"boost_ac_away_temp": "Temperature in Boost preset when no presence in AC mode"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"advanced": {
|
"advanced": {
|
||||||
|
|||||||
@@ -29,7 +29,8 @@
|
|||||||
"heater_entity3_id": "3ème radiateur",
|
"heater_entity3_id": "3ème radiateur",
|
||||||
"heater_entity4_id": "4ème radiateur",
|
"heater_entity4_id": "4ème radiateur",
|
||||||
"proportional_function": "Algorithme",
|
"proportional_function": "Algorithme",
|
||||||
"climate_entity_id": "Thermostat sous-jacent"
|
"climate_entity_id": "Thermostat sous-jacent",
|
||||||
|
"ac_mode": "AC mode ?"
|
||||||
},
|
},
|
||||||
"data_description": {
|
"data_description": {
|
||||||
"heater_entity_id": "Entity id du 1er radiateur obligatoire",
|
"heater_entity_id": "Entity id du 1er radiateur obligatoire",
|
||||||
@@ -37,7 +38,8 @@
|
|||||||
"heater_entity3_id": "Optionnel entity id du 3ème radiateur",
|
"heater_entity3_id": "Optionnel entity id du 3ème radiateur",
|
||||||
"heater_entity4_id": "Optionnel entity id du 4ème radiateur",
|
"heater_entity4_id": "Optionnel entity id du 4ème radiateur",
|
||||||
"proportional_function": "Algorithme à utiliser (Seul TPI est disponible pour l'instant)",
|
"proportional_function": "Algorithme à utiliser (Seul TPI est disponible pour l'instant)",
|
||||||
"climate_entity_id": "Entity id du thermostat sous-jacent"
|
"climate_entity_id": "Entity id du thermostat sous-jacent",
|
||||||
|
"ac_mode": "Utilisation du mode Air Conditionné (AC)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tpi": {
|
"tpi": {
|
||||||
@@ -54,7 +56,10 @@
|
|||||||
"data": {
|
"data": {
|
||||||
"eco_temp": "Température en preset Eco",
|
"eco_temp": "Température en preset Eco",
|
||||||
"comfort_temp": "Température en preset Comfort",
|
"comfort_temp": "Température en preset Comfort",
|
||||||
"boost_temp": "Température en preset Boost"
|
"boost_temp": "Température en preset Boost",
|
||||||
|
"eco_ac_temp": "Température en preset Eco en mode AC",
|
||||||
|
"comfort_ac_temp": "Température en preset Comfort en mode AC",
|
||||||
|
"boost_ac_temp": "Température en preset Boost en mode AC"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"window": {
|
"window": {
|
||||||
@@ -101,7 +106,10 @@
|
|||||||
"presence_sensor_entity_id": "Capteur de présence entity id (true si quelqu'un est présent)",
|
"presence_sensor_entity_id": "Capteur de présence entity id (true si quelqu'un est présent)",
|
||||||
"eco_away_temp": "Température en preset Eco en cas d'absence",
|
"eco_away_temp": "Température en preset Eco en cas d'absence",
|
||||||
"comfort_away_temp": "Température en preset Comfort en cas d'absence",
|
"comfort_away_temp": "Température en preset Comfort en cas d'absence",
|
||||||
"boost_away_temp": "Température en preset Boost en cas d'absence"
|
"boost_away_temp": "Température en preset Boost en cas d'absence",
|
||||||
|
"eco_ac_away_temp": "Température en preset Eco en cas d'absence en mode AC",
|
||||||
|
"comfort_ac_away_temp": "Température en preset Comfort en cas d'absence en mode AC",
|
||||||
|
"boost_ac_away_temp": "Température en preset Boost en cas d'absence en mode AC"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"advanced": {
|
"advanced": {
|
||||||
@@ -161,7 +169,8 @@
|
|||||||
"heater_entity3_id": "3ème radiateur",
|
"heater_entity3_id": "3ème radiateur",
|
||||||
"heater_entity4_id": "4ème radiateur",
|
"heater_entity4_id": "4ème radiateur",
|
||||||
"proportional_function": "Algorithme",
|
"proportional_function": "Algorithme",
|
||||||
"climate_entity_id": "Thermostat sous-jacent"
|
"climate_entity_id": "Thermostat sous-jacent",
|
||||||
|
"ac_mode": "AC mode ?"
|
||||||
},
|
},
|
||||||
"data_description": {
|
"data_description": {
|
||||||
"heater_entity_id": "Entity id du 1er radiateur obligatoire",
|
"heater_entity_id": "Entity id du 1er radiateur obligatoire",
|
||||||
@@ -169,7 +178,8 @@
|
|||||||
"heater_entity3_id": "Optionnel entity id du 3ème radiateur",
|
"heater_entity3_id": "Optionnel entity id du 3ème radiateur",
|
||||||
"heater_entity4_id": "Optionnel entity id du 4ème radiateur",
|
"heater_entity4_id": "Optionnel entity id du 4ème radiateur",
|
||||||
"proportional_function": "Algorithme à utiliser (Seul TPI est disponible pour l'instant)",
|
"proportional_function": "Algorithme à utiliser (Seul TPI est disponible pour l'instant)",
|
||||||
"climate_entity_id": "Entity id du thermostat sous-jacent"
|
"climate_entity_id": "Entity id du thermostat sous-jacent",
|
||||||
|
"ac_mode": "Utilisation du mode Air Conditionné (AC)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tpi": {
|
"tpi": {
|
||||||
@@ -186,7 +196,10 @@
|
|||||||
"data": {
|
"data": {
|
||||||
"eco_temp": "Température en preset Eco",
|
"eco_temp": "Température en preset Eco",
|
||||||
"comfort_temp": "Température en preset Comfort",
|
"comfort_temp": "Température en preset Comfort",
|
||||||
"boost_temp": "Température en preset Boost"
|
"boost_temp": "Température en preset Boost",
|
||||||
|
"eco_ac_temp": "Température en preset Eco en mode AC",
|
||||||
|
"comfort_ac_temp": "Température en preset Comfort en mode AC",
|
||||||
|
"boost_ac_temp": "Température en preset Boost en mode AC"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"window": {
|
"window": {
|
||||||
@@ -233,7 +246,10 @@
|
|||||||
"presence_sensor_entity_id": "Capteur de présence entity id (true si quelqu'un est présent)",
|
"presence_sensor_entity_id": "Capteur de présence entity id (true si quelqu'un est présent)",
|
||||||
"eco_away_temp": "Température en preset Eco en cas d'absence",
|
"eco_away_temp": "Température en preset Eco en cas d'absence",
|
||||||
"comfort_away_temp": "Température en preset Comfort en cas d'absence",
|
"comfort_away_temp": "Température en preset Comfort en cas d'absence",
|
||||||
"boost_away_temp": "Température en preset Boost en cas d'absence"
|
"boost_away_temp": "Température en preset Boost en cas d'absence",
|
||||||
|
"eco_ac_away_temp": "Température en preset Eco en cas d'absence en mode AC",
|
||||||
|
"comfort_ac_away_temp": "Température en preset Comfort en cas d'absence en mode AC",
|
||||||
|
"boost_ac_away_temp": "Température en preset Boost en cas d'absence en mode AC"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"advanced": {
|
"advanced": {
|
||||||
|
|||||||
@@ -30,7 +30,8 @@
|
|||||||
"heater_entity3_id": "Terzo riscaldatore",
|
"heater_entity3_id": "Terzo riscaldatore",
|
||||||
"heater_entity4_id": "Quarto riscaldatore",
|
"heater_entity4_id": "Quarto riscaldatore",
|
||||||
"proportional_function": "Algoritmo",
|
"proportional_function": "Algoritmo",
|
||||||
"climate_entity_id": "Termostato sottostante"
|
"climate_entity_id": "Termostato sottostante",
|
||||||
|
"ac_mode": "AC mode ?"
|
||||||
},
|
},
|
||||||
"data_description": {
|
"data_description": {
|
||||||
"heater_entity_id": "Entity id obbligatoria del primo riscaldatore",
|
"heater_entity_id": "Entity id obbligatoria del primo riscaldatore",
|
||||||
@@ -38,7 +39,8 @@
|
|||||||
"heater_entity3_id": "Entity id del terzo riscaldatore facoltativo. Lasciare vuoto se non utilizzato",
|
"heater_entity3_id": "Entity id del terzo riscaldatore facoltativo. Lasciare vuoto se non utilizzato",
|
||||||
"heater_entity4_id": "Entity id del quarto riscaldatore facoltativo. Lasciare vuoto se non utilizzato",
|
"heater_entity4_id": "Entity id del quarto riscaldatore facoltativo. Lasciare vuoto se non utilizzato",
|
||||||
"proportional_function": "Algoritmo da utilizzare (il TPI per adesso è l'unico)",
|
"proportional_function": "Algoritmo da utilizzare (il TPI per adesso è l'unico)",
|
||||||
"climate_entity_id": "Entity id del termostato sottostante"
|
"climate_entity_id": "Entity id del termostato sottostante",
|
||||||
|
"ac_mode": "Utilizzare la modalità AC (Air Conditioned) ?"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tpi": {
|
"tpi": {
|
||||||
@@ -55,7 +57,10 @@
|
|||||||
"data": {
|
"data": {
|
||||||
"eco_temp": "Temperatura nel preset Eco",
|
"eco_temp": "Temperatura nel preset Eco",
|
||||||
"comfort_temp": "Temperatura nel preset Comfort",
|
"comfort_temp": "Temperatura nel preset Comfort",
|
||||||
"boost_temp": "Temperatura nel preset Boost"
|
"boost_temp": "Temperatura nel preset Boost",
|
||||||
|
"eco_ac_temp": "Temperatura nel preset Eco (AC mode)",
|
||||||
|
"comfort_ac_temp": "Temperatura nel preset Comfort (AC mode)",
|
||||||
|
"boost_ac_temp": "Temperatura nel preset Boost (AC mode)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"window": {
|
"window": {
|
||||||
@@ -102,7 +107,10 @@
|
|||||||
"presence_sensor_entity_id": "Entity id sensore presenza (true se è presente qualcuno)",
|
"presence_sensor_entity_id": "Entity id sensore presenza (true se è presente qualcuno)",
|
||||||
"eco_away_temp": "Temperatura al preset Eco in caso d'assenza",
|
"eco_away_temp": "Temperatura al preset Eco in caso d'assenza",
|
||||||
"comfort_away_temp": "Temperatura al preset Comfort in caso d'assenza",
|
"comfort_away_temp": "Temperatura al preset Comfort in caso d'assenza",
|
||||||
"boost_away_temp": "Temperatura al preset Boost in caso d'assenza"
|
"boost_away_temp": "Temperatura al preset Boost in caso d'assenza",
|
||||||
|
"eco_ac_away_temp": "Temperatura al preset Eco in caso d'assenza (AC mode)",
|
||||||
|
"comfort_ac_away_temp": "Temperatura al preset Comfort in caso d'assenza (AC mode)",
|
||||||
|
"boost_ac_away_temp": "Temperatura al preset Boost in caso d'assenza (AC mode)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"advanced": {
|
"advanced": {
|
||||||
@@ -161,7 +169,8 @@
|
|||||||
"heater_entity3_id": "Terzo interruttore riscaldatore",
|
"heater_entity3_id": "Terzo interruttore riscaldatore",
|
||||||
"heater_entity4_id": "Quarto interruttore riscaldatore",
|
"heater_entity4_id": "Quarto interruttore riscaldatore",
|
||||||
"proportional_function": "Algoritmo",
|
"proportional_function": "Algoritmo",
|
||||||
"climate_entity_id": "Termostato sottostante"
|
"climate_entity_id": "Termostato sottostante",
|
||||||
|
"ac_mode": "AC mode ?"
|
||||||
},
|
},
|
||||||
"data_description": {
|
"data_description": {
|
||||||
"heater_entity_id": "Entity id obbligatoria del primo riscaldatore",
|
"heater_entity_id": "Entity id obbligatoria del primo riscaldatore",
|
||||||
@@ -169,7 +178,8 @@
|
|||||||
"heater_entity3_id": "Entity id del terzo riscaldatore facoltativo. Lasciare vuoto se non utilizzato",
|
"heater_entity3_id": "Entity id del terzo riscaldatore facoltativo. Lasciare vuoto se non utilizzato",
|
||||||
"heater_entity4_id": "Entity id del quarto riscaldatore facoltativo. Lasciare vuoto se non utilizzato",
|
"heater_entity4_id": "Entity id del quarto riscaldatore facoltativo. Lasciare vuoto se non utilizzato",
|
||||||
"proportional_function": "Algoritmo da utilizzare (il TPI per adesso è l'unico)",
|
"proportional_function": "Algoritmo da utilizzare (il TPI per adesso è l'unico)",
|
||||||
"climate_entity_id": "Entity id del termostato sottostante"
|
"climate_entity_id": "Entity id del termostato sottostante",
|
||||||
|
"ac_mode": "Utilizzare la modalità AC (Air Conditioned) ?"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tpi": {
|
"tpi": {
|
||||||
@@ -186,7 +196,10 @@
|
|||||||
"data": {
|
"data": {
|
||||||
"eco_temp": "Temperatura nel preset Eco",
|
"eco_temp": "Temperatura nel preset Eco",
|
||||||
"comfort_temp": "Temperatura nel preset Comfort",
|
"comfort_temp": "Temperatura nel preset Comfort",
|
||||||
"boost_temp": "Temperatura nel preset Boost"
|
"boost_temp": "Temperatura nel preset Boost",
|
||||||
|
"eco_ac_temp": "Temperatura nel preset Eco (AC mode)",
|
||||||
|
"comfort_ac_temp": "Temperatura nel preset Comfort (AC mode)",
|
||||||
|
"boost_ac_temp": "Temperatura nel preset Boost (AC mode)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"window": {
|
"window": {
|
||||||
@@ -233,7 +246,10 @@
|
|||||||
"presence_sensor_entity_id": "Entity id sensore presenza (true se è presente qualcuno)",
|
"presence_sensor_entity_id": "Entity id sensore presenza (true se è presente qualcuno)",
|
||||||
"eco_away_temp": "Temperatura al preset Eco in caso d'assenza",
|
"eco_away_temp": "Temperatura al preset Eco in caso d'assenza",
|
||||||
"comfort_away_temp": "Temperatura al preset Comfort in caso d'assenza",
|
"comfort_away_temp": "Temperatura al preset Comfort in caso d'assenza",
|
||||||
"boost_away_temp": "Temperatura al preset Boost in caso d'assenza"
|
"boost_away_temp": "Temperatura al preset Boost in caso d'assenza",
|
||||||
|
"eco_ac_away_temp": "Temperatura al preset Eco in caso d'assenza (AC mode)",
|
||||||
|
"comfort_ac_away_temp": "Temperatura al preset Comfort in caso d'assenza (AC mode)",
|
||||||
|
"boost_ac_away_temp": "Temperatura al preset Boost in caso d'assenza (AC mode)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"advanced": {
|
"advanced": {
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ class UnderlyingEntity:
|
|||||||
"""Set the target temperature"""
|
"""Set the target temperature"""
|
||||||
return
|
return
|
||||||
|
|
||||||
async def remove_entity(self):
|
def remove_entity(self):
|
||||||
"""Remove the underlying entity"""
|
"""Remove the underlying entity"""
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -180,7 +180,7 @@ class UnderlyingSwitch(UnderlyingEntity):
|
|||||||
if hvac_mode == HVACMode.OFF:
|
if hvac_mode == HVACMode.OFF:
|
||||||
if self.is_device_active:
|
if self.is_device_active:
|
||||||
await self.turn_off()
|
await self.turn_off()
|
||||||
await self._cancel_cycle()
|
self._cancel_cycle()
|
||||||
|
|
||||||
if self._hvac_mode != hvac_mode:
|
if self._hvac_mode != hvac_mode:
|
||||||
self._hvac_mode = hvac_mode
|
self._hvac_mode = hvac_mode
|
||||||
@@ -228,7 +228,7 @@ class UnderlyingSwitch(UnderlyingEntity):
|
|||||||
if self._async_cancel_cycle is not None:
|
if self._async_cancel_cycle is not None:
|
||||||
if force:
|
if force:
|
||||||
_LOGGER.debug("%s - we force a new cycle", self)
|
_LOGGER.debug("%s - we force a new cycle", self)
|
||||||
await self._cancel_cycle()
|
self._cancel_cycle()
|
||||||
else:
|
else:
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
"%s - A previous cycle is alredy running and no force -> waits for its end",
|
"%s - A previous cycle is alredy running and no force -> waits for its end",
|
||||||
@@ -258,7 +258,7 @@ class UnderlyingSwitch(UnderlyingEntity):
|
|||||||
else:
|
else:
|
||||||
_LOGGER.debug("%s - nothing to do", self)
|
_LOGGER.debug("%s - nothing to do", self)
|
||||||
|
|
||||||
async def _cancel_cycle(self):
|
def _cancel_cycle(self):
|
||||||
"""Cancel the cycle"""
|
"""Cancel the cycle"""
|
||||||
if self._async_cancel_cycle:
|
if self._async_cancel_cycle:
|
||||||
self._async_cancel_cycle()
|
self._async_cancel_cycle()
|
||||||
@@ -275,7 +275,7 @@ class UnderlyingSwitch(UnderlyingEntity):
|
|||||||
self._on_time_sec,
|
self._on_time_sec,
|
||||||
)
|
)
|
||||||
|
|
||||||
await self._cancel_cycle()
|
self._cancel_cycle()
|
||||||
|
|
||||||
if self._hvac_mode == HVACMode.OFF:
|
if self._hvac_mode == HVACMode.OFF:
|
||||||
_LOGGER.debug("%s - End of cycle (HVAC_MODE_OFF - 2)", self)
|
_LOGGER.debug("%s - End of cycle (HVAC_MODE_OFF - 2)", self)
|
||||||
@@ -327,7 +327,7 @@ class UnderlyingSwitch(UnderlyingEntity):
|
|||||||
self._should_relaunch_control_heating,
|
self._should_relaunch_control_heating,
|
||||||
self._off_time_sec,
|
self._off_time_sec,
|
||||||
)
|
)
|
||||||
await self._cancel_cycle()
|
self._cancel_cycle()
|
||||||
|
|
||||||
if self._hvac_mode == HVACMode.OFF:
|
if self._hvac_mode == HVACMode.OFF:
|
||||||
_LOGGER.debug("%s - End of cycle (HVAC_MODE_OFF - 2)", self)
|
_LOGGER.debug("%s - End of cycle (HVAC_MODE_OFF - 2)", self)
|
||||||
@@ -368,9 +368,9 @@ class UnderlyingSwitch(UnderlyingEntity):
|
|||||||
# increment energy at the end of the cycle
|
# increment energy at the end of the cycle
|
||||||
self._thermostat.incremente_energy()
|
self._thermostat.incremente_energy()
|
||||||
|
|
||||||
async def remove_entity(self):
|
def remove_entity(self):
|
||||||
"""Remove the entity"""
|
"""Remove the entity after stopping its cycle"""
|
||||||
await self._cancel_cycle()
|
self._cancel_cycle()
|
||||||
|
|
||||||
|
|
||||||
class UnderlyingClimate(UnderlyingEntity):
|
class UnderlyingClimate(UnderlyingEntity):
|
||||||
@@ -446,7 +446,7 @@ class UnderlyingClimate(UnderlyingEntity):
|
|||||||
def is_device_active(self):
|
def is_device_active(self):
|
||||||
"""If the toggleable device is currently active."""
|
"""If the toggleable device is currently active."""
|
||||||
if self.is_initialized:
|
if self.is_initialized:
|
||||||
return self._underlying_climate.hvac_action not in [
|
return self._underlying_climate.hvac_mode != HVACMode.OFF and self._underlying_climate.hvac_action not in [
|
||||||
HVACAction.IDLE,
|
HVACAction.IDLE,
|
||||||
HVACAction.OFF,
|
HVACAction.OFF,
|
||||||
]
|
]
|
||||||
@@ -581,8 +581,41 @@ class UnderlyingClimate(UnderlyingEntity):
|
|||||||
return self._underlying_climate.temperature_unit
|
return self._underlying_climate.temperature_unit
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def target_temperature_step(self) -> str:
|
def target_temperature_step(self) -> float:
|
||||||
"""Get the target_temperature_step"""
|
"""Get the target_temperature_step"""
|
||||||
if not self.is_initialized:
|
if not self.is_initialized:
|
||||||
return 1
|
return 1
|
||||||
return self._underlying_climate.target_temperature_step
|
return self._underlying_climate.target_temperature_step
|
||||||
|
|
||||||
|
@property
|
||||||
|
def target_temperature_high(self) -> float:
|
||||||
|
"""Get the target_temperature_high"""
|
||||||
|
if not self.is_initialized:
|
||||||
|
return 30
|
||||||
|
return self._underlying_climate.target_temperature_high
|
||||||
|
|
||||||
|
@property
|
||||||
|
def target_temperature_low(self) -> float:
|
||||||
|
"""Get the target_temperature_low"""
|
||||||
|
if not self.is_initialized:
|
||||||
|
return 15
|
||||||
|
return self._underlying_climate.target_temperature_low
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_aux_heat(self) -> bool:
|
||||||
|
"""Get the is_aux_heat"""
|
||||||
|
if not self.is_initialized:
|
||||||
|
return False
|
||||||
|
return self._underlying_climate.is_aux_heat
|
||||||
|
|
||||||
|
def turn_aux_heat_on(self) -> None:
|
||||||
|
"""Turn auxiliary heater on."""
|
||||||
|
if not self.is_initialized:
|
||||||
|
return None
|
||||||
|
return self._underlying_climate.turn_aux_heat_on()
|
||||||
|
|
||||||
|
def turn_aux_heat_off(self) -> None:
|
||||||
|
"""Turn auxiliary heater on."""
|
||||||
|
if not self.is_initialized:
|
||||||
|
return None
|
||||||
|
return self._underlying_climate.turn_aux_heat_off()
|
||||||
|
|||||||
Reference in New Issue
Block a user