@pnbruckner Brilliant! Thanks for your help.
@pnbruckner, With your inspiration I put together this little script as a proof of concept, but the value_template reports “true” regardess of the values set. What am I missing?
'1587739282724':
alias: Test
sequence:
- condition: template
value_template: '{{ state_attr('climate.thermostat_east', 'target_temp_high')!= states('input_select.thermostat_east_cool_setting') }}'
- data:
message: Ping
service: notify.sperry_house
Use double quotes outside the template:
value_template: "{{ state_attr('climate.thermostat_east', 'target_temp_high')!= states('input_select.thermostat_east_cool_setting') }}"
Otherwise this is your first pair of quotes:
value_template: '{{ state_attr('
Put this in the developer tools template editor, and post the results:
{{ state_attr('climate.thermostat_east', 'target_temp_high') }}
{{ states('input_select.thermostat_east_cool_setting') }}
Because you are comparing strings instead of numbers I suspect you might have something like:
23.0 != 23
Which can be solved by converting the strings to numbers:
value_template: "{{ state_attr('climate.thermostat_east', 'target_temp_high')|float != states('input_select.thermostat_east_cool_setting')|float }}"
returns:
74
75
Well (the string) 74 does not equal (the string) 75 so it should return true.
Exactly. But if I change them both to 75, it still returns true.
Try converting them to numbers:
value_template: "{{ state_attr('climate.thermostat_east', 'target_temp_high')|float != states('input_select.thermostat_east_cool_setting')|float }}"
That’s it! I am going to have to reevaluate a bunch of my templates. I suspect they haven’t been working as I expected.
Thanks for your help!
Ah. I think I might know why. States are always strings but attributes…? Maybe they can be numbers.
In which case:
If your templates are comparing values using operations like these:
>
<
>=
<=
==
!=
chances are you’re comparing numeric values so those values ought to be numeric. The state
value of all entities is a string. Therefore you might get unexpected results when you attempt to compare strings that look like numbers.
The one exception is when comparing time. Usually it is represented as a string like so:
21:15
It appears to be behave like it’s a numeric value because comparisons work correctly.
However, they are string values and the only reason the comparisons work is because of the way string comparisons function. The letter Z
is greater than A
because of how they are ordered in the ASCII table. Similarly the letter 9
is a higher order than the letter 0
. Therefore, by grace of how the characters are ordered, comparing time strings produces expected results. However, it’s no different than a string comparison of cat
and bat
.
That doesn’t explain why {{ '75' != '75' }}
was returning true though.
it was returning false based on your pic.
Also attributes can be any type where state is always strings so you had the right idea converting everything to floats just to make sure
Yeah but not in Philip’s template (read three posts from here): Force trigger to be re-evaluated?
Unless he left a vital bit of information out like one of the strings returned was actually 75.0
I figure when someone claims “one is not equal to one” that there’s something amiss with their definition of “one”. So the claim that “seventy-five is not equal to seventy-five” implies something wonky with one of the two values.
Just in case someone comes across this and finds it useful, this what I ended up doing. I wrote a couple scripts to set the thermostat if the thermostat setting do not match my variables for each. If the settings match, no action is taken. All my automations only change the variables – they do not send commands to the thermostats.
Anyway, I call these every few minutes with an automation and it seems to be working fine.
'1587748759636':
alias: Thermostat East Settings
sequence:
- condition: or
conditions:
- condition: template
value_template: '{{ state_attr(''climate.thermostat_east'', ''target_temp_high'')|float!=states(''input_select.thermostat_east_cool_setting'')|float
}}'
- condition: template
value_template: '{{ state_attr(''climate.thermostat_east'', ''target_temp_low'')|float!=states(''input_select.thermostat_east_heat_setting'')|float
}}'
- condition: template
value_template: '{{ states(''climate.thermostat_east'') != states(''input_select.thermostat_east_mode'')
}}'
- data_template:
entity_id: climate.thermostat_east
target_temp_high: '{{ states(''input_select.thermostat_east_cool_setting'')
}}'
target_temp_low: '{{ states(''input_select.thermostat_east_heat_setting'') }}'
service: climate.set_temperature
- data_template:
entity_id: climate.thermostat_east
hvac_mode: '{{ states(''input_select.thermostat_east_mode'') }}'
service: climate.set_hvac_mode
'1587752377152':
alias: Thermostat West Settings
sequence:
- condition: or
conditions:
- condition: template
value_template: '{{ state_attr(''climate.thermostat_west'', ''target_temp_high'')|float!=states(''input_select.thermostat_west_cool_setting'')|float
}}'
- condition: template
value_template: '{{ state_attr(''climate.thermostat_west'', ''target_temp_low'')|float!=states(''input_select.thermostat_west_heat_setting'')|float
}}'
- condition: template
value_template: '{{ states(''climate.thermostat_west'') != states(''input_select.thermostat_west_mode'')
}}'
- data_template:
entity_id: climate.thermostat_west
target_temp_high: '{{ states(''input_select.thermostat_west_cool_setting'')
}}'
target_temp_low: '{{ states(''input_select.thermostat_west_heat_setting'') }}'
service: climate.set_temperature
- data_template:
entity_id: climate.thermostat_west
hvac_mode: '{{ states(''input_select.thermostat_west_mode'') }}'
service: climate.set_hvac_mode
Edit: I also added a watchdog script to turn off the automation once the settings are correct. This way it will not cycle all day doing nothing useful. Plus it will keep from frustrating people who change the thermostat manually only to have it switch itself back automatically – even though that would be fun.
'1587822861319':
alias: Thermostat Watchdog
sequence:
- condition: and
conditions:
- condition: template
value_template: '{{ state_attr(''climate.thermostat_west'', ''target_temp_high'')|float==states(''input_select.thermostat_west_cool_setting'')|float
}}'
- condition: template
value_template: '{{ state_attr(''climate.thermostat_west'', ''target_temp_low'')|float==states(''input_select.thermostat_west_heat_setting'')|float
}}'
- condition: template
value_template: '{{ states(''climate.thermostat_west'') == states(''input_select.thermostat_west_mode'')
}}'
- condition: template
value_template: '{{ state_attr(''climate.thermostat_east'', ''target_temp_high'')|float==states(''input_select.thermostat_east_cool_setting'')|float
}}'
- condition: template
value_template: '{{ state_attr(''climate.thermostat_east'', ''target_temp_low'')|float==states(''input_select.thermostat_east_heat_setting'')|float
}}'
- condition: template
value_template: '{{ states(''climate.thermostat_east'') == states(''input_select.thermostat_east_mode'')
}}'
- data: {}
entity_id: automation.thermostat_set
service: automation.turn_off
FWIW, you could do it with one script:
set_thermostat:
alias: Set Thermostat
sequence:
- condition: template
value_template: >
{% set state = states.climate['thermostat_' ~ id] %}
{{ state.attributes.target_temp_high != states('input_select.thermostat_' ~ id ~ '_cool_setting')|float or
state.attributes.target_temp_low != states('input_select.thermostat_' ~ id ~ '_heat_setting')|float or
state.state != states('input_select.thermostat_' ~ id ~ '_mode') }}
- service: climate.set_hvac_mode
data_template:
entity_id: "climate.thermostat_{{ id }}"
hvac_mode: "{{ states('input_select.thermostat_' ~ id ~ '_mode') }}"
- service: climate.set_temperature
data_template:
entity_id: "climate.thermostat_{{ id }}"
target_temp_high: "{{ states('input_select.thermostat_' ~ id ~ '_cool_setting') }}"
target_temp_low: "{{ states('input_select.thermostat_' ~ id ~ '_heat_setting') }}"
That you call like this:
- service: script.set_thermostat
data:
id: east
or:
- service: script.set_thermostat
data:
id: west
Very cool. Smart. Can you tell I’m not a coder?