Improve efficiency of time-related templates

Hi all
I’ve been at this for about 18 months now and my configuration is slowly getting more complex - my hardware is nowhere near full in any sense, but as I pile more stuff in I am beginning to wonder if some of my coding is rather inefficient - in particular, with time-related templates being evaluated FAR too often. Here’s an example - its the code for a template helper.

    - name: Event Waste Garden
      state: >
        {% set midnight = today_at() %}
        {% set event = state_attr('calendar.waste_garden', 'start_time') | as_datetime | as_local %}
        {% set delta = event - midnight %}
        {% if delta.days == 0 %}
          Today
        {% elif delta.days == 1 %}
          Tomorrow
        {% else %}
          In {{ delta.days }} days
        {% endif %}

Now, this works perfectly: my concern is that according to the template testing tool, this expression is reevaluated every minute … when, really, it only needs to be evaluated once a day. I have lots of similar things going on!

One thought would be to refactor this completely - take everything that I know only changes once a day and write a script, automated to run just after midnight, that recalulates all the helpers like this one.

Another thought is to wonder if I can replace today_at() (which, AFAIK, is what is being recalulated every minute) with a different method that is only tested daily.

Any thoughts?

The “correct” way to do it is probably a trigger-based template entity that only runs once every midnight.

1 Like

Thank you, that’s very helpful - I’ve not looked at those before (there are so many bits in this system!).

In the meantime, I also came up with this approach which I think might have the same result

sensor:
  - platform: time_date
    display_options:
      - "date"
      - "time"
template:
  - sensor:
    - name: Event Waste Garden
      state: >
        {% set thisday = states('sensor.date') | as_datetime %}
        {% set event = state_attr('calendar.waste_garden', 'start_time') | as_datetime %}
        {% set delta = event - thisday %}

(etc)

If I read it correctly, that will trigger if sensor.date changes, ie once a day, but with the bonus (in this example) of also updating if the calendar updates.

Mayhem_SWE’s suggestion to use a Trigger-based Template Sensor can achieve both and without the need of a Time_Date sensor.

FWIW, the technique you demonstrated is what was done before Trigger-based Template entities were introduced.

1 Like

More thanks for that clarification. It’s not always easy to know what is current best practice and what is last-years-news, especially when trawling this forum for ideas!

Anyway I now have several improvements available to me. I’ve just identified one sensor that was being updated once a minute, when it only changes every six months! (I think I’ll be using a Calendar to fix that one).

1 Like