The way you have it now, it is going to render every time ‘sensor.time’ state changes (every minute or 1440 times a day) or when the ‘alarm_control_panel.ha_alarm’ state changes. Add this to the top of template to get it to work the same way:
{% set x = states('sensor.time') %}
Ideally we give you a way to make a time_interval sensor that only updates every hour so you could do
{% set x = states('sensor.time_that_updates_every_hour') %}
so it would only re-render when ‘sensor.time_that_updates_every_hour’ changes (24 times a day) or when the ‘alarm_control_panel.ha_alarm’ state changes.
Well you really only need one that updates at 9am and 5pm but 24 times is still a lot less than 1440 times a day so you could build an automation that fires at 9am and 5pm and calls homeassistant.update_entity on it which would mean it would only re-render 2x a day + any state change of ‘alarm_control_panel.ha_alarm’
So I remember back when we didn’t have to specify an entity_id at all and then we started getting warnings that the template didn’t know when to be evaluated and to add the entity_id… so this is now changing again and I need to remove all the entity_id entries from my sensors? Ok… so will there be a warning if the template can’t be evaluated again then so I will need to know I need some other magic to make it work?
The new system can always find all the entities and there isn’t a case where the automatic detection can fail anymore so there isn’t a warning about this anymore. The only time you would need to do manual evaluation is where there are no entities in the template or you have something like the now() case mentioned above.
I built an integration to create time_interval sensors, and then thought about adding something like refresh_time_patterns as it would be a lot more efficient than having additional state machine updates or tracking sensor.time:
# Example configuration.yaml entry
sensor:
- platform: template
sensors:
display_night_cards_armed:
friendly_name: Display card between 9PM and 5AM and Alarm Armed
value_template: >
{% set ct = now().hour + now().minute/60 + now().second/3600 %}
{{ (21 <= ct or ct <= 5) and is_state('alarm_control_panel.ha_alarm','armed_home')}}
refresh_time_patterns:
- hours: "5"
minutes: "0"
seconds: "0"
- hours: "21"
minutes: "0"
seconds: "0"
every_zero_second:
friendly_name: Time every zero second
value_template: "{{ now() }}"
refresh_time_patterns:
- hours: "*"
minutes: "*"
seconds: "0"
I’m still not sure if that picks up all the use cases.
Over the past 2 years, I’ve seen a lot of Template Sensors and the majority that needed periodic ‘prodding’ were well served by either sensor.time or sensor.date. I question the need for the dizzying amount of scheduling power and flexibility proposed in that example.
If someone needs something other than once a minute or once a day, they can use the (upcoming) documentation’s suggestion and use a Time Pattern Trigger in an automation that calls homeassistant.update_entity.
I think you are spot on. There are already multiple solutions here, and we do not need another one. The automation option is efficient, already has a nice UI to manage it, and doesn’t add any additional maintenance burden.
Just brainstorming but what if the Time & Date integration was enhanced so that its sensors had datetime objects as attributes? For example, if sensor.time had a time object, sensor.date had a date object and sensor.datetime had a datetime object.
Instead of using the now() function in a template, (to do some time arithmetic) I can use sensor.time and refer to its time object attribute (and employ its methods). My template has an identifiable entity, namely sensor.time, which isn’t just there to ‘prod’ for updates but is actually part of time calculations I would have otherwise used now() to perform.
EDIT
Actually, I would probably use sensor.datetime’s datetime attribute because that’s more like now().
If the entity_id is no longer defined, how would you know it would still be vacuum.robotrock…? This confuses me a little, since it was referencing the state of the entity_id, which is now not set manually. Maybe someone can explain this for me? I admit I’m not too familiar with template sensors within hass. Thanks.
There’s a clever function that scans the template for entity ids to monitor. This was the case before too. It’s just that it is much better at it now. So there’s no need to explicitly list them now.
I have seen in the documentation PR by @bdraco this trick used.
{{ states('sensor.time') and now() }}
states('entity_id') when provided with any entity_id valid or not returns as true so only the expression to the right of the and statement does anything useful. The entity_id in states() is only there for the parser.
True, but an int can remedy that whereas converting UTC to local time is messy.
Misunderstood your point about the microseconds.
All this to say that states.sensor.time.lastupdated is more like using utcnow() than now(). The user needs to keep that in mind if they intend to use it in their date calculations.
I think the takeaway is that states.sensor.time.last_updated can be useful but should be used judiciously because it isn’t the equivalent of either now() or utcnow(). As you mentioned, it’s sensor.time after all so it only has 1-minute resolution and last_updated is UTC-based.
That’s also good advice for existing Template Sensors that use this:
entity_id: sensor.time
and then proceed to use now() to perform time arithmetic that look for sub 1 minute differences. The darn thing is only going to be evaluated every minute so looking for, as you mentioned, a 30-second difference would be a mistake. You’re obliged to look for differences in whole minutes.
Hopefully, very few people have made that mistake.