Heads up! Upcoming breaking change in the Template integration

Is this in the 0.117 beta?

I should check it.

Yeah it was rolled into beta2 (going final today). I was hoping to receive some feedback during beta time but not getting bug reports is a good start :slight_smile:

1 Like

I’ll do some tests now.

EDIT: all working as described. Templates with now() are updating on the minute.

have been busy with some diehard issues and bug reports on the new template type consequences…

they are still not ironed out, but don’t have to do with either frequency or entity_id limiting, so haven’t reported here because of that.

all templates that had the {% set trigger = states('sensor.time')%} because the use now() now behave very nicely indeed without that.
That is to say, they update once a minute.

the ones that had that and have other recognizable entity_id’s can’t be limited any longer either by setting an entity_id or frequency (id). Which I still feel as a limitation of the toolset.

so yeah, mixed feelings will linger. Grateful though for all the efforts being made

Thank you for confirming.

Right, that is still a limitation compared to the previous template engine (well, it was more of a bicycle before). I am also a bit sorry that it is gone but … yeah, Hue lights are polled every five seconds, it is what it is.

If the limitation causes observable problems (other than to your guts) I am still interested in YAML showing the issue.

cool, will do. but first things first now, eagerly awaiting the results of this: https://github.com/home-assistant/core/pull/42494

to get my rest_command templates working again. Hope this makes it for todays release if 117.0 !

after that, I’ll throw my original Unknown, Unavailable, None template in 117 and see what happens… :wink:
exciting times.

btw, if I may Taras, I invite everyone to hop over here meanwhile and help me out finding a way to prevent these template Undefined errors…

2 Likes

I have a sensor with a for loop with if statements. eg.

{%- set domain = states['sensor'] -%}
{%- for item in domain if ("docker" in item.entity_id | lower and "status" in item.entity_id | lower and item.entity_id != "sensor.docker_status") -%}

Is it possible to have it updated less than each minute, like /10 of a minute?
To save processor uses?

No, that’s not possible anymore.
However running this template once a minute or every 10 minutes will not have any significant impact on performance.

just for reference here (too): yes! it has been solved by Frenck and Paulus: rest_command working again, with the original templates. No need to change the format at all. very nice!

With 0.117 it should actually update each second because you are using a single domain, not all states. This is still not expected to have a visible performance impact.

Maybe you can optimize it anyway, using a group. Giving advice is easier if you show the full template though.

I think I’ve hit a snag with the new template updating system.

I have a sensor, sensor.sleep_start_time that reports in the format HH:MM, e.g. 01:29 (from the Fitbit integration). I would like some long term stats on this, however I don’t seem to be able to graph this sensor in Grafana. I think I need to convert it to an iso datetime object for this to work.

Ideally the template sensor for this would only update when sensor.sleep_start_time changed to make sure the correct day is added. However using any form of now() is going to update it every minute. Using sensor.date has the same issue, but less often.

The sensor updates at any time (when the device is synced) which is always unrelated to the time state reported, so using the sensor’s last_changed attribute does not work.

My only thoughts are to trigger an automation on change of sensor.sleep_start_time and publish to an mqtt topic the current date-time with the hour and minutes replaced from the sensor. Then create an mqtt sensor.

Seems messy.

Any other ideas how I can accomplish this?

EDIT: never mind iso datetime object wont work either. The days will keep increasing and I only want to compare the times. So I ended up using the decimal hour representation:

{{ (states('sensor.sleep_start_time')[:2]|int + states('sensor.sleep_start_time')[3:]|int/60)|round(2)}}

Not sure if this is the right thread to post this in. I have an automation to update template sensors that only have the now() function. They would update every hour or so, depending on what I needed. Now I understand they will update every minute due to the now() function, so the automation is obsolete.

The sensor template looks like this (this one adjusts the thermostat in the morning to something more comfortable before we actually get up for coffee):

    prep_hvac_for_wakeup:
      friendly_name: Prep HVAC for wakeup
      value_template: >
        {% set delta_between_now_and_midnight = now().timestamp() - now().replace(hour=0).replace(minute=0).replace(second=0).timestamp() %}
        {% set target_start_timestamp = state_attr('input_datetime.morning_wakeup_workday_start','timestamp') - state_attr('input_datetime.pre_condition_morning_hvac','timestamp') %}
        {% set target_end_timestamp = state_attr('input_datetime.morning_wakeup_workday_start','timestamp') %}
        {{ ((delta_between_now_and_midnight >= target_start_timestamp and delta_between_now_and_midnight < target_end_timestamp)) }}

It checks to see if the current time (now()) is within the times specified by the input_datetime values. If it is, then the {{logic above}} returns true

I have similar sensors to trigger various time frames throughout the day (morning, late_morning, afternoon, etc) to adjust thermostats and other things.

Is there a better way to do this so it’s not updating every minute because of now()? Or… maybe updating a few sensors every minute when they don’t need to is not a big deal on the ol’ CPU.

Thoughts?

And the discussion in this thread is very interesting and helpful!! Thanks, @123 and @petro and @frenck for the helpful discussion!! I hadn’t updated since maybe 0.114, and it didn’t take long at all the hunt down and eliminate the entity_id statements in my templates.

No (and the workaround is impractical).

When you paste that into the Template Editor, it will report what it listens to for changes. The presence of the now() function ensure the template will be evaluated at least once a minute.

The only way around it would be to replace all instances of now() with some other time-based sensor that only change state every hour. However, that makes the entire template have a coarse resolution (hourly) and that negatively affects your time calculations.

Thanks, @123, for the answer. Kind of what I thought. I do appreciate having the now() function update the sensor/binary_sensor. I don’t know how many times I fell into that trap of creating a sensor with now() and then not having it update as I intended. Again, thanks for the effort on this!

1 Like

Right. Don’t worry about it.

1 Like

Jedi Mind Trick:

“These aren’t the extra CPU cycles you’re looking for …”

1 Like

@amelchio and @123 - you guys are a hoot - I’m not worrying about anymore!! Thanks, again, for the advice and help.

I don’t know if this has been covered here or somewhere else (and if it has and/or there is a better way to do it) and if so my apologies but…

I had been struggling to find a way to have a template update on the second aside from needing to rely on the states.DOMAIN listener.

I finally worked out a way to do it. It’s kind of ‘hacky’ but I believe that this is exactly the way the devs now expect us to do this sort of thing.

you need two things to make it work:

counter:
  one_second_update:
    initial: 0
    step: 1
 
automation:
  - alias: one second update
    trigger:
      platform: time_pattern
      seconds: '/1'
    action:
      - choose:
          - conditions:
              - condition: template
                value_template: "{{ now().second == 0 }}"
            sequence:
              - service: counter.reset
                entity_id: counter.one_second_update
        default:
          service: counter.increment
          data:
            entity_id: counter.one_second_update

This creates a continuously running counter that mimics simulates a one second resolution clock. Once it gets to 59 “seconds” it resets back to 0 like a regular clock would.

The reason why I stress “mimic” is that the counter won’t match the seconds of time in the real world.

You can use the state of the counter to force a one second update interval in any template in the same manner as using sensor.time used to do for one minute update intervals.

as an example for its use:

trigger:
    - platform: template
      value_template: >
        {% set update = states('counter.update') %}
        {{ (state_attr('input_datetime.both_date_and_time', 'timestamp') - now().timestamp()) <= 0 }}

Which would work great if the bug found by @123 (and posted to github by him almost 2 weeks ago (link) would be fixed to actually allow using now() in a trigger and have it work.

But you can still use it in template sensors or in dev-tools to test templates with one second update resolution.

EDIT: I updated the automation to reset the counter to 0 at the start of every minute so the counter should always be within 1 second of the actual real world seconds. The only time this won’t be true is after a HA restart (or eventually when we get a counter reload service) until the counter and now().seconds synchronize which will happen in less than a minute after HA restarts or counters get reloaded.

It’s just cleaner that way.

Maybe I am missing your point, but why don’t you use the service homeassistant.update_entity in the automation, for the sensors you want to update each second ?

It’s not about updating sensors by using an automation. Of course if there were only a few sensors you wanted to update every second and that’s all you wanted a one second resolution update interval for then I would agree.

But remember you need to first build the sensor and then create an automation to cause the one second update for the sensor.

using this update counter you can use it directly in the sensor template just like we used to need to do when we used sensor.time to update every minute. Then there is no further update automation required. You just have one automation and one counter updating every second in the background.

And it also allows you to use it in automations to compare now() to a date_time down to the second where right now it only works down to the minute without it (as in my example above).

Or it allows you to use it in dev-tools to auto refresh the page every second to test templates at one second resolution.

My point is that there are more than one use for this function aside from just updating sensors and it makes that sensor update functionality easier to do.

AT least, IMO.