Several radiator thermostats and heating pump

First of all I am very new to HA. So I may be asking what seem like obvious questions to some. Sorry for that.

I have a configuration which is fairly common in Europe in which I have a radiator in each room/zone that is controlled by a thermostatic valve. There is a separate system that heats the water, in my case both a solar heater and a heat pump. These are used to heat both the domestic water and provide water for the heating. There is a pump that can be switched on to provide hot water to the radiators.

Off course I could leave this pump running the whole time, but that us wasteful. So I want to crate an automation that determines if any of the thermostats is open - even a little - and turn on the pump. However, if all of the radiators are closed, then I want to turn the pump off.

I can then control the radiators separately in each zone by ToD, DoW, MoY, …

I use Tado thermostats and the integration is great. So what I want to do is create an automation that is triggered if any of the thermostats turns on or off. I will have around 10-15 thermostats in the house so I want an automation that will loop through however many thermostats there are in the system to determine if the heating pump should be on or off.

I’ve looked through the templates and I saw one to test the battery of the all of the radiators, and then send a message. But this is run on a regular cadence rather than being triggered by an event.

I’d love to get some pointers from the community, even if it is pointers to something similar.

Hi, I have a similar requirement for my setup, although I just gotten started with radiator thermostats.

I have created an automation that raises the setpoint my main thermostat (the one that controls the boiler). In your case that would be different, because you need to set the pump on/off.
When the room with the radiator thermostat reaches a temperature higher than the desired temperature, the main thermostat is reset to the default value.

The automation is not tested very extensively yet, so I expect some changes, but maybe it can give you some idea’s on how to create one for yourself.

automation:
  - alias: When one of the non main radiator valves requires heat, set main thermostat higher
    initial_state: true
    mode: restart
    trigger:
      platform: state
      entity_id: 
        - climate.radiator_valve_guest_room
        - climate.radiator_valve_office
        - climate.radiator_valve_bedroom
        - climate.radiator_valve_bathroom
      attribute: temperature
    condition:
      # new setpoint is actually higher dan old setpoint
      - condition: template
        value_template: '{{ (trigger.to_state.attributes.temperature | float) > (trigger.from_state.attributes.temperature | float) }}'
      # new setpoint is actually higher than current room temp
      - condition: template
        value_template: '{{ (trigger.to_state.attributes.temperature | float) > (trigger.from_state.attributes.current_temperature | float) < }}'
    action:
      - service: input_select.select_option
        target:
          entity_id: input_select.radiator_valve_requesting_heat
        data:
          option: '{{ trigger.entity_id }}'
      - service: input_number.set_value
        data:
          entity_id: input_number.heat_seeking_radiator_valve_setpoint_actual_degree_diff
          value: '{{ (trigger.to_state.attributes.temperature | float) - (states.sensor.toon_room_temp_setpoint.state | float) }}'
      - service: notify.telegram
        data:
          message: >
           "Setpoint for {{ trigger.to_state.name }} changed to {{trigger.to_state.attributes.temperature}} degrees. 
           Setting main thermostat {{states.input_number.heat_seeking_radiator_valve_setpoint_actual_degree_diff.state}} degrees higher than current temp to trigger boiler. 
      - service: climate.set_temperature
        data:
          entity_id: climate.toon_thermostaat
          temperature: >
            {% set min_diff = 1 | float %}
            {% set max_diff = 3 | float %}
            {% set diff_main_therm_and_radiator = states.input_number.heat_seeking_radiator_valve_setpoint_actual_degree_diff.state | float %}
            {% set new_setpoint = 0.0 %}
            {% if diff_main_therm_and_radiator > max_diff  %}
            {% set new_setpoint = states.sensor.toon_room_temp.state | float + max_diff %}
            {% elif diff_main_therm_and_radiator < min_diff  %}
            {% set new_setpoint = states.sensor.toon_room_temp.state | float + min_diff %}
            {% else  %}
            {% set new_setpoint = states.sensor.toon_room_temp.state | float + diff_main_therm_and_radiator %}
            {% endif  %}
            {{ new_setpoint }}
      - service: climate.set_preset_mode
        data:
          entity_id: '{{ trigger.entity_id }}'
          preset_mode: Boost
      - wait_for_trigger:
          - platform: template
            value_template: '{{ (states[states.input_select.radiator_valve_requesting_heat.state].attributes.current_temperature | float) > (states[states.input_select.radiator_valve_requesting_heat.state].attributes.temperature | float) }}'
        timeout:
          minutes: 120
      - service: notify.telegram
        data:
          message: >
           "Heating of room complete or timed out.
            Setting toon thermostat to normal preset value."
      - service: climate.set_preset_mode
        data:
          entity_id: climate.toon_thermostaat
          preset_mode: "{{states['input_select.thermostat_target_setting'].state }}"

1 Like

Many thanks

@freakshock wow, that looks very promising. Looking forward to implementing this into my own home. You said it’s not tested very extensively and changes were to be expected. Have you made any progress on this after this post?

So, I tried to implement this into my setup but I have almost zero programming skills and are running into my own shortcomings here.
When trying to use this automation i do the following:
Copy the example automation
Create a new automation in HA and go to YAML mode
Paste the example and replace several items to make it fit my setup by replacing radiator_valve_myownroomnames and toon_room_temp with my own Nest thermostats temp sensor.

After that I try to save the automation but it won’t save giving me the following erroe message:

Message malformed: invalid template (TemplateSyntaxError: unexpected ‘end of print statement’) for dictionary value @ data[‘condition’][1][‘value_template’]

I’m probably missing something silly, but can’t figure out what it is. Could someone help me out?

It’s best if you publish your code in this stream. It is difficult to determine the location of the error from the error message.

Good point, that would be this:

alias: HEATING
initial_state: true
mode: restart
trigger:
  platform: state
  entity_id:
    - climate.radiator_badkamer
    - climate.radiator_gang
    - climate.radiator_kamer_arthur_4
    - climate.radiator_kamer_robin
    - climate.radiator_slaapkamer
    - climate.radiator_slaapkamer_2
    - climate.radiator_woonkamer_links
    - climate.radiator_woonkamer_links_3
    - climate.radiator_woonkamer_rechts
    - climate.radiator_woonkamer_rechts_2
  attribute: temperature
condition:
  - condition: template
    value_template: >-
      {{ (trigger.to_state.attributes.temperature | float) >
      (trigger.from_state.attributes.temperature | float) }}
  - condition: template
    value_template: >-
      {{ (trigger.to_state.attributes.temperature | float) >
      (trigger.from_state.attributes.current_temperature | float) < }}
action:
  - service: input_select.select_option
    target:
      entity_id: input_select.radiator_valve_requesting_heat
    data:
      option: "{{ trigger.entity_id }}"
  - service: input_number.set_value
    data:
      entity_id: input_number.heat_seeking_radiator_valve_setpoint_actual_degree_diff
      value:
        "[object Object]": null
  - service: notify.whatsapp
    data:
      message: >
        "Setpoint for {{ trigger.to_state.name }} changed to
        {{trigger.to_state.attributes.temperature}} degrees.  Setting main
        thermostat
        {{states.input_number.heat_seeking_radiator_valve_setpoint_actual_degree_diff.state}}
        degrees higher than current temp to trigger boiler. 
  - service: climate.set_temperature
    data:
      entity_id: climate.woonkamer
      temperature: >
        {% set min_diff = 1 | float %} {% set max_diff = 3 | float %} {% set
        diff_main_therm_and_radiator =
        states.input_number.heat_seeking_radiator_valve_setpoint_actual_degree_diff.state
        | float %} {% set new_setpoint = 0.0 %} {% if
        diff_main_therm_and_radiator > max_diff  %} {% set new_setpoint =
        states.sensor.woonkamer_temperature.state | float + max_diff %} {% elif
        diff_main_therm_and_radiator < min_diff  %} {% set new_setpoint =
        states.sensor.woonkamer_temperature.state | float + min_diff %} {% else 
        %} {% set new_setpoint = states.sensor.woonkamer_temperature.state |
        float + diff_main_therm_and_radiator %} {% endif  %} {{ new_setpoint }}
  - service: climate.set_operation
    data:
      entity_id: "{{ trigger.entity_id }}"
      preset_mode: Heat
  - wait_for_trigger:
      - platform: template
        value_template: >-
          {{
          (states[states.input_select.radiator_valve_requesting_heat.state].attributes.current_temperature
          | float) >
          (states[states.input_select.radiator_valve_requesting_heat.state].attributes.temperature
          | float) }}
    timeout:
      minutes: 120
  - service: notify.whatsapp
    data:
      message: |
        "Heating of room complete or timed out.
         Setting NEST thermostat to normal preset value."
  - service: climate.set_operation
    data:
      entity_id: climate.toon_thermostaat
      preset_mode: "{{states['input_select.thermostat_target_setting'].state }}"
description: ""

I have highlighted the only error I could see as **<**. This < needs to be removed. I changed the preceding comparison operator in the same condition from > to <. My understanding is that the Conditions are testing whether there is a difference in temperature.

The rest I just changed for readability.

alias: HEATING
initial_state: true
mode: restart
trigger:
  platform: state
  entity_id:
    - climate.radiator_badkamer
    - climate.radiator_gang
    - climate.radiator_kamer_arthur_4
    - climate.radiator_kamer_robin
    - climate.radiator_slaapkamer
    - climate.radiator_slaapkamer_2
    - climate.radiator_woonkamer_links
    - climate.radiator_woonkamer_links_3
    - climate.radiator_woonkamer_rechts
    - climate.radiator_woonkamer_rechts_2
  attribute: temperature
condition:
  - condition: template
    value_template: >-
      {{ (trigger.to_state.attributes.temperature | float) >
      (trigger.from_state.attributes.temperature | float) }}
  - condition: template
    value_template: >-
      {{ (trigger.to_state.attributes.temperature | float) <
      (trigger.from_state.attributes.current_temperature | float) **<** }}
action:
  - service: input_select.select_option
    target:
      entity_id: input_select.radiator_valve_requesting_heat
    data:
      option: "{{ trigger.entity_id }}"
  - service: input_number.set_value
    data:
      entity_id: input_number.heat_seeking_radiator_valve_setpoint_actual_degree_diff
      value:
        "[object Object]": null
  - service: notify.whatsapp
    data:
      message: >
        "Setpoint for {{ trigger.to_state.name }} changed to {{trigger.to_state.attributes.temperature}} degrees.  Setting main thermostat {{states.input_number.heat_seeking_radiator_valve_setpoint_actual_degree_diff.state}} degrees higher than current temp to trigger boiler. 
  - service: climate.set_temperature
    data:
      entity_id: climate.woonkamer
      temperature: >-
        {% set min_diff = 1 | float %} 
        {% set max_diff = 3 | float %} 
        {% set diff_main_therm_and_radiator =
            states.input_number.heat_seeking_radiator_valve_setpoint_actual_degree_diff.state | float %} 
        {% set new_setpoint = 0.0 %} 
        {% if diff_main_therm_and_radiator > max_diff  %} 
            {% set new_setpoint = states.sensor.woonkamer_temperature.state | float + max_diff %} 
        {% elif diff_main_therm_and_radiator < min_diff  %} 
            {% set new_setpoint = states.sensor.woonkamer_temperature.state | float + min_diff %} 
        {% else %} 
            {% set new_setpoint = states.sensor.woonkamer_temperature.state | float + diff_main_therm_and_radiator %} 
        {% endif  %} 
        {{ new_setpoint }}
  - service: climate.set_operation
    data:
      entity_id: "{{ trigger.entity_id }}"
      preset_mode: Heat
  - wait_for_trigger:
      - platform: template
        value_template: >-
        {{ (states[states.input_select.radiator_valve_requesting_heat.state].attributes.current_temperature | float) > (states[states.input_select.radiator_valve_requesting_heat.state].attributes.temperature | float) }}
    timeout:
      minutes: 120
  - service: notify.whatsapp
    data:
      message: |
        "Heating of room complete or timed out.
         Setting NEST thermostat to normal preset value."
  - service: climate.set_operation
    data:
      entity_id: climate.toon_thermostaat
      preset_mode: "{{states['input_select.thermostat_target_setting'].state }}"
description: ""