Template - how to search & count all entities that have "_tv" at the end of entity name?

Template - how to search & count all entities that have “_tv” at the end of entity name?

I try like this, but template returns all entities that have “_tv” in name.

{{states.media_player
 |selectattr('entity_id', 'search', '_tv')|map(attribute='state')
 |select('eq','off')
  |list|count}}

Maybe this?

{{states.media_player
 |selectattr('entity_id', 'search', '_tv')
 |rejectattr('entity_id', 'search', 'tv_')
 |map(attribute='state')
 |select('eq','off')
  |list|count}}
1 Like

Add a $ to the end of the search pattern, like this:

 |selectattr('entity_id', 'search', '_tv$')

That will only match strings that end with _tv and not strings that may contain it elsewhere. You can then remove the rejectattr filter because it’s no longer needed.

4 Likes

Is there a similar trick for the beginning of a string?

Yes, it’s the ^ character. It’s regex syntax so you can do many other things such as search for multiple sub-strings using (cat|mouse|bird).

However, if you use the match filter, instead of the search filter, it is designed to always match from the beginning of the string.

1 Like

Excellent. Thanks.

I have a similar issue where I need to search within a hourly weather forecast.
I want to extract the forecast-temperature which is forecasted for T14:00, can someone (@123 @tom_l ) point me in the right direction?
Unfortunately, I cannot just go with {{ state_attr('weather.home','forecast')[1].temperature }} because its a rolling forecast.
Thanks a lot!

This how the data arrives from the entity weather.home

temperature: 25.1
forecast:
  - condition: partlycloudy
    temperature: 23.8
    datetime: '2022-05-18T13:00:00+00:00'
  - condition: partlycloudy
    temperature: 23.5
    datetime: '2022-05-18T14:00:00+00:00'
  - condition: sunny
    temperature: 23
    datetime: '2022-05-18T15:00:00+00:00'
attribution: >-

Copy_paste the following into the Template Editor and confirm it produces the desired result.

{% set f = state_attr('weather.home', 'forecast') | selectattr('datetime', 'search', 'T14:00') | list %}
{{ iif(f|count > 0, f[0].temperature, 'unknown') }}
1 Like

It exactly does what I need! Thank you so much!

It works, but only if the value T14:00 is available. If its not in the list, the following error is thrown (in the template editor): UndefinedError: list object has no element 0
can this be eliminated to either throw “unknown” or “0”?
I think the ‘unknown’ in your code should do it? If so, that unfortunately does not work.

I just learned something interesting about the immediate if (iif) statement. Regardless if its test is true or false, it will always evaluates both of its arguments.

For example, in the following template, if f|count is not greater than zero, you would think that iif would only evaluate and report its second argument, namely unknown. However, it actually evaluates its first argument f[0].temperature as well. :thinking:

{{ iif(f|count > 0, f[0].temperature, 'unknown') }}

That’s a problem for this application because we want f[0].temperature to be evaluated only if the list f is not empty.

I suggest you use this version instead:

{% set f = state_attr('weather.home', 'forecast') | selectattr('datetime', 'search', 'T14:00') | list %}
{{ f[0].temperature if f|count > 0 else 'unknown' }}

Is that likely to be fixed if an issue is opened?

Or is it expected?

I may be wrong but it seems like a bug to me and I’m posting it as an issue in the Core repo.

Curiously, this throws an error:

{% set x = [] %}
{{ iif(x == [], 'yes', x[0].foo) }}

but this doesn’t

{% set x = [] %}
{{ iif(x == [], 'yes', x[0]) }}

If it’s always evaluating both arguments then I don’t understand why the first example causes an error but not the second one. In both examples, the list x is empty.

It should at least be consistent and flag both examples with an error or, preferably, neither.

1 Like

That works for existing values and non-existing values (–> unknown). Thank you so much!

I didn’t make any progress in understanding why iif didn’t flag both examples (posted above) as errors.

My Issue in the Core repo was promptly closed because it’s documented that iif always evaluates both of its arguments (if_true and if_false) regardless of its filter’s result.

However, my posted Issue wasn’t about that (unfortunately all replies focused on it). My Issue asked why does iif appear to behave inconsistently when evaluating its arguments. For some unexplained reason, it didn’t complain about evaluating x[0] but carped about x[0].foo despite the fact the list x is empty in both cases.

I’ve asked for the Issue to be re-opened but I have the feeling no one is interested in explaining the inconsistency given that iif can’t be used for this application (i.e. unsuitable for applications where one of its two arguments should not be evaluated).

Last update:

There’s been no response to my request to re-open the Issue.

Basically, nobody is interested in explaining the root cause of the inconsistency and are satisfied with having supplied the wrong answer (“It’s documented” … except the inconsistency is not documented).

Anyway, this one will remain a mystery.