RubenKelevra / Tuya-thermostatic-valve

TuYa TS0601: Home Assistant automation for more accurate temperature control leveraging an external temperature sensor
GNU Affero General Public License v3.0
21 stars 1 forks source link
heating heating-control heating-controller home-assistant home-automation homeassistant sensor temperature temperature-control temperature-sensor thermostat thermostat-controller trv tuya tuya-devices tuya-smart

Tuya-thermostatic-valve

automation documentation for better temperture control, with an external temperature probe / window contact

prerequisites

recommended mods

limitations

helpers

Create the following helpers:

- `input_select.heating_mode_kitchen` with 3 values: `default`, `off` and `cut` - `input_boolean.heatsource_present_kitchen` - `input_boolean.heating_maintaince_kitchen` - `input_select.heating_forced_off_weather` with 3 values: `no`, `no-heating-required`, `hot-day` - `input_boolean.heating_kitchen` - `input_number.target_temp_kitchen` with step size 0.5 and ℃ as unit

Warning: Only manually modify the last two manually, the rest is to store the status of the automations.

expected naming of sensors/actuators

statistics sensors

heat source detection

This automatisms is an example how to detect a running stove or a heat generateing device early, to avoid running the heat at the same timewhile those devices are running. This way you can avoid venting the room in some cases, when it would become too hot otherwise.

Detection with just the temperature probe is too delayed in most cases to help much.

```yaml alias: 'Heating: Detect heat source - Kitchen' description: '' trigger: - type: power platform: device entity_id: sensor.power_plug_airfryer_power domain: sensor above: 100 - type: power platform: device entity_id: sensor.power_plug_exhaust_hood_power domain: sensor above: 2 condition: - condition: or conditions: - type: is_power condition: device entity_id: sensor.power_plug_airfryer_power domain: sensor above: 100 - type: is_power condition: device entity_id: sensor.power_plug_exhaust_hood_power domain: sensor above: 2 action: - service: input_boolean.turn_on data: {} entity_id: input_boolean.heatsource_present_kitchen mode: queued max: 10 ``` ```yaml alias: 'Heating: Detect heat source gone - Kitchen' description: '' trigger: - type: power platform: device entity_id: sensor.power_plug_airfryer_power domain: sensor below: 100 for: minutes: 5 - type: power platform: device entity_id: sensor.power_plug_exhaust_hood_power domain: sensor below: 3 for: minutes: 5 condition: - condition: and conditions: - type: is_power condition: device entity_id: sensor.power_plug_airfryer_power domain: sensor below: 100 - type: is_power condition: device entity_id: sensor.power_plug_exhaust_hood_power domain: sensor below: 3 - condition: state entity_id: input_boolean.heatsource_present_kitchen state: 'on' action: - service: input_boolean.turn_off data: {} entity_id: input_boolean.heatsource_present_kitchen mode: queued max: 10 ```

heat mode automation

This automatisms shuts the valves in all scenarios where this is commanded by other automatisms or by the user.

```yaml alias: 'Heating: Shut valve when heat mode is off/cut + weather detection - Kitchen' description: '' trigger: - platform: state entity_id: input_select.heating_mode_kitchen to: 'off' - platform: state entity_id: input_select.heating_mode_kitchen to: cut - platform: state entity_id: input_select.heating_forced_off_weather from: 'no' condition: - condition: or conditions: - condition: state entity_id: input_select.heating_mode_kitchen state: 'off' - condition: state entity_id: input_select.heating_mode_kitchen state: cut - condition: not conditions: - condition: state entity_id: input_select.heating_forced_off_weather state: 'no' action: - choose: - conditions: - condition: state entity_id: input_boolean.heating_maintaince_kitchen state: 'on' sequence: - wait_for_trigger: - platform: state entity_id: input_boolean.heating_maintaince_kitchen from: 'on' to: 'off' timeout: '00:15:00' - service: climate.set_hvac_mode data: hvac_mode: 'off' entity_id: climate.radiator_valve_kitchen - conditions: - condition: state entity_id: input_boolean.heating_maintaince_kitchen state: 'off' sequence: - service: climate.set_hvac_mode data: hvac_mode: 'off' entity_id: climate.radiator_valve_kitchen default: [] mode: queued max: 10 ``` ```yaml alias: 'Heating: Shut valve when heating is deactivated - Kitchen' description: '' trigger: - platform: state entity_id: input_boolean.heating_kitchen to: 'off' condition: [] action: - choose: - conditions: - condition: state entity_id: input_boolean.heating_maintaince_kitchen state: 'on' sequence: - wait_for_trigger: - platform: state entity_id: input_boolean.heating_maintaince_kitchen from: 'on' to: 'off' timeout: '00:15:00' - service: climate.set_hvac_mode data: hvac_mode: 'off' entity_id: climate.radiator_valve_kitchen - conditions: - condition: state entity_id: input_boolean.heating_maintaince_kitchen state: 'off' sequence: - service: climate.set_hvac_mode data: hvac_mode: 'off' entity_id: climate.radiator_valve_kitchen default: [] mode: queued max: 10 ```

'heat rising too quickly'-detection

This automatism can detect sudden rises in temperature, like if someone is taking a shower in a room, does cooking or has an electrical device on, which generates a lot of heat. It can also detect a haywire reaction of the valve opening too long which would lead to an overshooting of the set temperature. This is important if you vented the room down several degrees and you're trying to heat it up again. This automatism will shut the valve to give the radiator more time to spread the heat in the room.

```yaml alias: 'Heating: Shut valve when the temperature is rising too fast - Kitchen' description: and it's within 2 degrees of the set temperature trigger: - platform: state entity_id: sensor.temp_sensor_kitchen_temperature - platform: state entity_id: sensor.radiator_valve_kitchen_position for: '00:00:30' - platform: state entity_id: climate.radiator_valve_kitchen attribute: temperature for: '00:00:30' condition: - condition: numeric_state entity_id: sensor.derivation_filtered_temperature_kitchen above: '3' - condition: state entity_id: input_select.heating_mode_kitchen state: default - condition: state entity_id: input_boolean.heating_maintaince_kitchen state: 'off' - condition: template value_template: >- {{ (states("input_number.target_temp_kitchen") | float) < ((states("sensor.temp_sensor_kitchen_temperature") | float) + 2) }} action: - service: input_select.select_option data: option: cut entity_id: input_select.heating_mode_kitchen - delay: '00:15:00' mode: single ``` ```yaml alias: 'Heating: Turn the valve on again after 12 minutes cut - Kitchen' description: '' trigger: - platform: state entity_id: input_select.heating_mode_kitchen to: cut for: '00:12:00' - platform: time_pattern minutes: /15 condition: - condition: state entity_id: input_select.heating_mode_kitchen state: cut for: '00:11:55' action: - choose: - conditions: - condition: not conditions: - condition: state entity_id: input_boolean.heating_maintaince_kitchen state: 'off' sequence: - wait_for_trigger: - platform: state entity_id: input_boolean.heating_maintaince_kitchen to: 'off' timeout: '00:11:55' continue_on_timeout: false default: [] - service: input_select.select_option data: option: default entity_id: input_select.heating_mode_kitchen - delay: '00:03:00' mode: single ```

switch the heat mode for the window and heat sources

Those automatisms switch the input_select-heat modes according to the heat source and window sensors.

```yaml alias: 'Heating: switch mode to off (window/heat source) - Kitchen' description: '' trigger: - type: opened platform: device entity_id: binary_sensor.window_sensor_kitchen_contact domain: binary_sensor for: seconds: 5 - platform: state entity_id: input_boolean.heatsource_present_kitchen for: seconds: 5 to: 'on' from: 'off' - platform: homeassistant event: start condition: - condition: or conditions: - type: is_open condition: device entity_id: binary_sensor.window_sensor_kitchen_contact domain: binary_sensor - condition: state entity_id: input_boolean.heatsource_present_kitchen state: 'on' action: - service: input_select.select_option data: option: 'off' entity_id: input_select.heating_mode_kitchen mode: queued max: 10 ``` ```yaml alias: 'Heating: switch mode to on (window/heat source) - Kitchen' description: '' trigger: - type: not_opened platform: device entity_id: binary_sensor.window_sensor_kitchen_contact domain: binary_sensor for: seconds: 5 - platform: state entity_id: input_boolean.heatsource_present_kitchen from: 'on' to: 'off' for: '00:15:00' - platform: homeassistant event: start condition: - type: is_not_open condition: device entity_id: binary_sensor.window_sensor_kitchen_contact domain: binary_sensor - condition: state entity_id: input_boolean.heatsource_present_kitchen state: 'off' action: - service: input_select.select_option data: option: default entity_id: input_select.heating_mode_kitchen mode: queued max: 10 ```

thermostat controller

The main temperature controller automatism. Gets triggered by some events pretty regularily, but the delay at the end and the single execution makes sure it only runs once a minute at most - to avoid too many valve operations.

The first condition in the choose makes sure that if the temperature is within -0.5°C the heating is reduced properly by the valve. If not the valve is closed and the valve's automtion restarted at 0%, which ususlly let it open again slowly - if neccessary - on it's own.

When it's 30% or below it's ususally already detecting the approached set temperature right, and will close soon.

The second condition in the choose just updates the set temperature on the valve (relative to the measured temperature of the valve itself) as long as the set temperature isn't reached.

```yaml alias: 'Heating: Set temperature for default mode - Kitchen v4.3' description: '' trigger: - platform: state entity_id: input_number.target_temp_kitchen - platform: state entity_id: input_boolean.heating_kitchen to: 'on' - platform: state entity_id: input_select.heating_forced_off_weather to: 'no' - platform: state entity_id: input_select.heating_mode_kitchen to: default - platform: state entity_id: sensor.temp_sensor_kitchen_temperature for: '00:00:15' - platform: state entity_id: input_boolean.heating_maintaince_kitchen from: 'on' to: 'off' for: '00:01:00' - platform: numeric_state entity_id: sensor.radiator_valve_kitchen_position above: '40' for: '00:02:00' - platform: numeric_state entity_id: sensor.radiator_valve_kitchen_position above: '60' for: '00:02:00' - platform: numeric_state entity_id: sensor.radiator_valve_kitchen_position for: '00:02:00' above: '80' - platform: numeric_state entity_id: sensor.radiator_valve_kitchen_position for: '00:02:00' above: '90' - platform: numeric_state entity_id: sensor.radiator_valve_kitchen_position for: '00:02:00' above: '99' - platform: state entity_id: input_number.target_temp_kitchen for: '00:01:00' condition: - condition: state entity_id: input_select.heating_mode_kitchen state: default - condition: state entity_id: input_select.heating_forced_off_weather state: 'no' - condition: state entity_id: input_boolean.heating_kitchen state: 'on' - condition: state entity_id: input_boolean.heating_maintaince_kitchen state: 'off' action: - choose: - conditions: - condition: template value_template: >- {{ ((states("input_number.target_temp_kitchen") | float) - 0.5) < (states("sensor.temp_sensor_kitchen_temperature") | float) }} sequence: - choose: - conditions: - condition: numeric_state entity_id: sensor.radiator_valve_kitchen_position above: '30' sequence: - service: climate.set_hvac_mode data: hvac_mode: 'off' entity_id: climate.radiator_valve_kitchen - wait_for_trigger: - platform: numeric_state entity_id: sensor.radiator_valve_kitchen_position below: '1' timeout: '00:01:00' - service: climate.set_temperature data_template: entity_id: climate.radiator_valve_kitchen temperature: >- {{ ((states("input_number.target_temp_kitchen") | float - states("sensor.temp_sensor_kitchen_temperature") | float ) + state_attr("climate.radiator_valve_kitchen", "local_temperature") | float) | round(1, "ceil")}} - delay: '00:00:10' - service: climate.set_hvac_mode data: hvac_mode: auto entity_id: climate.radiator_valve_kitchen - conditions: - condition: template value_template: >- {{ (states("input_number.target_temp_kitchen") | float) > (states("sensor.temp_sensor_kitchen_temperature") | float) }} sequence: - service: climate.set_temperature data_template: entity_id: climate.radiator_valve_kitchen temperature: >- {{ ((states("input_number.target_temp_kitchen") | float - states("sensor.temp_sensor_kitchen_temperature") | float ) + state_attr("climate.radiator_valve_kitchen", "local_temperature") | float) | round(1, "ceil")}} - delay: '00:00:10' - service: climate.set_hvac_mode data: hvac_mode: auto entity_id: climate.radiator_valve_kitchen default: [] - delay: '00:01:00' mode: single ```

a simple weather detection

This detection tries to detect two different type of weather scanarios:

```yaml alias: 'Heating: Weather detection ' description: '' trigger: - platform: time_pattern minutes: '23' seconds: '42' condition: [] action: - choose: - conditions: - condition: numeric_state entity_id: sensor.temperature_statistics_24h attribute: max_value above: '26' - condition: numeric_state entity_id: sensor.temperature_statistics_24h attribute: min_value above: '10' sequence: - service: input_select.select_option data: option: hot-day entity_id: input_select.heating_forced_off_weather - conditions: - condition: numeric_state entity_id: sensor.temperature_statistics_24h attribute: min_value above: '18' sequence: - service: input_select.select_option data: option: no-heating-required entity_id: input_select.heating_forced_off_weather default: - service: input_select.select_option data: option: 'no' entity_id: input_select.heating_forced_off_weather mode: single ```

home assistant startup

On startup all valves will be closed and the heating mode will be set to the internal value default to make sure the automatism has a defined starting point.

```yaml alias: 'Heating: close valves and deactivate maintaince mode when starting' description: '' trigger: - platform: homeassistant event: start condition: [] action: - service: climate.set_hvac_mode data: hvac_mode: 'off' entity_id: climate.radiator_valve_kitchen - service: input_boolean.turn_off data: {} entity_id: input_boolean.heating_maintaince_kitchen - service: input_select.select_option data: option: default entity_id: input_select.heating_mode_kitchen mode: restart ```

valve maintaince

In summer the valves usually get never moved, this automation moves the valves once a day to avoid that the valves get sticky or stuck.

```yaml alias: 'Heating: Clean valves once per day (when heating mode is default)' description: '' trigger: - platform: time at: '04:47:33' condition: [] action: - service: input_boolean.turn_on data: {} entity_id: input_boolean.heating_maintaince_kitchen - service: climate.set_hvac_mode data: hvac_mode: 'off' entity_id: climate.radiator_valve_kitchen - delay: '00:01:00' - service: climate.set_hvac_mode data: hvac_mode: heat entity_id: climate.radiator_valve_kitchen - delay: '00:01:00' - service: climate.set_hvac_mode data: hvac_mode: 'off' entity_id: climate.radiator_valve_kitchen - delay: '00:01:00' - service: climate.set_hvac_mode data: hvac_mode: heat entity_id: climate.radiator_valve_kitchen - delay: '00:01:00' - service: climate.set_hvac_mode data: hvac_mode: 'off' entity_id: climate.radiator_valve_kitchen - service: input_boolean.turn_off data: {} entity_id: input_boolean.heating_maintaince_kitchen mode: restart ```