From ac9a18ec7d5a11862af30b741552fff8571aa12e Mon Sep 17 00:00:00 2001 From: Jean-Marc Collin Date: Sun, 10 Dec 2023 10:18:51 +0000 Subject: [PATCH] Implementation ok --- .../versatile_thermostat/base_thermostat.py | 11 ++- .../versatile_thermostat/config_flow.py | 4 +- .../versatile_thermostat/const.py | 13 +++- .../versatile_thermostat/services.yaml | 1 + .../versatile_thermostat/strings.json | 31 ++++++++ .../versatile_thermostat/translations/el.json | 4 + .../versatile_thermostat/translations/en.json | 31 ++++++++ .../versatile_thermostat/translations/fr.json | 42 ++++++++++ .../versatile_thermostat/translations/it.json | 4 + .../versatile_thermostat/translations/sk.json | 4 + tests/const.py | 4 + tests/test_auto_regulation.py | 2 + tests/test_bugs.py | 1 + tests/test_security.py | 3 + tests/test_start.py | 5 ++ tests/test_switch_ac.py | 54 +++++++------ tests/test_valve.py | 78 ++++++++++++------- 17 files changed, 234 insertions(+), 58 deletions(-) diff --git a/custom_components/versatile_thermostat/base_thermostat.py b/custom_components/versatile_thermostat/base_thermostat.py index 3617145c..9b80c688 100644 --- a/custom_components/versatile_thermostat/base_thermostat.py +++ b/custom_components/versatile_thermostat/base_thermostat.py @@ -272,6 +272,9 @@ def post_init(self, entry_infos): ) self._ac_mode = entry_infos.get(CONF_AC_MODE) is True + self._attr_max_temp = entry_infos.get(CONF_TEMP_MAX) + self._attr_min_temp = entry_infos.get(CONF_TEMP_MIN) + # convert entry_infos into usable attributes presets = {} items = CONF_PRESETS_WITH_AC.items() if self._ac_mode else CONF_PRESETS.items() @@ -281,6 +284,9 @@ def post_init(self, entry_infos): presets[key] = entry_infos.get(value) else: _LOGGER.debug("value %s not found in Entry", value) + presets[key] = ( + self._attr_max_temp if self._ac_mode else self._attr_min_temp + ) presets_away = {} items = ( @@ -294,6 +300,9 @@ def post_init(self, entry_infos): presets_away[key] = entry_infos.get(value) else: _LOGGER.debug("value %s not found in Entry", value) + presets_away[key] = ( + self._attr_max_temp if self._ac_mode else self._attr_min_temp + ) if self._window_call_cancel is not None: self._window_call_cancel() @@ -310,8 +319,6 @@ def post_init(self, entry_infos): self._proportional_function = entry_infos.get(CONF_PROP_FUNCTION) self._temp_sensor_entity_id = entry_infos.get(CONF_TEMP_SENSOR) self._ext_temp_sensor_entity_id = entry_infos.get(CONF_EXTERNAL_TEMP_SENSOR) - self._attr_max_temp = entry_infos.get(CONF_TEMP_MAX) - self._attr_min_temp = entry_infos.get(CONF_TEMP_MIN) # Default value not configurable self._attr_target_temperature_step = 0.1 self._power_sensor_entity_id = entry_infos.get(CONF_POWER_SENSOR) diff --git a/custom_components/versatile_thermostat/config_flow.py b/custom_components/versatile_thermostat/config_flow.py index 5a6a0880..e29474b9 100644 --- a/custom_components/versatile_thermostat/config_flow.py +++ b/custom_components/versatile_thermostat/config_flow.py @@ -331,7 +331,7 @@ def __init__(self, infos) -> None: self.STEP_PRESETS_DATA_SCHEMA = vol.Schema( # pylint: disable=invalid-name { - vol.Optional(v, default=0.0): vol.Coerce(float) + vol.Optional(v, default=0): vol.Coerce(float) for (k, v) in CONF_PRESETS.items() } ) @@ -339,7 +339,7 @@ def __init__(self, infos) -> None: 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) + vol.Optional(v, default=0): vol.Coerce(float) for (k, v) in CONF_PRESETS_WITH_AC.items() } ) diff --git a/custom_components/versatile_thermostat/const.py b/custom_components/versatile_thermostat/const.py index 9e58a6fc..4b353a9f 100644 --- a/custom_components/versatile_thermostat/const.py +++ b/custom_components/versatile_thermostat/const.py @@ -29,6 +29,7 @@ PRESET_POWER = "power" PRESET_SECURITY = "security" +PRESET_FROST_PROTECTION = "frost" HIDDEN_PRESETS = [PRESET_POWER, PRESET_SECURITY] @@ -112,6 +113,7 @@ CONF_PRESETS = { p: f"{p}_temp" for p in ( + PRESET_FROST_PROTECTION, PRESET_ECO, PRESET_COMFORT, PRESET_BOOST, @@ -121,6 +123,7 @@ CONF_PRESETS_WITH_AC = { p: f"{p}_temp" for p in ( + PRESET_FROST_PROTECTION, PRESET_ECO, PRESET_COMFORT, PRESET_BOOST, @@ -136,6 +139,7 @@ CONF_PRESETS_AWAY = { p: f"{p}_temp" for p in ( + PRESET_FROST_PROTECTION + PRESET_AWAY_SUFFIX, PRESET_ECO + PRESET_AWAY_SUFFIX, PRESET_COMFORT + PRESET_AWAY_SUFFIX, PRESET_BOOST + PRESET_AWAY_SUFFIX, @@ -145,6 +149,7 @@ CONF_PRESETS_AWAY_WITH_AC = { p: f"{p}_temp" for p in ( + PRESET_FROST_PROTECTION + PRESET_AWAY_SUFFIX, PRESET_ECO + PRESET_AWAY_SUFFIX, PRESET_COMFORT + PRESET_AWAY_SUFFIX, PRESET_BOOST + PRESET_AWAY_SUFFIX, @@ -154,7 +159,12 @@ ) } -CONF_PRESETS_SELECTIONABLE = [PRESET_ECO, PRESET_COMFORT, PRESET_BOOST] +CONF_PRESETS_SELECTIONABLE = [ + PRESET_FROST_PROTECTION, + PRESET_ECO, + PRESET_COMFORT, + PRESET_BOOST, +] CONF_PRESETS_VALUES = list(CONF_PRESETS.values()) CONF_PRESETS_AWAY_VALUES = list(CONF_PRESETS_AWAY.values()) @@ -213,6 +223,7 @@ CONF_AUTO_REGULATION_DTEMP, CONF_AUTO_REGULATION_PERIOD_MIN, CONF_INVERSE_SWITCH, + CONF_AUTO_FAN_MODE, ] + CONF_PRESETS_VALUES + CONF_PRESETS_AWAY_VALUES diff --git a/custom_components/versatile_thermostat/services.yaml b/custom_components/versatile_thermostat/services.yaml index 54367797..81cda9f0 100644 --- a/custom_components/versatile_thermostat/services.yaml +++ b/custom_components/versatile_thermostat/services.yaml @@ -43,6 +43,7 @@ set_preset_temperature: - "eco" - "comfort" - "boost" + - "frost" - "eco_ac" - "comfort_ac" - "boost_ac" diff --git a/custom_components/versatile_thermostat/strings.json b/custom_components/versatile_thermostat/strings.json index 26294a58..ac00ca55 100644 --- a/custom_components/versatile_thermostat/strings.json +++ b/custom_components/versatile_thermostat/strings.json @@ -79,9 +79,19 @@ "title": "Presets", "description": "For each preset set the target temperature (0 to ignore preset)", "data": { + "eco_temp": "Eco preset", + "comfort_temp": "Comfort preset", + "boost_temp": "Boost preset", + "frost_temp": "Frost protection preset", + "eco_ac_temp": "Eco preset for AC mode", + "comfort_ac_temp": "Comfort preset for AC mode", + "boost_ac_temp": "Boost preset for AC mode" + }, + "data_description": { "eco_temp": "Temperature in Eco preset", "comfort_temp": "Temperature in Comfort preset", "boost_temp": "Temperature in Boost preset", + "frost_temp": "Temperature in Frost protection 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" @@ -136,10 +146,21 @@ "title": "Presence management", "description": "Presence management attributes.\nGives the a presence sensor of your home (true is someone is present).\nThen specify either the preset to use when presence sensor is false or the offset in temperature to apply.\nIf preset is given, the offset will not be used.\nLeave corresponding entity_id empty if not used.", "data": { + "presence_sensor_entity_id": "Presence sensor", + "eco_away_temp": "Eco preset", + "comfort_away_temp": "Comfort preset", + "boost_away_temp": "Boost preset", + "frost_away_temp": "Frost protection preset", + "eco_ac_away_temp": "Eco preset in AC mode", + "comfort_ac_away_temp": "Comfort preset in AC mode", + "boost_ac_away_temp": "Boost pres et in AC mode" + }, + "data_description": { "presence_sensor_entity_id": "Presence sensor entity id", "eco_away_temp": "Temperature in Eco preset when no presence", "comfort_away_temp": "Temperature in Comfort preset when no presence", "boost_away_temp": "Temperature in Boost preset when no presence", + "frost_away_temp": "Temperature in Frost protection 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" @@ -250,9 +271,19 @@ "title": "Presets", "description": "For each preset set the target temperature (0 to ignore preset)", "data": { + "eco_temp": "Eco preset", + "comfort_temp": "Comfort preset", + "boost_temp": "Boost preset", + "frost_temp": "Frost protection preset", + "eco_ac_temp": "Eco preset for AC mode", + "comfort_ac_temp": "Comfort preset for AC mode", + "boost_ac_temp": "Boost preset for AC mode" + }, + "data_description": { "eco_temp": "Temperature in Eco preset", "comfort_temp": "Temperature in Comfort preset", "boost_temp": "Temperature in Boost preset", + "frost_temp": "Temperature in Frost protection 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" diff --git a/custom_components/versatile_thermostat/translations/el.json b/custom_components/versatile_thermostat/translations/el.json index aa62c3d4..5de35f3d 100644 --- a/custom_components/versatile_thermostat/translations/el.json +++ b/custom_components/versatile_thermostat/translations/el.json @@ -82,6 +82,7 @@ "eco_temp": "Θερμοκρασία στο προκαθορισμένο Eco", "comfort_temp": "Θερμοκρασία στο προκαθορισμένο Comfort", "boost_temp": "Θερμοκρασία στο προκαθορισμένο Boost", + "frost_temp": "Θερμοκρασία στο προκαθορισμένο Frost protection", "eco_ac_temp": "Θερμοκρασία στο προκαθορισμένο Eco για λειτουργία AC", "comfort_ac_temp": "Θερμοκρασία στο προκαθορισμένο Comfort για λειτουργία AC", "boost_ac_temp": "Θερμοκρασία στο προκαθορισμένο Boost για λειτουργία AC" @@ -140,6 +141,7 @@ "eco_away_temp": "Θερμοκρασία στο προκαθορισμένο Eco όταν δεν υπάρχει παρουσία", "comfort_away_temp": "Θερμοκρασία στο προκαθορισμένο Comfort όταν δεν υπάρχει παρουσία", "boost_away_temp": "Θερμοκρασία στο προκαθορισμένο Boost όταν δεν υπάρχει παρουσία", + "frost_away_temp": "Θερμοκρασία στο προκαθορισμένο Frost protection όταν δεν υπάρχει παρουσία", "eco_ac_away_temp": "Θερμοκρασία στο προκαθορισμένο Eco όταν δεν υπάρχει παρουσία σε λειτουργία AC", "comfort_ac_away_temp": "Θερμοκρασία στο προκαθορισμένο Comfort όταν δεν υπάρχει παρουσία σε λειτουργία AC", "boost_ac_away_temp": "Θερμοκρασία στο προκαθορισμένο Boost όταν δεν υπάρχει παρουσία σε λειτουργία AC" @@ -253,6 +255,7 @@ "eco_temp": "Θερμοκρασία στην οικονομική προεπιλογή", "comfort_temp": "Θερμοκρασία στην άνετη προεπιλογή", "boost_temp": "Θερμοκρασία στην ενισχυμένη προεπιλογή", + "frost_temp": "Θερμοκρασία στο προκαθορισμένο Frost protection", "eco_ac_temp": "Θερμοκρασία στην οικονομική προεπιλογή για τη λειτουργία AC", "comfort_ac_temp": "Θερμοκρασία στην άνετη προεπιλογή για τη λειτουργία AC", "boost_ac_temp": "Θερμοκρασία στην ενισχυμένη προεπιλογή για τη λειτουργία AC" @@ -311,6 +314,7 @@ "eco_away_temp": "Θερμοκρασία στο πρόγραμμα Eco όταν δεν υπάρχει παρουσία", "comfort_away_temp": "Θερμοκρασία στο πρόγραμμα Comfort όταν δεν υπάρχει παρουσία", "boost_away_temp": "Θερμοκρασία στο πρόγραμμα Boost όταν δεν υπάρχει παρουσία", + "frost_away_temp": "Θερμοκρασία στο προκαθορισμένο Frost protection όταν δεν υπάρχει παρουσία", "eco_ac_away_temp": "Θερμοκρασία στο πρόγραμμα Eco όταν δεν υπάρχει παρουσία σε λειτουργία AC", "comfort_ac_away_temp": "Θερμοκρασία στο πρόγραμμα Comfort όταν δεν υπάρχει παρουσία σε λειτουργία AC", "boost_ac_away_temp": "Θερμοκρασία στο πρόγραμμα Boost όταν δεν υπάρχει παρουσία σε λειτουργία AC" diff --git a/custom_components/versatile_thermostat/translations/en.json b/custom_components/versatile_thermostat/translations/en.json index 26294a58..ac00ca55 100644 --- a/custom_components/versatile_thermostat/translations/en.json +++ b/custom_components/versatile_thermostat/translations/en.json @@ -79,9 +79,19 @@ "title": "Presets", "description": "For each preset set the target temperature (0 to ignore preset)", "data": { + "eco_temp": "Eco preset", + "comfort_temp": "Comfort preset", + "boost_temp": "Boost preset", + "frost_temp": "Frost protection preset", + "eco_ac_temp": "Eco preset for AC mode", + "comfort_ac_temp": "Comfort preset for AC mode", + "boost_ac_temp": "Boost preset for AC mode" + }, + "data_description": { "eco_temp": "Temperature in Eco preset", "comfort_temp": "Temperature in Comfort preset", "boost_temp": "Temperature in Boost preset", + "frost_temp": "Temperature in Frost protection 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" @@ -136,10 +146,21 @@ "title": "Presence management", "description": "Presence management attributes.\nGives the a presence sensor of your home (true is someone is present).\nThen specify either the preset to use when presence sensor is false or the offset in temperature to apply.\nIf preset is given, the offset will not be used.\nLeave corresponding entity_id empty if not used.", "data": { + "presence_sensor_entity_id": "Presence sensor", + "eco_away_temp": "Eco preset", + "comfort_away_temp": "Comfort preset", + "boost_away_temp": "Boost preset", + "frost_away_temp": "Frost protection preset", + "eco_ac_away_temp": "Eco preset in AC mode", + "comfort_ac_away_temp": "Comfort preset in AC mode", + "boost_ac_away_temp": "Boost pres et in AC mode" + }, + "data_description": { "presence_sensor_entity_id": "Presence sensor entity id", "eco_away_temp": "Temperature in Eco preset when no presence", "comfort_away_temp": "Temperature in Comfort preset when no presence", "boost_away_temp": "Temperature in Boost preset when no presence", + "frost_away_temp": "Temperature in Frost protection 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" @@ -250,9 +271,19 @@ "title": "Presets", "description": "For each preset set the target temperature (0 to ignore preset)", "data": { + "eco_temp": "Eco preset", + "comfort_temp": "Comfort preset", + "boost_temp": "Boost preset", + "frost_temp": "Frost protection preset", + "eco_ac_temp": "Eco preset for AC mode", + "comfort_ac_temp": "Comfort preset for AC mode", + "boost_ac_temp": "Boost preset for AC mode" + }, + "data_description": { "eco_temp": "Temperature in Eco preset", "comfort_temp": "Temperature in Comfort preset", "boost_temp": "Temperature in Boost preset", + "frost_temp": "Temperature in Frost protection 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" diff --git a/custom_components/versatile_thermostat/translations/fr.json b/custom_components/versatile_thermostat/translations/fr.json index e9c6263f..d574f8cd 100644 --- a/custom_components/versatile_thermostat/translations/fr.json +++ b/custom_components/versatile_thermostat/translations/fr.json @@ -79,9 +79,19 @@ "title": "Presets", "description": "Pour chaque preset, donnez la température cible (0 pour ignorer le preset)", "data": { + "eco_temp": "Preset Eco", + "comfort_temp": "Preset Comfort", + "boost_temp": "Preset Boost", + "frost_temp": "Preset Hors-gel", + "eco_ac_temp": "Preset Eco en mode AC", + "comfort_ac_temp": "Preset Comfort en mode AC", + "boost_ac_temp": "Preset Boost en mode AC" + }, + "data_description": { "eco_temp": "Température en preset Eco", "comfort_temp": "Température en preset Comfort", "boost_temp": "Température en preset Boost", + "frost_temp": "Température en preset Hors-gel", "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" @@ -136,10 +146,21 @@ "title": "Gestion de la présence", "description": "Donnez un capteur de présence (true si quelqu'un est présent).\nEnsuite spécifiez soit un preset à utiliser, soit un offset de température à appliquer lorsque personne n'est présent.\nSi le préset est utilisé, l'offset ne sera pas pris en compte.\nLaissez l'entity id vide si la gestion de la présence est non utilisée.", "data": { + "presence_sensor_entity_id": "Capteur de présence", + "eco_away_temp": "preset Eco", + "comfort_away_temp": "preset Comfort", + "boost_away_temp": "preset Boost", + "frost_away_temp": "preset Hors-gel", + "eco_ac_away_temp": "preset Eco en mode AC", + "comfort_ac_away_temp": "preset Comfort en mode AC", + "boost_ac_away_temp": "preset Boost en mode AC" + }, + "data_description": { "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", "comfort_away_temp": "Température en preset Comfort en cas d'absence", "boost_away_temp": "Température en preset Boost en cas d'absence", + "frost_away_temp": "Température en preset Hors-gel 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" @@ -251,9 +272,19 @@ "title": "Presets", "description": "Pour chaque preset, donnez la température cible (0 pour ignorer le preset)", "data": { + "eco_temp": "Preset Eco", + "comfort_temp": "Preset Comfort", + "boost_temp": "Preset Boost", + "frost_temp": "Preset Hors-gel", + "eco_ac_temp": "Preset Eco en mode AC", + "comfort_ac_temp": "Preset Comfort en mode AC", + "boost_ac_temp": "Preset Boost en mode AC" + }, + "data_description": { "eco_temp": "Température en preset Eco", "comfort_temp": "Température en preset Comfort", "boost_temp": "Température en preset Boost", + "frost_temp": "Température en preset Hors-gel", "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" @@ -308,10 +339,21 @@ "title": "Gestion de la présence", "description": "Donnez un capteur de présence (true si quelqu'un est présent).\nEnsuite spécifiez soit un preset à utiliser, soit un offset de température à appliquer lorsque personne n'est présent.\nSi le préset est utilisé, l'offset ne sera pas pris en compte.\nLaissez l'entity id vide si la gestion de la présence est non utilisée.", "data": { + "presence_sensor_entity_id": "Capteur de présence", + "eco_away_temp": "preset Eco", + "comfort_away_temp": "preset Comfort", + "boost_away_temp": "preset Boost", + "frost_away_temp": "preset Hors-gel", + "eco_ac_away_temp": "preset Eco en mode AC", + "comfort_ac_away_temp": "preset Comfort en mode AC", + "boost_ac_away_temp": "preset Boost en mode AC" + }, + "data_description": { "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", "comfort_away_temp": "Température en preset Comfort en cas d'absence", "boost_away_temp": "Température en preset Boost en cas d'absence", + "frost_away_temp": "Température en preset Hors-gel 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" diff --git a/custom_components/versatile_thermostat/translations/it.json b/custom_components/versatile_thermostat/translations/it.json index 12608d43..b209433e 100644 --- a/custom_components/versatile_thermostat/translations/it.json +++ b/custom_components/versatile_thermostat/translations/it.json @@ -78,6 +78,7 @@ "eco_temp": "Temperatura nel preset Eco", "comfort_temp": "Temperatura nel preset Comfort", "boost_temp": "Temperatura nel preset Boost", + "frost_temp": "Temperatura nel preset Frost protection", "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)" @@ -129,6 +130,7 @@ "eco_away_temp": "Temperatura al preset Eco 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", + "frost_away_temp": "Temperatura al preset Frost protection 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)" @@ -238,6 +240,7 @@ "eco_temp": "Temperatura nel preset Eco", "comfort_temp": "Temperatura nel preset Comfort", "boost_temp": "Temperatura nel preset Boost", + "frost_temp": "Temperatura nel preset Frost protection", "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)" @@ -289,6 +292,7 @@ "eco_away_temp": "Temperatura al preset Eco 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", + "frost_away_temp": "Temperatura al preset Frost protection 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)" diff --git a/custom_components/versatile_thermostat/translations/sk.json b/custom_components/versatile_thermostat/translations/sk.json index 154aec6c..1ff1280a 100644 --- a/custom_components/versatile_thermostat/translations/sk.json +++ b/custom_components/versatile_thermostat/translations/sk.json @@ -82,6 +82,7 @@ "eco_temp": "Teplota v predvoľbe Eco", "comfort_temp": "Prednastavená teplota v komfortnom režime", "boost_temp": "Teplota v prednastavení Boost", + "frost_temp": "Teplota v prednastavení Frost protection", "eco_ac_temp": "Teplota v režime Eco prednastavená pre režim AC", "comfort_ac_temp": "Teplota v režime Comfort je prednastavená pre režim AC", "boost_ac_temp": "Prednastavená teplota v režime Boost pre režim AC" @@ -140,6 +141,7 @@ "eco_away_temp": "Teplota v prednastavenej Eco, keď nie je žiadna prítomnosť", "comfort_away_temp": "Teplota v režime Comfort je prednastavená, keď nie je prítomný", "boost_away_temp": "Prednastavená teplota v režime Boost, keď nie je prítomný", + "frost_away_temp": "Prednastavená teplota v režime Frost protection, keď nie je prítomný", "eco_ac_away_temp": "Teplota v prednastavenej Eco, keď nie je prítomná v režime AC", "comfort_ac_away_temp": "Teplota v režime Comfort je prednastavená, keď nie je prítomný v režime AC", "boost_ac_away_temp": "Teplota v prednastavenom Boost, keď nie je prítomný v režime AC" @@ -253,6 +255,7 @@ "eco_temp": "Teplota v predvoľbe Eco", "comfort_temp": "Prednastavená teplota v komfortnom režime", "boost_temp": "Teplota v prednastavení Boost", + "frost_temp": "Teplota v prednastavení Frost protection", "eco_ac_temp": "Teplota v režime Eco prednastavená pre režim AC", "comfort_ac_temp": "Teplota v režime Comfort je prednastavená pre režim AC", "boost_ac_temp": "Prednastavená teplota v režime Boost pre režim AC" @@ -311,6 +314,7 @@ "eco_away_temp": "Teplota v prednastavenej Eco, keď nie je žiadna prítomnosť", "comfort_away_temp": "Teplota v režime Comfort je prednastavená, keď nie je prítomný", "boost_away_temp": "Prednastavená teplota v režime Boost, keď nie je prítomný", + "frost_away_temp": "Prednastavená teplota v režime Frost protection, keď nie je prítomný", "eco_ac_away_temp": "Teplota v prednastavenej Eco, keď nie je prítomná v režime AC", "comfort_ac_away_temp": "Teplota v režime Comfort je prednastavená, keď nie je prítomný v režime AC", "boost_ac_away_temp": "Teplota v prednastavenom Boost, keď nie je prítomný v režime AC" diff --git a/tests/const.py b/tests/const.py index 6cf6cb02..32a6d278 100644 --- a/tests/const.py +++ b/tests/const.py @@ -58,6 +58,7 @@ CONF_INVERSE_SWITCH, CONF_AUTO_FAN_HIGH, CONF_AUTO_FAN_MODE, + PRESET_FROST_PROTECTION, ) MOCK_TH_OVER_SWITCH_USER_CONFIG = { @@ -155,12 +156,14 @@ } MOCK_PRESETS_CONFIG = { + PRESET_FROST_PROTECTION + "_temp": 7, PRESET_ECO + "_temp": 16, PRESET_COMFORT + "_temp": 17, PRESET_BOOST + "_temp": 18, } MOCK_PRESETS_AC_CONFIG = { + PRESET_FROST_PROTECTION + "_temp": 7, PRESET_ECO + "_temp": 17, PRESET_COMFORT + "_temp": 19, PRESET_BOOST + "_temp": 20, @@ -203,6 +206,7 @@ MOCK_PRESENCE_AC_CONFIG = { CONF_PRESENCE_SENSOR: "person.presence_sensor", + PRESET_FROST_PROTECTION + PRESET_AWAY_SUFFIX + "_temp": 7, PRESET_ECO + PRESET_AWAY_SUFFIX + "_temp": 16, PRESET_COMFORT + PRESET_AWAY_SUFFIX + "_temp": 17, PRESET_BOOST + PRESET_AWAY_SUFFIX + "_temp": 18, diff --git a/tests/test_auto_regulation.py b/tests/test_auto_regulation.py index cce901a3..0c673d13 100644 --- a/tests/test_auto_regulation.py +++ b/tests/test_auto_regulation.py @@ -76,6 +76,7 @@ def find_my_entity(entity_id) -> ClimateEntity: assert entity.target_temperature == entity.min_temp assert entity.preset_modes == [ PRESET_NONE, + PRESET_FROST_PROTECTION, PRESET_ECO, PRESET_COMFORT, PRESET_BOOST, @@ -185,6 +186,7 @@ def find_my_entity(entity_id) -> ClimateEntity: assert entity.target_temperature == entity.max_temp assert entity.preset_modes == [ PRESET_NONE, + PRESET_FROST_PROTECTION, PRESET_ECO, PRESET_COMFORT, PRESET_BOOST, diff --git a/tests/test_bugs.py b/tests/test_bugs.py index efb59560..00b6facc 100644 --- a/tests/test_bugs.py +++ b/tests/test_bugs.py @@ -399,6 +399,7 @@ def find_my_entity(entity_id) -> ClimateEntity: assert entity.target_temperature == entity.min_temp assert entity.preset_modes == [ PRESET_NONE, + PRESET_FROST_PROTECTION, PRESET_ECO, PRESET_COMFORT, PRESET_BOOST, diff --git a/tests/test_security.py b/tests/test_security.py index 1ea8f6e9..9165198e 100644 --- a/tests/test_security.py +++ b/tests/test_security.py @@ -43,6 +43,7 @@ async def test_security_feature(hass: HomeAssistant, skip_hass_states_is_state): "cycle_min": 5, "temp_min": 15, "temp_max": 30, + "frost_temp": 7, "eco_temp": 17, "comfort_temp": 18, "boost_temp": 19, @@ -72,6 +73,7 @@ async def test_security_feature(hass: HomeAssistant, skip_hass_states_is_state): assert entity.preset_mode is not PRESET_SECURITY assert entity.preset_modes == [ PRESET_NONE, + PRESET_FROST_PROTECTION, PRESET_ECO, PRESET_COMFORT, PRESET_BOOST, @@ -444,6 +446,7 @@ def find_my_entity(entity_id) -> ClimateEntity: assert entity.target_temperature == entity.min_temp assert entity.preset_modes == [ PRESET_NONE, + PRESET_FROST_PROTECTION, PRESET_ECO, PRESET_COMFORT, PRESET_BOOST, diff --git a/tests/test_start.py b/tests/test_start.py index 5c1f73f1..70ad3b37 100644 --- a/tests/test_start.py +++ b/tests/test_start.py @@ -61,6 +61,7 @@ def find_my_entity(entity_id) -> ClimateEntity: assert entity.target_temperature == entity.min_temp assert entity.preset_modes == [ PRESET_NONE, + PRESET_FROST_PROTECTION, PRESET_ECO, PRESET_COMFORT, PRESET_BOOST, @@ -130,6 +131,7 @@ def find_my_entity(entity_id) -> ClimateEntity: assert entity.target_temperature == entity.min_temp assert entity.preset_modes == [ PRESET_NONE, + PRESET_FROST_PROTECTION, PRESET_ECO, PRESET_COMFORT, PRESET_BOOST, @@ -194,6 +196,7 @@ def find_my_entity(entity_id) -> ClimateEntity: assert entity.target_temperature == entity.min_temp assert entity.preset_modes == [ PRESET_NONE, + PRESET_FROST_PROTECTION, PRESET_ECO, PRESET_COMFORT, PRESET_BOOST, @@ -249,6 +252,7 @@ async def test_over_switch_deactivate_preset( CONF_CYCLE_MIN: 8, CONF_TEMP_MIN: 15, CONF_TEMP_MAX: 30, + "frost_temp": 0, "eco_temp": 17, "comfort_temp": 0, "boost_temp": 19, @@ -273,6 +277,7 @@ async def test_over_switch_deactivate_preset( assert entity.preset_modes == [ PRESET_NONE, + # PRESET_FROST_PROTECTION, PRESET_ECO, # PRESET_COMFORT, PRESET_BOOST, diff --git a/tests/test_switch_ac.py b/tests/test_switch_ac.py index 4694fdaf..3d4bb129 100644 --- a/tests/test_switch_ac.py +++ b/tests/test_switch_ac.py @@ -12,13 +12,18 @@ from pytest_homeassistant_custom_component.common import MockConfigEntry from custom_components.versatile_thermostat.base_thermostat import BaseThermostat -from custom_components.versatile_thermostat.thermostat_switch import ThermostatOverSwitch +from custom_components.versatile_thermostat.thermostat_switch import ( + ThermostatOverSwitch, +) from .commons import * # pylint: disable=wildcard-import, unused-wildcard-import + @pytest.mark.parametrize("expected_lingering_tasks", [True]) @pytest.mark.parametrize("expected_lingering_timers", [True]) -async def test_over_switch_ac_full_start(hass: HomeAssistant, skip_hass_states_is_state): # pylint: disable=unused-argument +async def test_over_switch_ac_full_start( + hass: HomeAssistant, skip_hass_states_is_state +): # pylint: disable=unused-argument """Test the normal full start of a thermostat in thermostat_over_switch type""" entry = MockConfigEntry( @@ -52,7 +57,7 @@ def find_my_entity(entity_id) -> ClimateEntity: assert isinstance(entity, ThermostatOverSwitch) assert entity.name == "TheOverSwitchMockName" - assert entity.is_over_climate is False # pylint: disable=protected-access + assert entity.is_over_climate is False # pylint: disable=protected-access assert entity.ac_mode is True assert entity.hvac_action is HVACAction.OFF assert entity.hvac_mode is HVACMode.OFF @@ -60,17 +65,18 @@ def find_my_entity(entity_id) -> ClimateEntity: assert entity.target_temperature == entity.max_temp assert entity.preset_modes == [ PRESET_NONE, + PRESET_FROST_PROTECTION, PRESET_ECO, PRESET_COMFORT, PRESET_BOOST, PRESET_ACTIVITY, ] assert entity.preset_mode is PRESET_NONE - assert entity._security_state is False # pylint: disable=protected-access - assert entity._window_state is None # pylint: disable=protected-access - assert entity._motion_state is None # pylint: disable=protected-access - assert entity._presence_state is None # pylint: disable=protected-access - assert entity._prop_algorithm is not None # pylint: disable=protected-access + assert entity._security_state is False # pylint: disable=protected-access + assert entity._window_state is None # pylint: disable=protected-access + assert entity._motion_state is None # pylint: disable=protected-access + assert entity._presence_state is None # pylint: disable=protected-access + assert entity._prop_algorithm is not None # pylint: disable=protected-access # should have been called with EventType.PRESET_EVENT and EventType.HVAC_MODE_EVENT assert mock_send_event.call_count == 2 @@ -91,7 +97,7 @@ def find_my_entity(entity_id) -> ClimateEntity: event_timestamp = now - timedelta(minutes=4) await send_presence_change_event(entity, True, False, event_timestamp) - assert entity._presence_state == STATE_ON # pylint: disable=protected-access + assert entity._presence_state == STATE_ON # pylint: disable=protected-access await entity.async_set_hvac_mode(HVACMode.COOL) assert entity.hvac_mode is HVACMode.COOL @@ -108,36 +114,39 @@ def find_my_entity(entity_id) -> ClimateEntity: # Unset the presence event_timestamp = now - timedelta(minutes=3) await send_presence_change_event(entity, False, True, event_timestamp) - assert entity._presence_state == STATE_OFF # pylint: disable=protected-access - assert entity.target_temperature == 27 # eco_ac_away + assert entity._presence_state == STATE_OFF # pylint: disable=protected-access + assert entity.target_temperature == 27 # eco_ac_away # Open a window - with patch( - "homeassistant.helpers.condition.state", return_value=True - ): + with patch("homeassistant.helpers.condition.state", return_value=True): event_timestamp = now - timedelta(minutes=2) - try_condition = await send_window_change_event(entity, True, False, event_timestamp) + try_condition = await send_window_change_event( + entity, True, False, event_timestamp + ) # Confirme the window event await try_condition(None) assert entity.hvac_mode is HVACMode.OFF assert entity.hvac_action is HVACAction.OFF - assert entity.target_temperature == 16 # eco_ac_away + assert entity.target_temperature == 16 # eco_ac_away # Close a window - with patch( - "homeassistant.helpers.condition.state", return_value=True - ): + with patch("homeassistant.helpers.condition.state", return_value=True): event_timestamp = now - timedelta(minutes=2) - try_condition = await send_window_change_event(entity, False, True, event_timestamp) + try_condition = await send_window_change_event( + entity, False, True, event_timestamp + ) # Confirme the window event await try_condition(None) assert entity.hvac_mode is HVACMode.COOL - assert (entity.hvac_action is HVACAction.OFF or entity.hvac_action is HVACAction.IDLE) - assert entity.target_temperature == 27 # eco_ac_away + assert ( + entity.hvac_action is HVACAction.OFF + or entity.hvac_action is HVACAction.IDLE + ) + assert entity.target_temperature == 27 # eco_ac_away await entity.async_set_hvac_mode(HVACMode.HEAT) assert entity.hvac_mode is HVACMode.HEAT @@ -156,4 +165,3 @@ def find_my_entity(entity_id) -> ClimateEntity: await entity.async_set_preset_mode(PRESET_BOOST) assert entity.preset_mode is PRESET_BOOST assert entity.target_temperature == 18 - diff --git a/tests/test_valve.py b/tests/test_valve.py index e3a0a7b7..63a30451 100644 --- a/tests/test_valve.py +++ b/tests/test_valve.py @@ -17,8 +17,11 @@ from .commons import * # pylint: disable=wildcard-import, unused-wildcard-import + @pytest.mark.parametrize("expected_lingering_timers", [True]) -async def test_over_valve_full_start(hass: HomeAssistant, skip_hass_states_is_state): # pylint: disable=unused-argument +async def test_over_valve_full_start( + hass: HomeAssistant, skip_hass_states_is_state +): # pylint: disable=unused-argument """Test the normal full start of a thermostat in thermostat_over_switch type""" entry = MockConfigEntry( @@ -34,6 +37,7 @@ async def test_over_valve_full_start(hass: HomeAssistant, skip_hass_states_is_st CONF_CYCLE_MIN: 5, CONF_TEMP_MIN: 15, CONF_TEMP_MAX: 30, + PRESET_FROST_PROTECTION + "_temp": 7, PRESET_ECO + "_temp": 17, PRESET_COMFORT + "_temp": 19, PRESET_BOOST + "_temp": 21, @@ -54,6 +58,7 @@ async def test_over_valve_full_start(hass: HomeAssistant, skip_hass_states_is_st CONF_POWER_SENSOR: "sensor.power_sensor", CONF_MAX_POWER_SENSOR: "sensor.power_max_sensor", CONF_PRESENCE_SENSOR: "person.presence_sensor", + PRESET_FROST_PROTECTION + PRESET_AWAY_SUFFIX + "_temp": 7, PRESET_ECO + PRESET_AWAY_SUFFIX + "_temp": 17.1, PRESET_COMFORT + PRESET_AWAY_SUFFIX + "_temp": 17.2, PRESET_BOOST + PRESET_AWAY_SUFFIX + "_temp": 17.3, @@ -62,7 +67,7 @@ async def test_over_valve_full_start(hass: HomeAssistant, skip_hass_states_is_st CONF_SECURITY_DELAY_MIN: 5, CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_DEVICE_POWER: 100, - CONF_AC_MODE: False + CONF_AC_MODE: False, }, ) @@ -100,17 +105,18 @@ def find_my_entity(entity_id) -> ClimateEntity: assert entity.target_temperature == entity.min_temp assert entity.preset_modes == [ PRESET_NONE, + PRESET_FROST_PROTECTION, PRESET_ECO, PRESET_COMFORT, PRESET_BOOST, PRESET_ACTIVITY, ] assert entity.preset_mode is PRESET_NONE - assert entity._security_state is False # pylint: disable=protected-access - assert entity._window_state is None # pylint: disable=protected-access - assert entity._motion_state is None # pylint: disable=protected-access - assert entity._presence_state is None # pylint: disable=protected-access - assert entity._prop_algorithm is not None # pylint: disable=protected-access + assert entity._security_state is False # pylint: disable=protected-access + assert entity._window_state is None # pylint: disable=protected-access + assert entity._motion_state is None # pylint: disable=protected-access + assert entity._presence_state is None # pylint: disable=protected-access + assert entity._prop_algorithm is not None # pylint: disable=protected-access # should have been called with EventType.PRESET_EVENT and EventType.HVAC_MODE_EVENT assert mock_send_event.call_count == 2 @@ -147,19 +153,19 @@ def find_my_entity(entity_id) -> ClimateEntity: # set manual target temp await entity.async_set_temperature(temperature=18) - assert entity.preset_mode == PRESET_NONE # Manual mode + assert entity.preset_mode == PRESET_NONE # Manual mode assert entity.target_temperature == 18 # Nothing have changed cause we don't have room and external temperature assert mock_send_event.call_count == 1 - # Set temperature and external temperature with patch( "custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event" ) as mock_send_event, patch( "homeassistant.core.ServiceRegistry.async_call" ) as mock_service_call, patch( - "homeassistant.core.StateMachine.get", return_value=State(entity_id="number.mock_valve", state="90") + "homeassistant.core.StateMachine.get", + return_value=State(entity_id="number.mock_valve", state="90"), ): # Change temperature event_timestamp = now - timedelta(minutes=10) @@ -172,10 +178,20 @@ def find_my_entity(entity_id) -> ClimateEntity: assert entity.hvac_action == HVACAction.HEATING assert mock_service_call.call_count == 2 - mock_service_call.assert_has_calls([ - call.async_call('number', 'set_value', {'entity_id': 'number.mock_valve', 'value': 90}), - call.async_call('number', 'set_value', {'entity_id': 'number.mock_valve', 'value': 98}) - ]) + mock_service_call.assert_has_calls( + [ + call.async_call( + "number", + "set_value", + {"entity_id": "number.mock_valve", "value": 90}, + ), + call.async_call( + "number", + "set_value", + {"entity_id": "number.mock_valve", "value": 98}, + ), + ] + ) assert mock_send_event.call_count == 0 @@ -190,10 +206,10 @@ def find_my_entity(entity_id) -> ClimateEntity: # Change presence to on event_timestamp = now - timedelta(minutes=4) await send_presence_change_event(entity, True, False, event_timestamp) - assert entity.presence_state == STATE_ON # pylint: disable=protected-access + assert entity.presence_state == STATE_ON # pylint: disable=protected-access assert entity.preset_mode is PRESET_COMFORT assert entity.target_temperature == 19 - assert entity.valve_open_percent == 100 # Full heating + assert entity.valve_open_percent == 100 # Full heating assert entity.is_device_active is True assert entity.hvac_action == HVACAction.HEATING @@ -211,7 +227,6 @@ def find_my_entity(entity_id) -> ClimateEntity: assert entity.is_device_active is False assert entity.hvac_action == HVACAction.IDLE - await send_temperature_change_event(entity, 17, datetime.now()) # switch to Eco await entity.async_set_preset_mode(PRESET_ECO) @@ -222,38 +237,41 @@ def find_my_entity(entity_id) -> ClimateEntity: # Unset the presence event_timestamp = now - timedelta(minutes=2) await send_presence_change_event(entity, False, True, event_timestamp) - assert entity.presence_state == STATE_OFF # pylint: disable=protected-access + assert entity.presence_state == STATE_OFF # pylint: disable=protected-access assert entity.valve_open_percent == 10 - assert entity.target_temperature == 17.1 # eco_away + assert entity.target_temperature == 17.1 # eco_away assert entity.is_device_active is True assert entity.hvac_action == HVACAction.HEATING # Open a window - with patch( - "homeassistant.helpers.condition.state", return_value=True - ): + with patch("homeassistant.helpers.condition.state", return_value=True): event_timestamp = now - timedelta(minutes=1) - try_condition = await send_window_change_event(entity, True, False, event_timestamp) + try_condition = await send_window_change_event( + entity, True, False, event_timestamp + ) # Confirme the window event await try_condition(None) assert entity.hvac_mode is HVACMode.OFF assert entity.hvac_action is HVACAction.OFF - assert entity.target_temperature == 17.1 # eco + assert entity.target_temperature == 17.1 # eco assert entity.valve_open_percent == 0 # Close a window - with patch( - "homeassistant.helpers.condition.state", return_value=True - ): + with patch("homeassistant.helpers.condition.state", return_value=True): event_timestamp = now - timedelta(minutes=0) - try_condition = await send_window_change_event(entity, False, True, event_timestamp) + try_condition = await send_window_change_event( + entity, False, True, event_timestamp + ) # Confirme the window event await try_condition(None) assert entity.hvac_mode is HVACMode.HEAT - assert (entity.hvac_action is HVACAction.OFF or entity.hvac_action is HVACAction.IDLE) - assert entity.target_temperature == 17.1 # eco + assert ( + entity.hvac_action is HVACAction.OFF + or entity.hvac_action is HVACAction.IDLE + ) + assert entity.target_temperature == 17.1 # eco assert entity.valve_open_percent == 10