Template: how to filter out based on 'solaredge' being in the entity_id

ok thanks, I tried In but as you noticed, that wont work in this order of things…

side question, now that I revisit my solar_edge sensors, would there be any preference for either versions:

          {{ (states.sensor.solaredge_overview.attributes.overview.lifeTimeData.energy|float/1000)|round(2) }}

          {{ (state_attr('sensor.solaredge_overview','overview').lifeTimeData.energy|float/1000)|round(2)}}

          {% set overview = state_attr('sensor.solaredge_overview','overview') %}
          {{(overview.lifeTimeData.energy|float/1000)|round(2)}}

always prefer the state_attr() myself for known reasons, and kind of like the further development of the bottom version, since it emphasizes the relation to the mother sensor visually for me.

none of them are safe. If the attribute or entity_id don’t exist you’ll get errors. Not sure If I would care though.

{% set overview = state_attr('sensor.solaredge_overview','overview') %}
{% if 'lifeTimeData' in overview %}
{{(overview.lifeTimeData.energy|float/1000)|round(2)}}
{% else %}
 xxxx
{% endif %}

This isn’t a very pretty solution but it does work.

Lets say these are your sensor names:
solaredge_a
solaredge_b
solaredge_c
solaredge_d
solaredge_e
etc

This template selects all entities whose names are greater than “solaredge_” and less than “solaredge_x”:

{{ states | selectattr('object_id','gt','solaredge_') 
          | selectattr('object_id','lt','solaredge_x')
          | list }}

For your requirements, you would replace selectattr with rejectattr.


Example:
I have these two object_ids:
laundry_door
laundry_door_lock

This template gets both of them:

{{ states | selectattr('object_id','gt','laundry_') 
          | selectattr('object_id','lt','laundry_x')
          | list }}

thought about being safe, but must admit, on the level of the mother sensor:

if sensor.solar_edge_overview exists, all the other sensors exist.

And, as a matter of fact, the mother sensor happens to get thrown out now and then, the rest sensor doesnt always connect. If so, all these sensors show Unknown…

so, shouldn’t I test on the existence of the mother sensor?

{% if 'sensor.solaredge_overview' %}
  {% set overview = state_attr('sensor.solaredge_overview','overview') %}
     {{(overview.lifeTimeData.energy|float/1000)|round(2)}}
{% else %} Unavailable #(or offline...)
{% endif %}

Yeah probably. That’s why I said that I wouldn’t really worry about it. Or at least, I wouldn’t in your shoes.

I’ve been contemplating adding startswith, endswith, and contains as filters for some time now. Just been lazy.

3 Likes

Make it a New Year’s resolution. :slight_smile:

1 Like

yes, those are deeply missed!

please do, it would be very much appreciated, and prevent a lot of workarounds and hacks…

1 Like

yes, it does work indeed:

would I need both in case if rejectattr?

If I use (either the single of both )gt and lt now, it indeed excludes the solaredge sensors, but also all that are alphabetically beyond it…

I was wrong about this one. It works for selecting a set of similarly named entities but not for rejecting them.

It can be done in two steps:

{% set x = states 
           | selectattr('object_id','gt','solaredge_')
           | selectattr('object_id','lt','solaredge_x') 
           | map(attribute='entity_id') 
           | list %}

{{ states | rejectattr('entity_id', 'in', x) | list }}
1 Like

Clever, nice one :+1:

But, tbh, still hope @petro will follow up on his thoughts about Pr-ing the extra operators…

Thanks for hanging in there with me :blush:

4 Likes

Seem like New Year’s gift hasn’t come yet! :rofl:

It’s a pita to add them, looked into it. Wasn’t easy at the time and moved on :wink:

1 Like

Home Assistant now supports match and search. The first one is like"startswith" and the second is like “contains”.

No tests and filters are currently a workaround for ‘startswith’ AFAIK.


You must have missed my post where I said match serves the purpose of startswith. Here’s the relevant section from Home Assistant’s documentation for Templating - Regular Expressions

  • Test string is match(find, ignorecase=False) will match the find expression at the beginning of the string using regex.
  • Test string is search(find, ignorecase=True) will match the find expression anywhere in the string using regex.

Here’s an example of match and search in action:

1 Like

from the looks of it, they still can’t be used for the original intent which is something that filters a list based on contains or startswith. I haven’t played with the tests much, but they don’t appear to help much.

EDIT: They can’t be used in selectattr, rejectattr, select, or reject. Making them 100% useless IMO.

EDIT2: Nope, they can!

{% set items = ['abc', 'bcd', 'cde'] %}
{{ items | select("search", 'b') | list }}

returns

[
  "abc",
  "bcd"
]

another example

{{ states.sensor | selectattr('entity_id', 'search', 'humidity') | map(attribute='entity_id') | list }}

returns

[
  "sensor.bonus_server_room_humidity",
  "sensor.garage_humidity",
  "sensor.kitchen_humidity",
  "sensor.master_bathroom_average_humidity",
  "sensor.master_bathroom_filtered_humidity",
  "sensor.master_bathroom_filtered_humidity_statistics",
  "sensor.master_bathroom_humidity",
  "sensor.master_bedroom_humidity",
  "sensor.ms_humidity"
]

So these basically do what I wanted to do in this post:

EDIT3:

We’ll need to add more examples in the docs because the provided example is piss poor.

3 Likes

Yep, I had suggested its use in this post to match either “The Batchelor” or “The Batchelorette”.

state_attr('sensor.sonarr_upcoming_media', 'data')
        | selectattr('title', 'match', 'The Bachelor') | list | length > 0

Initially I had the same concern because the example in the documentation isn’t quite the way I would normally use a filter.


EDIT

I agree the documentation’s example falls short of showing how useful match and search can be.

Well, I don’t see a need for namespace anymore… Outside organizing data before presenting it.

just wait til marius finds this, that’s going to be a lot of refactoring