#How to count entities in dynamic group?

1 messages · Page 1 of 1 (latest)

mystic violet
#

I created a dynamic group to list devices with low battery level on dashboard. Works mostly:

alias: Dynamic Battery Group
description: Creates Group of Items with Low Battery Level on HA Startup
triggers:
  - trigger: homeassistant
    event: start
conditions: []
actions:
  - action: group.set
    metadata: {}
    data:
      object_id: low_battery
      name: Low Battery
      icon: mdi:battery-outline
      entities: >-
        {{ states.sensor | selectattr('attributes.device_class', 'defined') |
        selectattr('attributes.device_class', 'eq', 'battery') |
        rejectattr('entity_id', 'eq', 'SM-S906U') | selectattr('state',
        'lt','50') | map(attribute='entity_id') | list  }}
mode: single
```yaml

Questions:
1. The rejectattr line is not working to prevent my phone with HA companion app from being on the list.  Do I need to refer to that entity differently?
2. I have tried to create a separate template sensor to count the number of items in this dynamic group with no luck.  This is to be used as a badge on a dashboard.  Any example code on how to create this count sensor?

Any thoughts would be appreciated.
limpid sky
#
  1. You are using entity_id in your rejectattr() filter, but SM-S906U is not an entity_id. An entity_id would be something like senor.sm_s906u_battery_level
  2. The group will have an entity_id attribute, which will list all entities in the group, you can count the entities in that attriubte: {{ state_attr('group.your_group', 'entity_id') | count }}
#

BUT: your template for the entities will not do what you want it to do. You are doing a state comparison with strings

#

and string comparisons will give unwanted result, as they are compared character by character

#

so for example "6" < "50" will return false as 6 is higher than 5

mystic violet
dusky radish
#

you can either:
create a for loop and iterate through each item so that you can cast the state to an int, check if it is <50, and if it is then you would append it to a namespace variable that is a list

-or-

make two lists (one with entity id's and one with states cast to int) and zip them together and then filter them.

#

this is the 2nd option, place it in developer tools -> template and see if it outputs what you expect

{% set sensors = states.sensor | selectattr('attributes.device_class', 'defined') | selectattr('attributes.device_class', 'eq', 'battery') | rejectattr('entity_id', 'eq', 'sensor.sm_s906u_battery_level') | list %}
{% set sensor_dict = zip(sensors | map(attribute='entity_id'), sensors | map(attribute='state') | map('int',-1)) %}
{{ sensor_dict | selectattr(1, 'lt', 50) | map(attribute=0) | list }}
limpid sky
#

I would add | selectattr('entity_id', 'has_value') to the first line to filter out non numeric states, then you also don't need the default in the int filter

#

like itis above, you will also get the sensors which are unavailable or unkown

#
{% set sensors = states.sensor
                  | selectattr('entity_id', 'has_value')
                  | selectattr('attributes.device_class', 'defined')
                  | selectattr('attributes.device_class', 'eq', 'battery')
                  | rejectattr('entity_id', 'eq', 'sensor.sm_s906u_battery_level')
                  | list
%}
{% set sensor_dict = zip(sensors | map(attribute='entity_id'), sensors | map(attribute='state') | map('int')) %}
{{ sensor_dict | selectattr(1, 'lt', 50) | map(attribute=0) | list }}