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

Tags: #<Tag:0x00007fc3fc5ec938> #<Tag:0x00007fc3fc5ec7f8>

following up on Sensor - Unavailable/Offline Detection which I dont want to hijack any further with this ‘detail’ please have a look how I can ‘filter’ out entities in a template using a glob mask

this is what I have now:

          {% set ignore_list =  ['light.driveway','light.garden_backyard','light.garden_terrace',
                                'light.porch_outdoors'] if 
                                 is_state('binary_sensor.outside_daylight_sensor','on') else [] %}
          {% set unavailable = states|selectattr('state','eq','unavailable')
                                     |rejectattr('entity_id','in',state_attr('group.entity_blacklist','entity_id'))
                                     |rejectattr('entity_id','in',ignore_list)
                                     |rejectattr('domain','eq','media_player')
                                     |map(attribute='entity_id')
                                     |list %}
          {{ unavailable|count }}

And I need to prevent the group of sensors made by my SolarEdge sensor of being included.

I can add these individually in my blacklist group or even in the verbose ignore_list, but would hope to use some filter in the template.

as said in the other thread, along the lines of

|rejectattr(‘object_id’,‘startswith’,‘solaredge’)

now I know this isn’t valid, but hope you can see what I am looking for.

thanks for having a look

Not possible without a for loop.

Do these devices have a set of similar attributes?

no (other than the friendly_name starting with SolarEdge) they are templated sensors based on a rest sensor with these values as attributes…

  - platform: rest
    name: Solaredge overview
    scan_interval: 400
    json_attributes:
      - overview
    value_template: '{{ value_json.states }}'
    resource: !secret se_overview_resource

##########################################################################################
# Template Sensor
# https://home-assistant.io/components/sensor.template/
##########################################################################################
  - platform: template
    sensors:

#{'lastUpdateTime': '2019-11-20 11:07:32', 
# 'lifeTimeData': {'energy': 13920349.0}, 
# 'lastYearData': {'energy': 4378777.0}, 
# 'lastMonthData': {'energy': 72276.0}, 
# 'lastDayData': {'energy': 503.0}, 
# 'currentPower': {'power': 1028.0}, 
# 'measuredBy': 'INVERTER'}

      solaredge_lifetime_energy:
        friendly_name: 'SolarEdge Lifetime energy'
        value_template: >
          {{ (states.sensor.solaredge_overview.attributes.overview.lifeTimeData.energy|float/1000)|round(2) }}
        unit_of_measurement: 'kWh'

      solaredge_lastyear_energy:
        friendly_name: 'SolarEdge Last year energy'
        value_template: >
          {{ (states.sensor.solaredge_overview.attributes.overview.lastYearData.energy|float/1000)|round(2) }}
        unit_of_measurement: 'kWh'

I could of course set an attribute in the attributes_template :wink: and reject that in the template?

isn’t an operator available to do:

|rejectattr(‘friendly_name’,‘eq’,‘SolarEdge’) (and then use contain instead of eq)

Yep (Ignore the rest of this, 10 char min)

haha, cool.

above might be considered a hack… not sure if the would be better programming than adding the sensors to the blacklist.

btw, these are the operators/tests for the reject filter?

yep

You could use ‘in’ btw. It’s not the same as startswith, but it’ll filter it out. EDIT Nevermind, thinking about it backwards.

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”.