Set Thermostat Setpoint depending on Season

Folks, I am hoping that someone can assist in troubleshooting this automation.
Basicly, my use case is to set my thermostat at a certain level, but this level can be different depending on the season. For this example, I am looking at setting it to 71 degrees in winter, 69 degrees in autumn or spring (keeping them seperate in case I want to change one of the season, and then the default of 65 in summer. I have a Z-Wave CT-100 thermostat. Here is the code that I came up with, but it’s throwing an error although the YAML checks out fine.

- alias: Basement Temp - Raise 430PM
  initial_state: True
  hide_entity: True
  trigger: 
    platform: time
    at: '18:35:00'
  condition: 
    condition: state
    entity_id: binary_sensor.house_occupied
    state: 'on'
  action:
    - service: climate.set_temperature
      entity_id: climate.radio_thermostat_company_of_america_ct100_thermostat_usa_heating_1_3
      data_template:
        temperature: >
          {% if is_state("sensor.season", "winter") %}
            71
          {% elif is_state("sensor.season", "autumn") %}
            69
          {% elif is_state("sensor.season", "spring") %}
            69
          {% else %}
            67
          {% endif %}
          operation_mode: 'heat'

The error message that I am getting is:
Invalid data for call_service at pos 1: expected float for dictionary value @ data[‘temperature’]

I am sure that I have an error in my data_template but I have no idea on how to really set this up to work.
Any ideas?

OK, UPDATE:
I knew that as soon as I would post something, I would most likely find a solution;
It seems like removing:

operation_mode: ‘heat’

from my automation, things started working.
I’ll post back if I have further issues.

Removing it eliminated the error because it was indented incorrectly.

Shift the line containing operation_mode: heat to the left by two spaces so it aligns vertically with the start of temperature: >

… and for consistency, move entity_id on a line below data_template and indent by two spaces. Sort of like this:

- alias: Basement Temp - Raise 430PM
  trigger: 
    platform: time
    at: '18:35:00'
  condition: 
    condition: state
    entity_id: binary_sensor.house_occupied
    state: 'on'
  action:
    - service: climate.set_temperature
      data_template:
        entity_id: climate.radio_thermostat_company_of_america_ct100_thermostat_usa_heating_1_3
        operation_mode: 'heat'
        temperature: >
          {% set t = {'winter': '71', 'autumn': '69', 'spring': '69', 'summer': '67'} %}
          {% set s = states('sensor.season') %}
          {{ t[s] if s in t.keys() else '69' }}

EDIT
Corrected syntax error in template. Added %} to the end of {% set s = states('sensor.season')

I tried that first and still got the error, now I am thinking that the word ‘heat’ should not be in quotes. I’ll try that next.

But now looking at your solution, I think that I like the looks of that much better, it’s more compact. I’ll surely give this a shot. Not sure if ‘heat’ should be in quotes still. Thanks for providing a great solution.

If you search the forum for set_operation_mode you will find examples of other people using 'heat' and heat with equal success.

https://community.home-assistant.io/search?q=set_operation_mode

Thanks, just tried your automation and it’s throwing an error … any ideas, I really like the look of yours better than mine

Invalid config for [automation]: invalid template (TemplateSyntaxError: expected token ‘end of statement block’, got ‘{’) for dictionary value @ data[‘action’][0][‘data_template’][‘temperature’]. Got None. (See ?, line ?). Please check the docs at https://home-assistant.io/integrations/automation/

My mistake; I overlooked to close a statement.

Change this line:

          {% set s = states('sensor.season')

to this:

          {% set s = states('sensor.season') %}

I’ll correct the example in my post above.

BTW, your automation got me thinking about the operation_mode. Do you only heat the house all year or do you also cool it in summer?

Currently, the automation sets operation_mode to heat for all seasons of the year. My understanding (and I may be incorrect) is that this means it will activate heating in summer if the ambient temperature falls below 69 but never activate cooling if it rises above 69 (because the HVAC system is set to heat mode).

If this is how you want it to work, then all is well.

Hi Taras,

Yes, we only heat the house and never cool it, we don’t have air conditioning and not in the area of the country that really needs it. so I am fine with that.

That being said, I just tried your automation and it never sets the temperature to the desired degree, should there be quotes around the ‘71’, ‘69’ etc.? I am not getting any yaml verification errors any more as I had also found the missing “%}”.
Any other ideas? I would hate to revert back to my method . :slight_smile:

When I test setting the temperature using the Services page, it appears to make no difference if I delimit the value with or without quotes (it works both ways).

Temperature (in Celsius) with quotes:
Screenshot%20from%202019-10-16%2020-32-34

Temperature (in Celsius) without quotes:
Screenshot%20from%202019-10-16%2020-35-19

Try setting the temperature using the Services page on your system and see if it behaves the same way.

Thanks for your help Taras and tanks for teaching me the “Services” tab, never played with that before, found it too intimidating, but I was able to find what works and what didn’t. I am posting my working configuration below in case it helps someone else. Basically, I had to delete "operation_mode: ‘heat’ " ad it was throwing errors and took the single quotes off the actual temperature setting, now everything is working great. Thanks again.

Configuration for a CT-100 z-wave thermostat:

- alias: Basement Temp - Raise 400PM
  initial_state: True
  hide_entity: True
  trigger: 
    platform: time
    at: '16:00:00'
  condition: 
    condition: state
    entity_id: binary_sensor.house_occupied
    state: 'on'
  action:
    - service: climate.set_temperature
      data_template:
        entity_id: climate.radio_thermostat_company_of_america_ct100_thermostat_usa_heating_1_3
        temperature: >
          {% set t = {'winter': 71, 'autumn': 69, 'spring': 69, 'summer': 65} %}
          {% set s = states('sensor.season') %}
          {{ t[s] if s in t.keys() else 65 }}

Are you saying that when you used the Services page to set the thermostat’s temperature, it failed to work if the value was delimited by quotes?

In other words, this Service Data failed for you:

{
  "temperature": "70",
  "entity_id": "climate.radio_thermostat_company_of_america_ct100_thermostat_usa_heating_1_3"
}

If so, your result differs from mine.

So this time, it worked … the last time, I didn’t have as many quotes around all the items, so that may have been my fault with lack of experience. I guess for now, I will keep it the way I’ve posted it up above, if it breaks, I’ll start adding quotes again. I’m envious of folks like you that can come up with all these solutions, maybe in time, I’ll learn.

FWIW, entity state values are stored as strings (i.e. not as numerical values but as text).

That’s why when you want to do some arithmetic with, for example, a temperature sensor, you have to convert its state to a numeric value using int or float (because its state, despite looking like a numeric value, actually is a string).

This will work:

{{ states('sensor.indoor_temperature') | float + 3 }}

This will cause an error:

{{ states('sensor.indoor_temperature') + 3 }}

So setting the temperature to 72 (integer value) or '72' (string value) is a wash because ultimately it will be stored as a string (i.e. Home Assistant converts the numeric version to a string).

1 Like

I performed an experiment and discovered an interesting discrepancy.

I can set the thermostat’s temperature using the Services page with the following options which include operation_mode.

If I use the following simple automation to perform the same task, Home Assistant complains that operation_mode is an invalid option.

- alias: 'test set thermostat'
  trigger: 
    platform: state
    entity_id: input_boolean.toggler
    to: 'on'
  action:
    - service: climate.set_temperature
      data_template:
        entity_id: climate.thermostat
        operation_mode: 'heat'
        temperature: >
          {% set t = {'winter': '21', 'autumn': '20', 'spring': '19', 'summer': '18'} %}
          {% set s = states('sensor.season') %}
          {{ t[s] if s in t.keys() else '19' }}

Error while executing automation automation.test_set_thermostat. Invalid data for call_service at pos 1: extra keys not allowed @ data[‘operation_mode’]

Both the Services page and the automation are calling the same service (climate.set_temperature) yet operation_mode is considered to be an ‘extra key’ only when used in the automation.

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.

It would appear that the Services page is more lax and, as long as the options needed by the service are present, it ignores any superfluous options (i.e. keys). In contrast, the Config Check is more strict and rejects options that aren’t required for the called service.

This discrepancy can lead to the kind of error that occurred in this topic. I performed the test using the Services page where operation_mode was not flagged as an error. You performed the test with the automation where the presence of the same option was reported as an error.

tl;dr
The Services page isn’t as strict as Config Check.

1 Like