Help with climate data_template

But my issue is still there.
The automation triggered when I turn on thermostat manually, but still get error when run the hvac_mode change.

Log shows " Invalid data for call_service at pos 1: value is not allowed for dictionary value @ data[‘hvac_mode’]"

Oops. Sorry I misunderstood. Have you tried separating out the hvac mode and temperature calls?

    - service: climate.set_hvac_mode
      data_template:
        entity_id: {{ trigger.entity_id }}
        hvac_mode: >
          {% if ((now().month >= 11) or (now().month <= 3)) and (trigger.to_state.state != 'heat') %}
             heat
          {% elif ((now().month >= 6) and (now().month <= 10)) and (trigger.to_state.state != 'cool') %}
             cool
          {% else %}
             auto
          {% endif %}

    - service: climate.set_temperature
      data_template:
        entity_id: {{ trigger.entity_id }}
        temperature: 24

I’d be interested to hear the answer. In the linked post I wrote:

Strictly speaking, the error message is correct. A completely different service is used to set the operation mode ( climate.set_operation_mode ) so if this option appears with climate.set_temperature it’s superfluous (i.e. ‘extra key’) and reported to be an error.

To reiterate, the error I received is not the same one as in this topic but there are similarities in what both topics are attempting (use the set_temperature service to set temperature and hvac_mode). It seems it works fine here unless a template is used for hvac_mode. That’s very strange.

I tried only set “climate.set_hvac_mode” but still same error… It looks like hvac_mode hates “if else” in my scenario…:joy:

It suggests there’s a problem with the template.

Try this template. It is equivalent to just setting hvac_mode to heat (but does it with a template).

  action:
  - service: climate.set_temperature
    data_template:
      entity_id: '{{ trigger.entity_id }}'
      temperature: 26
      hvac_mode: "{{ 'heat' if true else 'auto' }}"

If it fails to work than there’s something unusual going on.

Please post the configuration of your climate entity.

“{{ ‘heat’ if true else ‘auto’ }}” works without any errors.

Good. So that means it doesn’t have a general problem using a template, just a specific problem with the template in your example.

Now try this version:

hvac_mode: "{{ 'auto' if true else 'heat' }}"

If it generates an error it implies your thermostat doesn’t support auto mode.

“{{ ‘auto’ if true else ‘heat’ }}” still good.

More good news. That means your thermostat has no problems with auto or heat or templates in general.

The only problem it has is when it attempts to use your example’s template. Unfortunately, I don’t see anything wrong with your template. The only way it can fail is if you trigger the automation manually in which case trigger.to_state.state will be undefined and the template will fail to produce a valid value for hvac_mode.

Think there’s any point to trying the template like this to eliminate an issue with the trigger.to_state? I know it shouldn’t make a difference but it already should work.

          {% if ((now().month >= 11) or (now().month <= 3)) %}
             heat
          {% elif ((now().month >= 6) and (now().month <= 10)) %}
             cool
          {% else %}
             auto
          {% endif %}

Unfortunately it doesn’t work anyway, I also tried

{% if states.climate.mi_acpartner_bedroom.state == 'cool' %}
    'heat'
{% elif states.climate.mi_acpartner_bedroom.state == 'heat' %}
    'cool'
{% else %}
    'auto'
{% endif %}

Well my friend you have me stumped. I’ve run out of ideas for you. I’ll be watching the thread to find out what the solution is so if you figure it out please update us!

Yeah, that’s very weird… I know the undefined error if I trigger the automation manually, but it’s a different story here.

Thank you folks, I am afraid I will just force to set hvac_mode to ‘heat’ for now, tried all the solutions as much as I can image. :sweat_smile:

@123 I think I may have figured it out!

@sephrioth I got bored and had another good look at this last night. When I used your original automation in my config I got the exact same error as you did. After looking at the logic again I realized you were recursively triggering the automation. So I added in the steps to make sure that doesn’t happen and it seemed to do the trick! The following automation runs as expected on my system now without error.

EDIT: I was concentrating so hard on getting this automation to work I completely overlooked some of the other issues it has.

  • Your automation is going to fire every time you touch the thermostat and every time the HVAC system turns on to heat or cool the house. I don’t think that is what you intended. I added a condition to prevent it from running if the temperature hasn’t been adjusted and the hvac mode hasn’t changed.

  • The temperature is always going to be reset back to 26 degrees. So if you’ve got a little chill or are a little warm and want to bump your temperature either way you can’t because the automation will run and will reset it back to 26. So as it stands you’ll have to manually turn this automation off any time you want to have manual control over the temperature. It also means your temperature will be the same value all year long, which most people don’t do. I added a template to demonstrate.

  • With my thermostat (Nest) including the hvac_mode in the set_temperature service does not produce an error but it also doesn’t do anything. I have to call them separately. I’m not sure if yours will work the same way or not. You can try it but I have them separated below.

  • What happens when this runs anytime between November and March? It hits the first part of your template and it asks if the new state was not set to heat then set it to heat which is fine if it wasn’t. But if it WAS set to heat it heads down to the else statement and sets the HVAC mode to auto. Removing the trigger.to_state check fixes this problem. I don’t think it’s necessary. If the system is in heat mode and you set it again to heat mode nothing happens except an additional call to the API.

- alias: 'Climate Auto Mode'
  initial_state: true

  trigger:
    - platform: state
      entity_id: climate.mi_acpartner_playroom_2, climate.mi_acpartner_bedroom

  condition:
    - condition: template
      value_template: "{{ (trigger.to_state.state != 'unavailable') and  (trigger.to_state.state != 'off') }}"

    - condition: template
      value_template: >
        {{ (trigger.to_state.attributes.temperature != trigger.from_state.attributes.temperature)
          or (trigger.to_state.attributes.hvac_mode != trigger.from_state.attributes.hvac_mode) }}

  action:
    - service: automation.turn_off  # you need to turn this off or you get a recursive trigger!
      entity_id: automation.climate_auto_mode

    - service: climate.set_hvac_mode
      data_template:
        entity_id: "{{ trigger.entity_id }}"
        hvac_mode: >
          {% if ((now().month >= 11) or (now().month <= 3)) %}
            heat
          {% elif ((now().month >= 6) and (now().month <= 10)) %}
            cool
          {% else %}
            auto
          {% endif %}

    - service: climate.set_temperature
      data_template:
        entity_id: "{{ trigger.entity_id }}"
        temperature: >
          {% if ((now().month >= 11) or (now().month <= 3)) %}
            26
          {% elif ((now().month >= 6) and (now().month <= 10)) %}
            28
          {% else %}
            27
          {% endif %}

    - delay: '00:00:02'  # this is needed to allow states to change.

    - service: automation.turn_on # remember to turn it back on!
      entity_id: automation.climate_auto_mode

1 Like

Jason, you are so great, huge thanks!
Here is some feedback before I try your new solution. :smiley:

Actually I thought about the recursively trigger issue, so I tried to add for “00:00:03” to heat and cool in trigger, but still old errors so I just gave up.

  • And I also I aware the fire issue, so I modified the code to
  trigger:
  - platform: state
    entity_id: climate.mi_acpartner_playroom_2, climate.mi_acpartner_bedroom  
  condition:
    condition: or
    conditions:
    - condition: template
      value_template: "{{ (trigger.to_state.state == 'heat') and  ((now().month >= 6) and (now().month <= 10)) }}"
    - condition: template
      value_template: "{{ (trigger.to_state.state == 'cool') and  ((now().month >= 11) or (now().month <= 3)) }}"  
  • Based on my code above, I think temperature change won’t trigger the automation right (Will test later)?

  • I need test first to see if I have to call them separately.

  • Should do nothing because the condition not matched based on my new code, so I can manually change it, I hope.

Good luck to me, I will do the test and back later, thanks again, dude! @jazzyisj

The new conditions you show here won’t stop the automation from triggering when the hvac turns on to heat or cool the house. They also prevent any climate adjustments at all in April and May. The heat will only run from June until October and the A/C will only run from November to March. I’m pretty sure that’s not what you want unless you happen to live in Australia (maybe you do?).

The automation I wrote for you should be plug and play for your config. Give it a try as it is written and see if it does what you need it to do. If it does not, and you can’t figure out why on your own, I’m happy to keep working with you on it.

It finally works!!!

And I did some tests found something even more weird. @Burningstone asked me to remove single quote in previous post and I got same error that time, and today I just removed the single quote and no errors at all, even I didn’t add automation control.

BTW, my action code is this, so I am not in Australia :joy:

        {% if trigger.to_state.state == 'cool' %}
          heat
        {% elif trigger.to_state.state == 'heat' %}
          cool
        {% else %}
          auto
        {% endif %}

Whew. Glad we finally got it figure out for you. That was a tough nut to crack! :grinning:

Yeah, not an easy one, but I am still confused with single quote usage now, in previous test

"{{ 'heat' if true else 'auto' }}" 

works good with single quote?