How to set a climate mode via templating

Hi there.
I am trying to template an automation for set up climate modes i my home assistant but I think I am doing someting wrong, the state never changes. Can some one point me to right direccion?

  alias: Set flow temperature modes
  description: ''
  trigger:
  - platform: time_pattern
    seconds: /5
  action:
  - service: >
        {% if (state_attr("climate.flow_thermostat","current_temperature")
          - state_attr("climate.flow_thermostat","temperature")) <= -5 %}
          climate.set_hvac_mode: "heat"
             
        {% elif (state_attr("climate.flow_thermostat","current_temperature")
          - state_attr("climate.flow_thermostat","temperature")) >= 5 %}
          climate.set_hvac_mode: "cool"
        {% endif %}
    entity_id: climate.flow_thermostat

Thanks

See here: you’re calling the service wrong.

 action:
  - service: climate.set_hvac_mode
    data:
      hvac_mode: >
        {% if (state_attr("climate.flow_thermostat","current_temperature")
          - state_attr("climate.flow_thermostat","temperature")) <= -5 %}
          "heat"
        {% elif (state_attr("climate.flow_thermostat","current_temperature")
          - state_attr("climate.flow_thermostat","temperature")) >= 5 %}
          "cool"
        {% endif %}
    entity_id: climate.flow_thermostat

You should also include a condition to prevent the action from executing if the difference is less than 5 — at the moment, it’d fall through the if and elif, and try to set the hvac_mode to False.

Alternatively, do a template trigger to run only if the gap is bigger than 5 instead of your time_pattern trigger. Like this (untested; the abs filter in the trigger always returns a positive number for the gap):

alias: Set flow temperature modes
trigger:
  - platform: template
    value_template: '{{ (state_attr("climate.flow_thermostat","current_temperature") - state_attr("climate.flow_thermostat","temperature"))|abs > 5 }}'
condition: []
action:
  - service: climate.set_hvac_mode
    entity_id: climate.flow_thermostat
    data:
      hvac_mode: '{{ "heat" if (state_attr("climate.flow_thermostat","current_temperature") < state_attr("climate.flow_thermostat","temperature")) else "cool" }}'

This will trigger on every update of either sensor if the gap is larger than 5; and the template in the action determines whether to heat or cool. I think I have it the right way around…

Hi
Thanks but it is still not working. The climate mode never changes.
I will investigate a litle bit more later.

Note I’ve corrected a typo: the service should be climate.set_hvac_mode.

If it still doesn’t work, please post a screenshot of climate.flow_thermostat from the Developer Tools / States page, showing the States and Attributes columns.

Yes I had corrected it before your answer. No changes.
I will paste the screenshot later

Also see if you can manually set the mode:

Yes I can set it manually aswell.

Can you not just have it set to heat/cool with the correct setpoints?

Hi guys.
Thas the way I got this working.

  action:
  - service: climate.set_hvac_mode
    data:
      hvac_mode: >
           {% if (state_attr("climate.flow_thermostat","current_temperature")
             - state_attr("climate.flow_thermostat","temperature")) <= -5 %}
             heat
           {% elif (state_attr("climate.flow_thermostat","current_temperature")
             - state_attr("climate.flow_thermostat","temperature")) >= 5 %}
             cool
           {% endif %}
    entity_id: climate.flow_thermostat

Just removed quotation marks in “hvac_modes”
Thanks a lot for your answers, hopefully this helps someone else

What if the temperature difference is neither less than -5 or greater than 5? For example, what if it’s -4 or 4 degrees (i.e. a value between -5 and 5)? Your template doesn’t handle that case so it will return an empty string value to hvac_mode which will cause an error message.

Yes
In that case it sets automatically hvac_mode to idle and this is exactly what I want.
Good appointment
Thanks

idle is an invalid value for hvac_mode. It’s a valid value for hvac_action (which is set by the integration, not a service call).

Unless your template ends with an else containing a valid hvac_mode value, it will produce an empty value when the temperature difference is between -5 and 5. The service call climate.set_hvac_mode won’t accept an empty value.

Perhaps finish with an:

           {% else %}
             {{ states('climate.flow_thermostat') }}
           {% endif %}

to set it to its current value? I still think this logic should be in the trigger and condition blocks as per my suggestion above though.