Heads up! Upcoming breaking change in the Template integration

It’s off-topic (python code to emulate expand) but maybe someone else can help.

It’s choosing between which group(s) to use with an if-else. I suppose you could use an inline if to shorten it a bit. You don’t need to use a namespace with an if-else so that eliminates one line. :man_shrugging:

Note that

expand(...) |

is not a substitute for

entity_id: ...

Rather, it is an alternative to the filtering:

states | selectattr('entity_id', 'in', [...]) |

To me it looks like a shortcut more than a detour.

sure, I understand that.
it’s just that the expand() function limits the updating of the template to the entities in the group that is expanded, while the states | filtering created listeners on all entities.

limiting the entities listened to is the important thing here, so that’s why I ‘compared’ it to the former entity_id:

so yeah, shortcut or detour, suppose getting there is most important :wink:

you’ve got to admit, it’s not the most obvious way of doing things though.

hear you, will post in a dedicated thread, sorry.

not really sire what you mean with this? Are you saying I should template it all inside the template itself? Isnt the beauty of this, one creates a namespace, and handles that with the filter outside the template? Or do you mean something else.

You don’t need to use namespace.

        {% if is_state('group.guests','not_home') %}
          {% set x = expand('group.all_inside_lights') %}
        {% else %}
          {% set x = expand('group.main_inside_lights' , 'group.living_ceiling_spots') %}
        {% endif %}
        {% set lights_on = x | selectattr('state','eq','on')|map(attribute='entity_id')|list %}
        {{lights_on|join(', ') if lights_on|length > 0 else 'none'}}
3 Likes

thanks!. you’re right, now why I had that I can’t remember… good catch.

since we’re talking efficiency too here, I wonder if there’s any preference using either of these:

        {%- set ns = namespace(below=0) %}
        {%- for s in expand('group.battery_sensors')
          if s.state|int < states('input_number.battery_alert_level')|int %}
            {%- set ns.below = ns.below + 1 %}
        {%- endfor %}
        {{ns.below}}

          {% set alert_level = states('input_number.battery_alert_level')|int %}
          {{expand('group.battery_sensors')
            |map(attribute='state')|map('int')
            |select('<',alert_level)
            |list|count}}

would creating the namespace be more costly for the system?

since you asked for examples of templating frequency needs, please have a look here

Have a couple of situations at hand where I do need an update per second. Of course, without trying to overload the full system with that.

What I always wanted to know, but was afraid to ask… can’t we sense the systems heartbeat, ie have a sensor.second or sensor.heartbeat. Would be cool if that was supplied via core, so not causing any extra processor %, and use that in a template using now(). On a single occasion, where once a minute is way behind the needs for that single purpose.

thanks for having a look

@finity @anon43302295

Rate limit is dropped to 1s from 1 minute on {{ states.domain }} templates after bringing up this discussion.

FYI

Appreciate the tag, but I’ve got to be honest that this is getting really confusing. People are putting a lot of work into rewriting vast swathes of their configuration only for the goalposts to move again a couple of weeks later.

I can’t even tell now whether my templates are going to do what I want, whether they will update on a state change, every second or every minute, which ones I need to manually override with an automation to speed them up etc.

This puts me in a position where I basically have to wait for something to fail before I realise it needs fixing, which is the opposite of the proactive approach I usually like to take.

4 Likes

Good discussion.

FWIW, although the proposal to implement glob is appealing, the examples you provided illustrate a point I made elsewhere: an entity’s object_id shouldn’t be used for storing meta-data. Custom attributes are best suited for meta-data.

For example, by including the word “energy” in each entity’s name, it becomes a challenge to create a template that selects all energy-related entities. The proposal is to support glob so that the template is simplified to:

 {{ new_glob('sensor.node_*_energy') | map(attribute='state') | map('float') | sum }}

where new_glob('sensor.node_*_energy') is the new feature.

Although I like the proposal, it encourages the practice of using the entity’s name (object_id) to store meta-data. I don’t think that’s a ‘best practice’.

What can be achieved now is to simply create a custom attribute for each energy-related entity, such as type: energy. In other words, instead of creating long-winded entity names, loaded with meta-data, keep them short and put the meta-data in custom attributes. Then the template can be:

 {{ states.sensor | selectattr('attributes.type', 'eq', 'energy') | map(attribute='state') | map('float') | sum }}

Multiple attributes (standard and custom) can be employed to make it highly selective:

 {{ states.sensor
     | selectattr('attributes.device_class', 'eq', 'power')
     | selectattr('attributes.location', 'eq', 'garage')
     | map(attribute='state')
     | map('float') | sum }}

It’s a throttle. When this PR is accepted, you can have at most 1 update per second when using states. The current implementation is at most 1 update per minute.

Well, that thread/issue was my compromise to the issue that @finity and @anon43302295 brought up: states.domain/states are throttled to update only once a minute. I was also trying to get a 2 birds one stone by ninja’ing in a poor mans "contains test for selectattr" through this new_glob method.

I appreciate the effort to rectify the throttling problem, I don’t think it ultimately fixes the overall issue.

as of before we had two choices - update when a monitored state changed or at most every minute.

Now we have two choices - update when a monitored state changed or at most every second.

What happens if we want a sensor to only update once a minute or once a day?

There’s no way to control that at all.

Even if you set up an automation to update the sensor at the desired periodicity the sensor will still update itself whenever one of the monitored entities change. If that happens before the automation triggers then it will update then in addition to when the automation triggers it to update.

Not to mention that even if the automation control worked as desired (which it won’t) then that still requires you to create an additional automation to control the update when before it was as simple as adding one line of code to the sensor config.

the change added (unforeseen?) complexity and minimized user control.

I still don’t see why the additional user controls were nixed especially when the work was already done to implement the functionality.

I wish someone could give a logical rationale for that decision besides “because I said so”.

the rationale is because the users have to specify an entity_id with every template for all integrations that need it. If the control done through the single template, the second field isn’t needed. Right now, there’s a ton of templates that do not have the entity_id control (prior to it’s deprecation). Those places all cannot update properly. The main goal of the change was to remove the need for entity_id while simultaneously providing a solution for all template fields.

The reason I received was that restoring entity_id would only address Template-based entities and not Template Triggers. Although I felt the urge to say “Yeah but that was the status quo up until 0.115!”, I didn’t. It’s clear to me that the driving force is to invent a comprehensive solution (wherever templates are used).

I should point out that this was, for me, an unsatisfactory reason for eliminating entity_id. I still believe it was removed with good intentions (simplification) but without a full appreciation of the consequences (loss of functionality).

2 Likes

And it failed in that goal.

The proposed update controls seemed like they would have worked but they were nixed after the work was already done. That’s the part that makes no sense and I haven’t seen a logical answer to.

So now I can’t even predict when my template will update?

Might be every state change, might be every second, might be every 10 seconds, every half minute, every minute…

This is completely brain boggling.

It’s updated when a state change occurs but throttled to at most once per second. So you’d rather have it only update on a period and not update on state changes? If that’s the case you’d have delays in your responses…

seems to be some confusion goin on indeed.

The current PR makes the templates update per second when using {{states.DOMAIN|xxx}}, and per minute when using {{states|xxx}}

2 Likes

Never mind; read it wrong the first time …