Exclude light entities contained in specified groups from the list of all lights

Hello guys!

I am trying to create a list of all light entities that are on except for the ones that have a “dim” prefix in their name. I my case “dim prefixed” lights are the groups of the lights that are dimmable and can ramp on/off

By now I know how to create a list of ‘all lights’:

{{states.light | selectattr("state", "eq", "on")| map(attribute='entity_id') | list}}

I also know how to create a list of “dim prefixed” lights (list of group names in this case e.g. light.dim_salon, light.dim_entrance etc.):

{{states.light | selectattr("entity_id", "search", "dim")| map(attribute='entity_id') | list}}

Could you help me with a code that would exclude the entities contained in the “dim prefixed” list from the list of all lights that are on?

Simply reject the attribute:


{{states.light
|rejectattr("entity_id", "search", "dim")
|selectattr("state", "eq", "on")
|map(attribute="entity_id")
|list}}

2 Likes

Thanks for the advice, but in this case it will not help because the list of “all lights” contains both: 1. "dim prefixed lights (=groups) 2. the entities that are members of the “dim prefixed” groups.

In you suggestion it will only exclude 1. But the entities that are members of these “dim prefixed” groups will still remain in the list.

Just to make myself more clear, here is the example of what I mean.

All the lights list contains the following:
[
“light.dim_salon”,
“light.fondo_tele_salon”,
“light.mesa_de_marmol_salon”,
“light.palmera_estanteria_salon”,
]

While the group “light.dim_salon” itself consists of:
[
“light.fondo_tele_salon”,
“light.mesa_de_marmol_salon”,
]

And at the end I want to receive:
[
“light.palmera_estanteria_salon”,
]

Add something like this:

rejectattr('entity_id', 'in', expand('your_group'))
1 Like

I tried this:

{{states.light | 
selectattr("state", "eq", "on")|
rejectattr('entity_id', 'in', expand('light.dim_salon'))|
map(attribute='entity_id') | list}}

This, unfortunately, does not do anything and all the items that are in light.dim_salon still remain in the final list.

{{states.light | 
selectattr("state", "eq", "on") |
rejectattr('entity_id', 'in', expand('light.dim_salon') | map(attribute='entity_id')) |
map(attribute='entity_id') | list}}
2 Likes

Pieter, sorry, my mistake. :innocent: It actually worked with your first suggestion (equally with the second).

Thank you very much for your help!!!

1 Like

@parautenbach, do you know if it’s possible to apply wildcard to “expand(‘light.dim_salon’)” in this case.

The thing is that I have several light groups (light.dim_salon, light.dim_comedor etc.) and I want to exclude all the entities that are present in these groups.

Or may be there is some other workaround for that?

Do you want to apply the search to all groups, to select certain groups, or do you want to refine the items in your current list by filtering it further?

Basically, you can pass search as a function (in the HA templating docs) to select or selectattr.

Here is a good post: Template: how to filter out based on 'solaredge' being in the entity_id.

1 Like

FWIW, we are discussing some other template expressions that allow for more flexible sorting and filtering here: WTH can't I tag entities and use tags queries for service calls? - #6 by Mossberget

1 Like

@famous.bulb Thanks a LOT for this link. It really helped me to come up with the code based on suggestions from @petro

{{ states.light 
  | map(attribute='entity_id')
  | reject('in', states.light 
    | selectattr('entity_id', 'search', 'dim_')
    | expand
    | map(attribute='entity_id')
    | list)
  | reject('in', states.light 
    | selectattr('attributes.entity_id', 'defined')
    | map(attribute='entity_id')
    | list)
  | select('in', states.light 
    | selectattr('state', 'eq', 'on')
    | map(attribute='entity_id')
    | list)
  | list  
}}

Now it does what I needed: from all the lights that I have in my house it excludes the lights that are members of “dim prefixed” lights. Consequently it excludes groups of lights and includes only the lights that are on.

I know that the code is quite bulky. I wonder if @petro would suggest a way to shorted it up if the case has a room for it.

Thanks again!

1 Like
{{ states.light 
  | rejectattr('state', 'eq', 'on')
  | rejectattr('entity_id', 'search', 'dim_')
  | rejectattr('attributes.entity_id', 'defined')
  | map(attribute='entity_id')
  | list  
}}
2 Likes

Thank you for your suggestion @petro.

However, it’s not exactly the same what I wanted. Namely, ‘dim_’ are groups of dimmable lights which I want to exclude. That’s why I use expand to ‘open’ the groups and then reject to exclude them.

that’s what this does…

rejectattr, not selectattr.

1 Like

Not exactly.

In my case state.light contains:

  • light.salon1
  • light.salon2
  • light.salon3
  • light.dim_salon (consists of two members: light.salon1, light.salon2)
  • light.comedor1
  • light.comedor2
  • light.comedor3
  • light.dim_comedor (consists of two members: light.comedor1, light.comedor2)

If I use your code I will exclude light.dim_salon and light.dim_comedor from state.light and it will produce the list:

  • light.salon1
  • light.salon2
  • light.salon3
  • light.comedor1
  • light.comedor2
  • light.comedor3

While at the end I want to get these if they are on:

  • light.salon3
  • light.comedor3

That’s why I search for dim_ prefixed entities, expand them and exclude from the final list while the groups themselves are excludeв with | rejectattr(‘attributes.entity_id’, ‘defined’).

Sorry, if I didn’t make myself clear enough from the beginning.

{{ states.light 
  | rejectattr('state', 'eq', 'on')
  | rejectattr('entity_id', 'in', states.light 
    | selectattr('entity_id', 'search', 'dim_') 
    | map(attribute='attributes.entity_id')
    | list | sum(start=[]) )
  | rejectattr('attributes.entity_id', 'defined')
  | map(attribute='entity_id')
  | list  
}}
1 Like

This works like a charm! :smiley: And the code is much shorter. I appreciate your help a lot!
I am still a beginner here. I wish I knew what ’ | sum(start=[]) ’ does to the in this case :blush:

I made just one correction: the final list should include the lights that are ‘on’:

{{ states.light 
  | selectattr('state', 'eq', 'on')
  | rejectattr('entity_id', 'in', states.light 
    | selectattr('entity_id', 'search', 'dim_') 
    | map(attribute='attributes.entity_id')
    | list | sum(start=[]) )
  | rejectattr('attributes.entity_id', 'defined')
  | map(attribute='entity_id')
  | list  
}}

Thanks a lot from your help Petro!

1 Like

Sum adds things together. The entity_id attribute is a list. For some reason, sun has a default starting value of 0 and then tries to add things to that value. So you need to make sure that starting value is a list so that you’re only adding lists.

2 Likes

Ah, ok. Now it make sense to me. Thanks a lot for that explanation!