So I think I know what’s happening but am wondering if there is an appropriate way to fix it. I have the following value template.
{% if (states('sensor.hvac_operating_state') == 'cooling') and states.sensor.ac_split_ambient_temp is defined and states.sensor.ac_split_cold_temp is defined %}
{% if (as_timestamp(now()) - as_timestamp(states.sensor.hvac_operating_state.last_updated) > 240 ) %}
{{ (states('sensor.ac_split_ambient_temp') | float - states('sensor.ac_split_cold_temp') | float ) | round(1) }}
{% else %}
{{ "unknown" }}
{% endif %}
{% else %}
{{ "unknown" }}
{% endif %}
The purpose of this is, when the AC is cooling, and has been cooling for at least 240 seconds, it takes a difference of two temperatures. If anything isn’t true, like it has not been running that long or it is not cooling or for some reason the temperatures go missing it just returns Unknown.
The problem is that it takes much longer than 240 seconds to calculate. I am pretty sure the issue is that the value templates are recalculating only when the states of the expressions change, and it is not recalculating based on the last_updated times’ difference changing. Or more precisely when now() changes.
Which makes sense… Wouldn’t want it calculating every millisecond or whatever the resolution is there for “now”:.
So is there any way to do the above but make it evaluate every minute or some such? The only thing I can think of (and have yet to code to try) is to create a new sensor that contains a minute-by-minute time, and somehow include that in the template. Ugly.
So thought I would ask: Is my presumption correct about why?
your guess is right, take a look at the docs (and examples).
basically, you just need to change your code to use sensor.time instead of now() and that will cause regular re-evaluations of your template.
This is a Template Sensor so just add the following to its configuration:
entity_id: sensor.time
That entity changes state every 60 seconds and so will cause the template to be evaluated every 60 seconds.
Ensure you have configured sensor.time. It’s part of the Time & Date integration.
EDIT
AhmadK made a good point in a post below so I’ll make a clarification. If you add entity_id: to the Template Sensor, Home Assistant will monitor all the entities listed in entity_id for state-changes. Therefore it should contain all the entities used within the template. Adding sensor.time corrects the issue of using the now() function but you also have to list all the other entities used in your template.
As the docs put it I assume the template won’t be re-evaluated on state changes of any entity apart from sensor.time.
That’s exactly why I prefer to convert my templates so they use now() to states('sensor.time') or (if I don’t need time per se and just want a refresh every minute) a dummy call of states('sensor.time') - if using entity_id I’d need to list all entities whose state changes template should react to, and it’s a bit too much in terms of making changes, too easy to forget to add/remove something to it and you’d end up with improperly updated template.
Tom, my main point here was that using entity_id: sensor.time wouldn’t break the TS’s template but the template will not be re-evaluated immediately when say, sensor.hvac_operating_state changes it state.
Not sure it’s a welcomed side-effect.
Fair enough. I was just saying this isn’t such a chore as the template is right near the entity_id key and I have made a consious point of checking whenever I change a template.
Your assumption is correct. When entity_id is employed, its list of entities is used in lieu of the template’s entities. This simple Template Sensor demonstrates that:
It will be evaluated only when sensor.time changes and not when the input_boolean changes. In other words, the inclusion of entity_id means Home Assistant doesn’t inspect the template to find eligible entities to monitor (for state-changes) but simply defers to using the entities listed in entity_id.
When I wrote " just add the following to its configuration" it was meant as an alternative to re-writing the template (i.e. your suggestion to use sensor.time instead of now() for the time test). I should have been more precise and indicated that all entities used in the template ought to be listed in entity_id.
The reason I made the suggestion is because it requires a lot more gymnastics to get the current timestamp using sensor.time compared to using now().
@AhmadK, mea culpa. Once pointed out I recognize that page from reading it months ago but was looking in the wrong place, trying to find some kind of update frequency like you can add for some sensors. Thank you!!
@everyone-else:
So let me make sure I understand: if I add an entity_id of sensor.time I get by-minute updates, but I lose updates caused by changes in the other entities. I can, however, use automation and update_entity, and if I do that it updates on that schedule, but will ALSO update with any other entity state changes as well. And with automation I could condition the update on attribute state, e.g. avoid minute-by-minute updates unless the A/C is running.
That exclusion/inclusion seems a rather defining aspect of the two approaches.
And no one else seems to feel the sensor.time is deprecated.
Thanks everyone, amazing amount of help so fast. Thank you thank you.
Looks like that. I’d rather say that one need to be more careful when using now() (but they’ll be fine as others already bumped into it and added some useful info/examples to the docs so keep on checkin them).
On the other hand, sensor.time has its limitations (as it cannot be easily used with datetime objects and some"gymnastics" is required) so what approach to use depends on each case.
Good that you have it sorted!
p.s have a look at the epic topic and the docs.