Template sensor doesn't recalculate on attribute change

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?

And is there a better way?

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.

      entity_id:
        - sensor.time
        - sensor.hvac_operating_state
        - sensor.ac_split_ambient_temp
        - sensor.ac_split_cold_temp
        - sensor.hvac_operating_state

I believe that using the sensor.time in this manner has been deprecated.

I find that very hard to believe.

Where’d you get that information from?

index

A reference for that deprecation would be appreciated.

2 Likes

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.

Happy to be wrong here.

1 Like

Not so much wrong as different strokes for different folks.

I have no problem with maintaining the full list of entities used in the template.

2 Likes

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.

1 Like

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:

      example1:
        entity_id: sensor.time
        value_template: >-
          {{ 'hello' if states('input_boolean.toggler') == 'on' else 'goodbye'}}

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().

2 Likes

You mean : - “It’s A Royal Pain In The Ass”

@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.

No, the template will still update on state changes of the other entities if you list them along with sensor.time.

1 Like

Ah… it’s really clear in the writeup, I don’t know why I interpreted it as only including these fake entities. Thanks again.

Compared to other home automation systems I’ve used, date/time arithmetic in Home Assistant can definitely be that.

In fact, finity wrote his doctoral thesis on this very subject: :slight_smile:

2 Likes

It is the ‘Holy Text’ when it comes to ‘time’ (but don’t tell finity I said that) He’s got a big enough Head already !

:rofl:

1 Like

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.