Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c4fc976007 | |||
| 31d862acab | |||
| 9709a9eed0 | |||
| 61eae8c066 | |||
| e16daa3d53 | |||
| 90a6c926e3 | |||
| 64ce3aa0ad | |||
| 3f498ffbd3 | |||
| 3236be6c3b | |||
| be86fd3ac0 | |||
| e35ba57bd7 |
@@ -10,7 +10,7 @@ jobs:
|
|||||||
runs-on: "ubuntu-latest"
|
runs-on: "ubuntu-latest"
|
||||||
name: Validate
|
name: Validate
|
||||||
steps:
|
steps:
|
||||||
- uses: "actions/checkout@v2"
|
- uses: "actions/checkout@v3.5.2"
|
||||||
|
|
||||||
- name: HACS validation
|
- name: HACS validation
|
||||||
uses: "hacs/action@main"
|
uses: "hacs/action@main"
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
name: HACS Action
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
schedule:
|
||||||
|
- cron: "0 0 * * *"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
hacs:
|
||||||
|
name: HACS Action
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
steps:
|
||||||
|
- name: HACS Action
|
||||||
|
uses: "hacs/action@main"
|
||||||
|
with:
|
||||||
|
category: "integration"
|
||||||
@@ -8,7 +8,7 @@ jobs:
|
|||||||
runs-on: "ubuntu-latest"
|
runs-on: "ubuntu-latest"
|
||||||
name: Validate
|
name: Validate
|
||||||
steps:
|
steps:
|
||||||
- uses: "actions/checkout@v2"
|
- uses: "actions/checkout@v3.5.2"
|
||||||
|
|
||||||
- name: HACS validation
|
- name: HACS validation
|
||||||
uses: "hacs/action@main"
|
uses: "hacs/action@main"
|
||||||
@@ -23,8 +23,8 @@ jobs:
|
|||||||
runs-on: "ubuntu-latest"
|
runs-on: "ubuntu-latest"
|
||||||
name: Check style formatting
|
name: Check style formatting
|
||||||
steps:
|
steps:
|
||||||
- uses: "actions/checkout@v2"
|
- uses: "actions/checkout@v3.5.2"
|
||||||
- uses: "actions/setup-python@v1"
|
- uses: "actions/setup-python@v4.6.0"
|
||||||
with:
|
with:
|
||||||
python-version: "3.x"
|
python-version: "3.x"
|
||||||
- run: python3 -m pip install black
|
- run: python3 -m pip install black
|
||||||
@@ -35,9 +35,9 @@ jobs:
|
|||||||
name: Run tests
|
name: Run tests
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code from GitHub
|
- name: Check out code from GitHub
|
||||||
uses: "actions/checkout@v2"
|
uses: "actions/checkout@v3.5.2"
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: "actions/setup-python@v1"
|
uses: "actions/setup-python@v4.6.0"
|
||||||
with:
|
with:
|
||||||
python-version: "3.8"
|
python-version: "3.8"
|
||||||
- name: Install requirements
|
- name: Install requirements
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ jobs:
|
|||||||
runs-on: "ubuntu-latest"
|
runs-on: "ubuntu-latest"
|
||||||
name: Validate
|
name: Validate
|
||||||
steps:
|
steps:
|
||||||
- uses: "actions/checkout@v2"
|
- uses: "actions/checkout@v3.5.2"
|
||||||
|
|
||||||
- name: HACS validation
|
- name: HACS validation
|
||||||
uses: "hacs/action@main"
|
uses: "hacs/action@main"
|
||||||
@@ -26,8 +26,8 @@ jobs:
|
|||||||
runs-on: "ubuntu-latest"
|
runs-on: "ubuntu-latest"
|
||||||
name: Check style formatting
|
name: Check style formatting
|
||||||
steps:
|
steps:
|
||||||
- uses: "actions/checkout@v2"
|
- uses: "actions/checkout@v3.5.2"
|
||||||
- uses: "actions/setup-python@v1"
|
- uses: "actions/setup-python@v4.6.0"
|
||||||
with:
|
with:
|
||||||
python-version: "3.x"
|
python-version: "3.x"
|
||||||
- run: python3 -m pip install black
|
- run: python3 -m pip install black
|
||||||
|
|||||||
+1
-1
@@ -62,7 +62,7 @@ Ce composant personnalisé pour Home Assistant est une mise à niveau et est une
|
|||||||
> * **release majeure 2.0** : ajout du thermostat "over climate" permettant de transformer n'importe quel thermostat en Versatile Thermostat et lui ajouter toutes les fonctions de ce dernier.
|
> * **release majeure 2.0** : ajout du thermostat "over climate" permettant de transformer n'importe quel thermostat en Versatile Thermostat et lui ajouter toutes les fonctions de ce dernier.
|
||||||
|
|
||||||
# Merci pour la bière [buymecoffee](https://www.buymeacoffee.com/jmcollin78)
|
# Merci pour la bière [buymecoffee](https://www.buymeacoffee.com/jmcollin78)
|
||||||
Un grand merci à @salabur pour la bière. Ca fait très plaisir.
|
Un grand merci à @salabur, @pvince83 and @bergoglio pour les bières. Ca fait très plaisir.
|
||||||
|
|
||||||
|
|
||||||
# Quand l'utiliser et ne pas l'utiliser
|
# Quand l'utiliser et ne pas l'utiliser
|
||||||
|
|||||||
@@ -61,7 +61,8 @@ This custom component for Home Assistant is an upgrade and is a complete rewrite
|
|||||||
> * **major release 2.0**: addition of the "over climate" thermostat allowing you to transform any thermostat into a Versatile Thermostat and add all the functions of the latter.
|
> * **major release 2.0**: addition of the "over climate" thermostat allowing you to transform any thermostat into a Versatile Thermostat and add all the functions of the latter.
|
||||||
|
|
||||||
# Thanks for the beer [buymecoffee](https://www.buymeacoffee.com/jmcollin78)
|
# Thanks for the beer [buymecoffee](https://www.buymeacoffee.com/jmcollin78)
|
||||||
Many thanks to @salabur for the beer. It's very pleasing. (Vielen Dank an @salabur für das Bier. Es ist sehr erfreulich.)
|
Many thanks to @salabur, @pvince83 and @bergoglio for the beers. It's very pleasing.
|
||||||
|
|
||||||
|
|
||||||
# When to use / not use
|
# When to use / not use
|
||||||
This thermostat can control 2 types of equipment:
|
This thermostat can control 2 types of equipment:
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ fi
|
|||||||
if [ "$command" == "hassfest" ]; then
|
if [ "$command" == "hassfest" ]; then
|
||||||
echo "Running container start"
|
echo "Running container start"
|
||||||
python3 -m script.hassfest
|
python3 -m script.hassfest
|
||||||
|
# python -m script.hassfest --requirements --action validate --integration-path config/custom_components/versatile_thermostat/
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$command" == "restart" ]; then
|
if [ "$command" == "restart" ]; then
|
||||||
|
|||||||
@@ -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,10 +406,10 @@ 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
|
||||||
# Will be restored if possible
|
# Will be restored if possible
|
||||||
@@ -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"""
|
||||||
@@ -1191,7 +1199,7 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
|
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
async def async_set_hvac_mode(self, hvac_mode):
|
async def async_set_hvac_mode(self, hvac_mode, need_control_heating=True):
|
||||||
"""Set new target hvac mode."""
|
"""Set new target hvac mode."""
|
||||||
_LOGGER.info("%s - Set hvac mode: %s", self, hvac_mode)
|
_LOGGER.info("%s - Set hvac mode: %s", self, hvac_mode)
|
||||||
|
|
||||||
@@ -1201,13 +1209,13 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
self._hvac_mode = hvac_mode
|
self._hvac_mode = hvac_mode
|
||||||
|
|
||||||
# Delegate to all underlying
|
# Delegate to all underlying
|
||||||
need_control_heating = False
|
sub_need_control_heating = False
|
||||||
for under in self._underlyings:
|
for under in self._underlyings:
|
||||||
need_control_heating = (
|
sub_need_control_heating = (
|
||||||
await under.set_hvac_mode(hvac_mode) or need_control_heating
|
await under.set_hvac_mode(hvac_mode) or need_control_heating
|
||||||
)
|
)
|
||||||
|
|
||||||
if 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)
|
||||||
|
|
||||||
# Ensure we update the current operation after changing the mode
|
# Ensure we update the current operation after changing the mode
|
||||||
@@ -1286,13 +1294,18 @@ 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 [
|
|
||||||
STATE_ON,
|
|
||||||
STATE_HOME,
|
|
||||||
]:
|
|
||||||
return self._presets[preset_mode]
|
|
||||||
else:
|
else:
|
||||||
return self._presets_away[self.get_preset_away_name(preset_mode)]
|
# 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_HOME,
|
||||||
|
]:
|
||||||
|
return self._presets[preset_mode]
|
||||||
|
else:
|
||||||
|
return self._presets_away[self.get_preset_away_name(preset_mode)]
|
||||||
|
|
||||||
def get_preset_away_name(self, preset_mode):
|
def get_preset_away_name(self, preset_mode):
|
||||||
"""Get the preset name in away mode (when presence is off)"""
|
"""Get the preset name in away mode (when presence is off)"""
|
||||||
@@ -1452,7 +1465,7 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
self,
|
self,
|
||||||
self._saved_hvac_mode,
|
self._saved_hvac_mode,
|
||||||
)
|
)
|
||||||
await self.restore_hvac_mode()
|
await self.restore_hvac_mode(True)
|
||||||
elif self._window_state == STATE_ON:
|
elif self._window_state == STATE_ON:
|
||||||
_LOGGER.info(
|
_LOGGER.info(
|
||||||
"%s - Window is open. Set hvac_mode to '%s'", self, HVACMode.OFF
|
"%s - Window is open. Set hvac_mode to '%s'", self, HVACMode.OFF
|
||||||
@@ -1578,7 +1591,7 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
)
|
)
|
||||||
|
|
||||||
_LOGGER.info(
|
_LOGGER.info(
|
||||||
"%s - Underlying climate changed. Event.new_state is %s, hvac_mode=%s, hvac_action=%s, old_hvac_action=%s",
|
"%s - Underlying climate changed. Event.new_state is %s, current_hvac_mode=%s, new_hvac_action=%s, old_hvac_action=%s",
|
||||||
self,
|
self,
|
||||||
new_state,
|
new_state,
|
||||||
self._hvac_mode,
|
self._hvac_mode,
|
||||||
@@ -1857,7 +1870,7 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
)
|
)
|
||||||
# Set attributes
|
# Set attributes
|
||||||
self._window_auto_state = False
|
self._window_auto_state = False
|
||||||
await self.restore_hvac_mode()
|
await self.restore_hvac_mode(True)
|
||||||
|
|
||||||
if self._window_call_cancel:
|
if self._window_call_cancel:
|
||||||
self._window_call_cancel()
|
self._window_call_cancel()
|
||||||
@@ -1953,9 +1966,9 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
self._hvac_mode,
|
self._hvac_mode,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def restore_hvac_mode(self):
|
async def restore_hvac_mode(self, need_control_heating=False):
|
||||||
"""Restore a previous hvac_mod"""
|
"""Restore a previous hvac_mod"""
|
||||||
await self.async_set_hvac_mode(self._saved_hvac_mode)
|
await self.async_set_hvac_mode(self._saved_hvac_mode, need_control_heating)
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
"%s - Restored hvac_mode - saved_hvac_mode is %s, hvac_mode is %s",
|
"%s - Restored hvac_mode - saved_hvac_mode is %s, hvac_mode is %s",
|
||||||
self,
|
self,
|
||||||
@@ -2025,7 +2038,7 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
self._saved_preset_mode,
|
self._saved_preset_mode,
|
||||||
)
|
)
|
||||||
if self._is_over_climate:
|
if self._is_over_climate:
|
||||||
await self.restore_hvac_mode()
|
await self.restore_hvac_mode(False)
|
||||||
await self.restore_preset_mode()
|
await self.restore_preset_mode()
|
||||||
self.send_event(
|
self.send_event(
|
||||||
EventType.POWER_EVENT,
|
EventType.POWER_EVENT,
|
||||||
@@ -2050,7 +2063,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
|
||||||
@@ -2127,7 +2143,7 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
await self._async_set_preset_mode_internal(PRESET_SECURITY)
|
await self._async_set_preset_mode_internal(PRESET_SECURITY)
|
||||||
# Turn off the underlying climate or heater if security default on_percent is 0
|
# 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:
|
if self._is_over_climate or self._security_default_on_percent <= 0.0:
|
||||||
await self.async_set_hvac_mode(HVACMode.OFF)
|
await self.async_set_hvac_mode(HVACMode.OFF, False)
|
||||||
if self._prop_algorithm:
|
if self._prop_algorithm:
|
||||||
self._prop_algorithm.set_security(self._security_default_on_percent)
|
self._prop_algorithm.set_security(self._security_default_on_percent)
|
||||||
|
|
||||||
@@ -2161,7 +2177,7 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
self._security_state = ret
|
self._security_state = ret
|
||||||
# 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()
|
await self.restore_hvac_mode(False)
|
||||||
await self.restore_preset_mode()
|
await self.restore_preset_mode()
|
||||||
if self._prop_algorithm:
|
if self._prop_algorithm:
|
||||||
self._prop_algorithm.unset_security()
|
self._prop_algorithm.unset_security()
|
||||||
@@ -2294,6 +2310,8 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
|
|||||||
self.get_preset_away_name(PRESET_COMFORT)
|
self.get_preset_away_name(PRESET_COMFORT)
|
||||||
),
|
),
|
||||||
"power_temp": self._power_temp,
|
"power_temp": self._power_temp,
|
||||||
|
"target_temp": self.target_temperature,
|
||||||
|
"current_temp": self._cur_temp,
|
||||||
"ext_current_temperature": self._cur_ext_temp,
|
"ext_current_temperature": self._cur_ext_temp,
|
||||||
"current_power": self._current_power,
|
"current_power": self._current_power,
|
||||||
"current_power_max": self._current_power_max,
|
"current_power_max": self._current_power_max,
|
||||||
|
|||||||
@@ -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[CONF_AC_MODE]:
|
||||||
|
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[CONF_AC_MODE]:
|
||||||
"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[CONF_AC_MODE]:
|
||||||
|
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 +1,2 @@
|
|||||||
homeassistant
|
homeassistant
|
||||||
|
ffmpeg
|
||||||
@@ -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": {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
from unittest.mock import patch, MagicMock
|
from unittest.mock import patch, MagicMock
|
||||||
import pytest
|
import pytest # pylint: disable=unused-import
|
||||||
|
|
||||||
from homeassistant.core import HomeAssistant, Event, EVENT_STATE_CHANGED, State
|
from homeassistant.core import HomeAssistant, Event, EVENT_STATE_CHANGED, State
|
||||||
from homeassistant.const import UnitOfTemperature, STATE_ON, STATE_OFF
|
from homeassistant.const import UnitOfTemperature, STATE_ON, STATE_OFF
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ from homeassistant.components.binary_sensor import BinarySensorDeviceClass
|
|||||||
|
|
||||||
from pytest_homeassistant_custom_component.common import MockConfigEntry
|
from pytest_homeassistant_custom_component.common import MockConfigEntry
|
||||||
|
|
||||||
from .commons import *
|
from .commons import * # pylint: disable=wildcard-import, unused-wildcard-import
|
||||||
from ..climate import VersatileThermostat
|
from ..climate import VersatileThermostat
|
||||||
from ..binary_sensor import (
|
from ..binary_sensor import (
|
||||||
SecurityBinarySensor,
|
SecurityBinarySensor,
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
@@ -167,6 +167,7 @@ class UnderlyingSwitch(UnderlyingEntity):
|
|||||||
self._should_relaunch_control_heating = False
|
self._should_relaunch_control_heating = False
|
||||||
self._on_time_sec = 0
|
self._on_time_sec = 0
|
||||||
self._off_time_sec = 0
|
self._off_time_sec = 0
|
||||||
|
self._hvac_mode = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def initial_delay_sec(self):
|
def initial_delay_sec(self):
|
||||||
@@ -174,12 +175,18 @@ class UnderlyingSwitch(UnderlyingEntity):
|
|||||||
return self._initial_delay_sec
|
return self._initial_delay_sec
|
||||||
|
|
||||||
async def set_hvac_mode(self, hvac_mode: HVACMode) -> bool:
|
async def set_hvac_mode(self, hvac_mode: HVACMode) -> bool:
|
||||||
"""Set the HVACmode. Returns true if we need to redo a control_heating"""
|
"""Set the HVACmode. Returns true if something have change"""
|
||||||
|
|
||||||
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()
|
await self._cancel_cycle()
|
||||||
return True
|
|
||||||
|
if self._hvac_mode != hvac_mode:
|
||||||
|
self._hvac_mode = hvac_mode
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_device_active(self):
|
def is_device_active(self):
|
||||||
@@ -221,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",
|
||||||
@@ -251,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()
|
||||||
@@ -361,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):
|
||||||
@@ -421,10 +428,10 @@ class UnderlyingClimate(UnderlyingEntity):
|
|||||||
"""True if the underlying climate was found"""
|
"""True if the underlying climate was found"""
|
||||||
return self._underlying_climate is not None
|
return self._underlying_climate is not None
|
||||||
|
|
||||||
async def set_hvac_mode(self, hvac_mode: HVACMode):
|
async def set_hvac_mode(self, hvac_mode: HVACMode) -> bool:
|
||||||
"""Set the HVACmode of the underlying climate"""
|
"""Set the HVACmode of the underlying climate. Returns true if something have change"""
|
||||||
if not self.is_initialized:
|
if not self.is_initialized:
|
||||||
return
|
return False
|
||||||
|
|
||||||
data = {ATTR_ENTITY_ID: self._entity_id, "hvac_mode": hvac_mode}
|
data = {ATTR_ENTITY_ID: self._entity_id, "hvac_mode": hvac_mode}
|
||||||
await self._hass.services.async_call(
|
await self._hass.services.async_call(
|
||||||
@@ -433,6 +440,8 @@ class UnderlyingClimate(UnderlyingEntity):
|
|||||||
data,
|
data,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_device_active(self):
|
def is_device_active(self):
|
||||||
"""If the toggleable device is currently active."""
|
"""If the toggleable device is currently active."""
|
||||||
@@ -572,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