Heads up! Upcoming breaking change in the Template integration

No don’t use mine. I just went through the template and it doesn’t match your functionality. It’s a threshold for the state, not the zone number. Use your old template.

I understand how that might be perceived to be the general-purpose solution (‘shoehorn the entity_id into the template’) but I feel it only applies to a specific case: the template itself lacks appropriate entities.

The classic example is a template that uses now() to do some date arithmetic (for those who don’t know, now() is a function, not an entity). The usual workaround is to add entity_id: sensor.time to cause the template to be updated once a minute (i.e. when sensor.time changes state).

In an upcoming release, you will no longer be able to do that because the entity_id option is deprecated. The first few posts in this growing thread discussed a proposed workaround where you simply add the following to the template:

{% set x = states('sensor.time') %}

Although it may feel like a band-aid solution, it’s really no worse than the old workaround of adding entity_id: sensor.time. It’s the same principle, ensure sensor.time is identifiable.


Exploring new possibilities:

One way to make it feel less like a kludge is to use sensor.time in one’s date arithmetic as opposed to employing now(). bdraco pointed out that this:

states.sensor.time.last_updated

is a datetime object and so we can use that to get timestamp, year, month, day, hour, and minute. However, there are caveats because it’s UTC time and only provides resolution to the nearest minute, not second. Converting it to local time is currently a messy proposition so bdraco proposed a new filter called as_local to easily convert a datetime object from UTC to local.

To reiterate, all of this applies to the case where the template had no identifiable entities and sensor.time was employed to ensure the template is evaluated every minute.

Yes

the “clever code” (as tom puts it) will read your template, work out what states are affecting it, and monitor those.
The issue comes where you used (say) sensor.time (as an entity_id: ) to trigger an update in (say) a sensor that only had (say) now() in it.
now() is a function, it changes on a millisecond basis, no listener (or whatever they use) can be assigned to it, so we have to introduce something to which a listener can be assigned.
So rather than just {% embed %} sensor.time (or whatever) to make the template be re-evaluated (using now() ) we actually use sensor.time to generate a timestamp that we can use directly instead of now(). [This is to shorten and simplify the resulting template].
So far the alternatives look a little long winded in these particular usage cases but bdrago is woking on his as_local() to contract it producing local time rather than working out if dst is applied or not then doing this offset or that offset.
These are quite esoteric outliers and most people won’t be affected by them (they just will be prompted to remove the entity_id: portion AND maybe (This would help people in general) be prompted to look at the release notes on dealing with the loss of entity_id: IF it contained sensor.time)
[Not all would need tweeking though - I have schedules set up that just compare sensor.time to (say) states(‘input_datetime.id_time’) [0:5] ]

Edit: @123 SNAP !

Edit2: Also the template checker (not sure what it should be referred to as (clever code is as good as anything but … ) is just an update on the current (slightly less clever code) that has the ability to make dramatic improvements in performance.
The point is that the ‘old way’ was not without it’s problems. Say I had 5 entities that were in my old template and I didn’t have an entity_id: section, the template would work as intended UNLESS it had one of the outlier cases above. SO I introduced the entity_id: section and listed only 4 of the 5 used entities. This would tell the less_clever_bit_of_code to ignore the fifth element (see what I did there ???)
The New code is more bullet proof than that BUT you need to tell it EVERYTHING it needs to work out what it should be doing (no change there then, when writting code in general)

2 Likes

I can’t think of a quick way to convert a UTC datetime object to a local datetime object. For example, timestamp_local converts from UTC to local but produces a string. Yes, I can slice the string to get the parts I want but that’s less convenient than if the result remained a datetime object.

I think I would prefer : -
states.sensor.time.last_local
or somesuch, but the amount of work that would require and the crannies explored and the things it would thus affect … Yeah go with the filter/function thang !

4 Likes

Many Thanks Kind Sir
Do you think this will also make it into 0.115.0 ???

It is a very small so it seems likely, but there are lot of PRs waiting for review so there are no guarantees it will make 0.115.

With all the WTH PRs 0.115 is going to be loaded!

afraid I cheered too soon. Only sensor.time updates the templates now. Must have been a cache thing…

Will add the entity_id’s back to the large timestamp sensor, which is the triggering entity_id for all other sensors, and await the result.

Were you running a 0.115.0 Beta ?

no, heavily awaiting that, but there’s no beta live yet?

Yeah I didn’t think so (wasn’t sure)
So how/what were you testing ?

I was thinking that.
Let’s hope the release notes are up to the job :grin:
Speaking of which, I used top be able to find them before they were live but now I can’t.

Can someone point me in the right direction.
I like to be prepared :wink:

1 Like

this :wink:
Sep-03-2020 17-21-53

left my browser window, right, the new HA Mac app

and this sensor

They get released with the beta, which has been pushed back. See:

1 Like

I have a template sensor defined to work with the Alexa Media Player integration to get the last device which was used. It looks like this currently:

last_alexa_device:
  value_template: >-
    {{ states.media_player 
        | selectattr('attributes.last_called','eq',True) 
        | map(attribute='entity_id') | first }}
  entity_id:
    - media_player.bedroom
    - media_player.computer_room
    - media_player.kitchen

Would the new template parsing work with this without entity_id or would I be better with something like this?

last_alexa_device:
  value_template: >-
    {{ [states.media_player.bedroom, 
        states.media_player.computer_room, 
        states.media_player.kitchen] 
       | selectattr('attributes.last_called','eq',True) 
       | map(attribute='entity_id') | first }}

Until bdraco supplies the definitive answer, here’s my guess:
First version gets listeners assigned to every media_player you have based on states.media_player (and assumes you remove entity_id, because it’s deprecated).
Second version gets three listeners assigned, one for each of the identifiable entities.

from my understanding of what @bdraco said, the template now searches for accessed state object instead of regex string parsing. So if your template access a state object, that state objects entity_id is added to the listeners.

Yeah, I think you’re correct.

And in @Mariusthvdb’s case, his weekday changes will only update during the weekdays and his weekend changes will only update during the weekend. So he should use the rewritten macro. Unless new listeners are dynamically added (and never removed). Then his template will work after a full week has passed.

@klogg’s should work all the time.