WTH, Getting an accurate time reference in that automatically re-renders in templates is so complicated now

There has been a rather long discussion in Heads up! Upcoming breaking change in the Template integration about how to deal with rendering now() in a template now that manually placing sensor.date in the entity_id: line of the template has been deprecated.

So far I have seen some methods of how to deal with it, but none of which seem to be an optimal way compared to the old method.

  1. Use {{states.sensor.time.last_updated}} as a substitute for now()
    What it can’t do… On the initial rendering of the template sensor.time returns a time in the past, not the current time. The time value of the template is only accurate when sensor.time changes state, not when any other entity in the template changes state, unlike now() which always returns an accurate time when any part of the template is rendered. This method won’t work if precision is required.

  2. Use {{now()}} but manually refresh the template via an automation.
    This method is the most accurate. The user must now keep track of instances of now() and have to create an automation, blacklist in in logger, and recorder to keep it from spamming the logs/db. I think this is only an option for template sensors and not template triggers.

  3. Trick the parser into including sensor.time in the entity_id list to render by using {{states('sensor.time') and now() }}
    This has been the least intuitive method I have tried, especially when combined with if-elif-else statements. The user would have to know exactly which part of the template to place it where it would trigger a rerender, so the safest option would be to put it in every single template that uses now() .

Number 1 is the easiest, but slightly inaccurate. Number 2 is the most concise as far as writing templates, but now the user has to manually refresh, and it may not work outside of template sensors. Number 3 seems most hackish of all and makes for messy templates.

It would be nice if there custom templating function that behaves like now() as that it immediately returns the current time upon rendering but also triggers a template rerender at 1 minute intervals. We need a solution that is both concise and will work everywhere a template would be supported.

or the easiest… Keep your template the same but add this line before it

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

I think it would be great if we could just add a special scan interval that would update periodically… or utilize time_pattern functionality:

scan_interval:  60 #every 60 seconds from startup
scan_interval:
  minutes: 1 # every minute from startup.
scan_interval:
  minutes: /1 # every minute on the minute.
scan_interval:
  hour: /1 # every hour on the hour.
2 Likes

Your post appears to confuse two distinct needs:

  • To evaluate the template periodically
  • To acquire the current time

Petro’s reply covers the periodic part and you can continue to use now() for current time. Done and done.

if we update scan interval to work with time patterns across the board then add it to template sensor, it basically get the job done with the added benefit of working everywhere.

Sounds like an interesting Feature Request. It’s like the documentation’s suggestion to use an automation to periodically execute homeassistant.update_entity for the Template Sensor, only much simpler.

Won’t request a template to be re-evaluated (never has) [well, there are were some really weird exceptions to that but not for 98% of use cases) as now() is just a function call ]

But all other state changes occur on the minute (“sensor.time” anyone ???)

You can create a timestamp value from sensor.time if you want (read the thread you refer to)
So how else are you going to trigger an update ???
petro suggests one answer
But the ‘old’ traditional way was to have an automation that updates individual (or a list (or ALL) of them) sensors

I’m not quite sure why you’d need that
bdraco 's solution was to create a new function acting (say) on sensor.time (so it will be updated every whole minute) with : -
as_local(states.sensor.time.last_updated)
You object to this as you say you need ‘more accuracy’ - why ? - name 3 instances ?

You also say : -

Why ?

  1. We’ve already been through that normal states don’t have template updates triggered more frequently that 1 minute intervals.
  2. If you have an event or a device staus change that triggers beween the ‘minute’ - now() can still be used and you can still measure intervals by looking at last_changed(of whatever) to now()
  3. If you have : -

(functions don’t update, we’ve said this before) but assuming you had a state that changed every second, you are then consigning everything (using that) to be evaluated every second of every minute of every hour of every day. Thus helping to negate 95% of bdraco 's work on the performance improvements. ( now() has MICROsecond resolution, so surely you can’t be proposing that )

I’d love to see the 3 usage cases, hell - just one to be going on with, whilst you think of the rest.

Edit : There was a moment in the thread you refer to where I had the same opinion as you, Then in the same post I had a lightbulb moment - ALL we ever look at is historical events, it’s just the time-frame that changes. We are not recording Usain Bolt’s lastest World Record attempt here, we are turning light bulbs on and off. But we can make it so you can gain access to such levels of detail, but don’t mistake detail for accuracy.

The 0.117 beta adds auto-refresh to now(); using it will force the template to refresh every time a new minute starts.