I have a trigger-based template sensor using a time pattern that’s supposed to update every minute, but it isn’t. It used to work fine, as far as I can tell. I only noticed this issue yesterday after a restart. I didn’t upgrade or perform any other updates. I made some config changes to my configuration, but not to this. HA Core 2024.3.1.
Here’s the sensor’s config:
- trigger:
- platform: time_pattern
hours: "*"
minutes: "*"
seconds: 0
- platform: state
entity_id:
- number.capacity_point_1
- number.capacity_point_2
- number.capacity_point_3
- number.capacity_point_4
- number.capacity_point_5
- number.capacity_point_6
sensor:
- name: "Capacity Charge Point"
unique_id: "12b69471-fdbc-4f9a-9a75-960545211e3e"
state: >-
{%- from 'resources.jinja' import get_current_entity_id -%}
{{ states(get_current_entity_id('number.capacity_point_')) }}
attributes:
current_entity_id: >-
{%- from 'resources.jinja' import get_current_entity_id -%}
{{ get_current_entity_id('number.capacity_point_') }}
# not really, but we get dynamic icons this way
device_class: battery
unit_of_measurement: "%"
This is suppose to trigger every hour of every minute or when one of the listed entities changes. All this really does is to pick the correct entity ID’s value, since these entities have a value for different timeslots of the day. I use this sensor purely for display purposes to show me the current value.
Here’s the macro:
{# https://www.home-assistant.io/docs/configuration/templating/#reusing-templates #}
{#
Get the index for the current work mode slot and add it to an entity ID prefix.
:param entity_id_prefix: An entity ID prefix (i.e. including the domain).
:returns: An entity ID after adding an integer to the prefix.
#}
{%- macro get_current_entity_id(entity_id_prefix) -%}
{%- set time = now().strftime('%H:%M') -%}
{#- these times must match the work mode timers on the inverter -#}
{#- could use a map too; whatever -#}
{%- if '01:00' <= time < '05:00' -%}
{{ entity_id_prefix }}1
{%- elif '05:00' <= time < '08:00' -%}
{{ entity_id_prefix }}2
{%- elif '08:00' <= time < '13:00' -%}
{{ entity_id_prefix }}3
{%- elif '13:00' <= time < '17:00' -%}
{{ entity_id_prefix }}4
{%- elif '17:00' <= time < '21:00' -%}
{{ entity_id_prefix }}5
{%- else -%}
{#- 21:00-01:00 -#}
{{ entity_id_prefix }}6
{%- endif -%}
{%- endmacro -%}
At 13:00 today (it is now just after 14:00), the value of 15% was supposed to change to 50%.
When I evaluate the template in the dev tools, it works as expected. It uses the correct entity ID and it gets the correct value (the third value is the current template sensor value, which is incorrect):
- sensor:
- name: "Capacity Charge Point"
unique_id: "12b69471-fdbc-4f9a-9a75-960545211e3e"
state: >-
{%- from 'resources.jinja' import get_current_entity_id -%}
{{ states(get_current_entity_id('number.capacity_point_')) }}
attributes:
current_entity_id: >-
{%- from 'resources.jinja' import get_current_entity_id -%}
{{ get_current_entity_id('number.capacity_point_') }}
# not really, but we get dynamic icons this way
device_class: battery
unit_of_measurement: "%"
the now() in your macro will force the template to update once a minute on the minute. Whatever state you grab for the main state will force updates from just that entity. When it switches to a new entity based on time, the template will listen to that new entity (instead of all entities at all times).
Outside that, your time_pattern is odd. I’d just have
I think I somehow thought the dynamically created entity IDs (number.capacity_point_*) wouldn’t be detected and thus subscribed to for changes, but given what you’re saying, I see I might’ve been wrong there. The one thing I did miss is that I have now() in there.
I think, for clarity (since the macro cannot be seen while looking at this piece of config), I might keep the time pattern to make it clear (to my future self) that it’s how it will be evaluated. The counter to that would be, should I want a lower resolution of updates (say every 5 min), then it will still update every minute due to the use of now(). I need to think this over.
You’re right about the time pattern too: That’s simpler and more cron-like. I think I copy and pasted this from an older example I had somewhere when I created this (and it’s also used in the docs).
Way back in the day, the template engine would parse the template and look for entity_id’s.
About 4 years ago, templates were rewritten. When the states function is called, the template will register a listener for the entity_id that the states function is calling.
Yes, has_value was a bug. I added the minutely updates to today_at and relative_time at the same time because it was stupid having to use now() with either of those to get the template to update.
This has been added as one of the Cookbook items.
Please review and edit for any changes there. I also suggest using that page as a referral.
I basically copied that post and included attribution, then added the cookbook tag and added a link in the cookbook index. At What Rates Do Templates Render & Update.