From 1797332908695a795a9201b4fd9af9affa586dfd Mon Sep 17 00:00:00 2001 From: KartoffelToby Date: Fri, 22 Sep 2023 20:06:12 +0200 Subject: [PATCH] [TASK] main implmentation --- .devcontainer/configuration.yaml | 13 +++- .../better_thermostat/config_flow.py | 6 +- .../better_thermostat/events/cooler.py | 8 ++- .../better_thermostat/events/trv.py | 16 +++-- .../better_thermostat/utils/controlling.py | 64 +++++++++++++++++++ 5 files changed, 96 insertions(+), 11 deletions(-) diff --git a/.devcontainer/configuration.yaml b/.devcontainer/configuration.yaml index e8034729..c8fccd78 100644 --- a/.devcontainer/configuration.yaml +++ b/.devcontainer/configuration.yaml @@ -28,8 +28,8 @@ climate: - platform: generic_thermostat name: Dummy_real_AC - heater: input_boolean.heater2 - target_sensor: input_number.internal_sensor2 + heater: input_boolean.cooler + target_sensor: input_number.internal_sensor3 ac_mode: true cold_tolerance: 0.3 @@ -40,6 +40,9 @@ input_boolean: heater2: name: Heater2 initial: on + cooler: + name: Cooler + initial: on window_open: name: Window open initial: off @@ -57,6 +60,12 @@ input_number: max: 35 step: 0.1 initial: 20 + internal_sensor3: + name: Internal Sensor2 + min: 5 + max: 35 + step: 0.1 + initial: 20 external_sensor: name: External Sensor initial: 18.2 diff --git a/custom_components/better_thermostat/config_flow.py b/custom_components/better_thermostat/config_flow.py index 13bc2489..47c55855 100644 --- a/custom_components/better_thermostat/config_flow.py +++ b/custom_components/better_thermostat/config_flow.py @@ -305,7 +305,7 @@ async def async_step_user(self, user_input=None): vol.Required(CONF_HEATER): selector.EntitySelector( selector.EntitySelectorConfig(domain="climate", multiple=True) ), - vol.Required(CONF_COOLER): selector.EntitySelector( + vol.Optional(CONF_COOLER): selector.EntitySelector( selector.EntitySelectorConfig(domain="climate", multiple=False) ), vol.Required(CONF_SENSOR): selector.EntitySelector( @@ -353,7 +353,7 @@ async def async_step_user(self, user_input=None): ): int, vol.Optional( CONF_TOLERANCE, default=user_input.get(CONF_TOLERANCE, 0.0) - ): float, + ): vol.All(vol.Coerce(float), vol.Range(min=0)), } ), errors=errors, @@ -682,7 +682,7 @@ async def async_step_user(self, user_input=None): vol.Optional( CONF_TOLERANCE, default=self.config_entry.data.get(CONF_TOLERANCE, 0.0) ) - ] = float + ] = vol.All(vol.Coerce(float), vol.Range(min=0)) return self.async_show_form( step_id="user", data_schema=vol.Schema(fields), last_step=False diff --git a/custom_components/better_thermostat/events/cooler.py b/custom_components/better_thermostat/events/cooler.py index a1ec71ae..9595ab81 100644 --- a/custom_components/better_thermostat/events/cooler.py +++ b/custom_components/better_thermostat/events/cooler.py @@ -46,13 +46,17 @@ async def trigger_cooler_change(self, event): _LOGGER.debug(f"better_thermostat {self.name}: Cooler {entity_id} update received") + _main_key = "temperature" + if "temperature" not in old_state.attributes: + _main_key = "target_temp_high" + _old_cooling_setpoint = convert_to_float( - str(old_state.attributes.get("temperature", None)), + str(old_state.attributes.get(_main_key, None)), self.name, "trigger_cooler_change()", ) _new_cooling_setpoint = convert_to_float( - str(new_state.attributes.get("temperature", None)), + str(new_state.attributes.get(_main_key, None)), self.name, "trigger_cooler_change()", ) diff --git a/custom_components/better_thermostat/events/trv.py b/custom_components/better_thermostat/events/trv.py index f6e6739e..60ef0c2d 100644 --- a/custom_components/better_thermostat/events/trv.py +++ b/custom_components/better_thermostat/events/trv.py @@ -134,13 +134,17 @@ async def trigger_trv_change(self, event): ): self.bt_hvac_mode = mapped_state + _main_key = "temperature" + if "temperature" not in old_state.attributes: + _main_key = "target_temp_high" + _old_heating_setpoint = convert_to_float( - str(old_state.attributes.get("temperature", None)), + str(old_state.attributes.get(_main_key, None)), self.name, "trigger_trv_change()", ) _new_heating_setpoint = convert_to_float( - str(new_state.attributes.get("temperature", None)), + str(new_state.attributes.get(_main_key, None)), self.name, "trigger_trv_change()", ) @@ -181,8 +185,12 @@ async def trigger_trv_change(self, event): self.bt_target_temp = _new_heating_setpoint if self.cooler_entity_id is not None: if self.bt_target_temp <= self.bt_target_cooltemp: - self.bt_target_temp = ( - self.bt_target_cooltemp + self.bt_target_temp_step + self.bt_target_cooltemp = ( + self.bt_target_temp - self.bt_target_temp_step + ) + if self.bt_target_temp >= self.bt_target_cooltemp: + self.bt_target_cooltemp = ( + self.bt_target_temp - self.bt_target_temp_step ) _main_change = True diff --git a/custom_components/better_thermostat/utils/controlling.py b/custom_components/better_thermostat/utils/controlling.py index 76dbfd5f..01894906 100644 --- a/custom_components/better_thermostat/utils/controlling.py +++ b/custom_components/better_thermostat/utils/controlling.py @@ -106,6 +106,70 @@ async def control_trv(self, heater_entity_id=None): _new_hvac_mode = handle_window_open(self, _remapped_states) + # New cooler section + if self.cooler_entity_id is not None: + if ( + self.cur_temp >= self.bt_target_cooltemp - self.tolerance + and _new_hvac_mode is not HVACMode.OFF + and self.cur_temp > self.bt_target_temp + ): + await self.hass.services.async_call( + "climate", + "set_temperature", + { + "entity_id": self.cooler_entity_id, + "temperature": self.bt_target_cooltemp, + }, + blocking=True, + context=self.context, + ) + await self.hass.services.async_call( + "climate", + "set_hvac_mode", + {"entity_id": self.cooler_entity_id, "hvac_mode": HVACMode.COOL}, + blocking=True, + context=self.context, + ) + elif ( + self.cur_temp < self.bt_target_cooltemp - self.tolerance + and _new_hvac_mode is not HVACMode.OFF + ): + await self.hass.services.async_call( + "climate", + "set_temperature", + { + "entity_id": self.cooler_entity_id, + "temperature": self.bt_target_cooltemp, + }, + blocking=True, + context=self.context, + ) + await self.hass.services.async_call( + "climate", + "set_hvac_mode", + {"entity_id": self.cooler_entity_id, "hvac_mode": HVACMode.OFF}, + blocking=True, + context=self.context, + ) + else: + await self.hass.services.async_call( + "climate", + "set_temperature", + { + "entity_id": self.cooler_entity_id, + "temperature": self.bt_target_cooltemp, + }, + blocking=True, + context=self.context, + ) + await self.hass.services.async_call( + "climate", + "set_hvac_mode", + {"entity_id": self.cooler_entity_id, "hvac_mode": HVACMode.OFF}, + blocking=True, + context=self.context, + ) + # if we don't need ot heat, we force HVACMode to be off if self.call_for_heat is False: _new_hvac_mode = HVACMode.OFF