Group.add_entities: Interesting concept... how does it work?

I came across something potentially very useful in the Service Developer Tool today. When I typed group.set in the Service field, add_entities appeared as a possible parameter for that service!

My questions are:

  1. Is add_entities implemented?
  2. Is there also a delete_entities method?
  3. If not can I use add_entities to replace the contents of a group?

The possibilities were swirling in my mind. I recently simplified @CCOSTAN’s speech code somewhat by creating a constantly updated list of turned on lights. I have found this list very useful elsewhere such as dimming lights every half hour in the evening… but only the lights that are already on.

Right now I store this list in a template sensor sensor.lights_on. It occurs to me that this list would be a good candidate to be converted to a group instead. Unfortunately I has been unable to get add_entities to change a test group I created.

group:
  lights_on:
    entities:
      - light.dummy
    name: "Lights On"
sensor:
  - platform: template
    sensors:
      lights_on:
        value_template: >
          {% macro get_lights_on() -%}
            {%- for group in states.light|groupby('state') -%}
              {%- for entity in group.list -%}
                {%- if  entity.state == 'on'
                    and entity.entity_id.split('_')|last != 'nightlight'
                    and entity.entity_id|lower != 'light.garage_entry_light'
                    and entity.entity_id|lower != 'light.shoe_closet_light' -%}
                  {{ entity.entity_id }}{{ ' ' }}
                {%- endif -%}
              {%- endfor -%}
            {%- endfor -%}
            {%- for group in states.switch|groupby('state') -%}
              {%- for entity in group.list -%}
                {%- if  entity.state == 'on'
                    and entity.entity_id.split('_')|last == 'light' -%}
                  {{ entity.entity_id }}{{ ' ' }}
                {%- endif -%}
              {%- endfor -%}
            {%- endfor -%}
          {%- endmacro %}
          {{ get_lights_on()|trim|replace(' ', ',') }}
  1. Looking at the code it does look like add_entities is indeed implemented. Note that it is mutually exclusive with entities. (I.e., you can use one or the other but not both in the same service call.) add_entities will add the entity or entities listed to the group, whereas entities will replace the current list of entities in the group with those specified in the service call.

  2. No, there is no delete_entities option currently.

  3. No, as I described above, you would use entities to replace the contents of the group.

I might also add that this service can be used to dynamically create a group, too. I.e., if the group you specify does not exist, it will be created. In this case add_entities and entities effectively do the same thing. So you don’t necessarily need to define the group in your static configuration.

1 Like

On a side note @BrianHanifin, have you seen my automation to auto dim lights as they turn on depending on time of day?

Sweet! I mean, very nice. (Apparently posts must be at least 10 characters! :wink:)

I’m a fan of that code too. :slight_smile: I love tinkering with your code. It has been such an amazing starting point for me to explore. Thank you so much for sharing it.

I split the “action” portion of that code into a script, which I pass the trigger entity_id to. But I also added an automation to run every half hour to dim the lights that are already turned on as the night goes on. It serves double duty perfectly.

  - alias: Adjust brightness every half hour
    trigger:
      platform: time
      minutes: '/30'
      seconds: 00
    action:
      - service: script.set_light_brightness_pct_by_time
        data_template:
          trigger_entity_id: "{{ states('sensor.lights_on') }}"
1 Like

Thanks for that explanation. Its totally unnecessary because the solution I have is already working so well… but I might have a tinker anyway. :slight_smile:

I like it… I experimented with Auto Dimming lights that were on already but reverted it since it was overriding manual adjustments… Although now with the lack of ALEXA dimming, we do MUCH less manual dimming. Might have to revisit this.

1 Like

If you are looking for an example of dynamically creating a group as well as managing the group members, the code below may be of help. I ended up using entities instead of add_entities because it was a better fit for my use case.

1 Like

@CCOSTAN: My family really seems to mostly appreciate the auto dimming. On the rare occasion when we need full brightness late at night we can just ask Alexa to set the light to 100.

@NotoriousBDG: Thank you! I recently added your battery monitor, it has been very helpful to keep track of all of my Xiaomi sensors, and to know when my Raincloud watering system is offline (so I can make sure it gets back online before my wife’s plants die). :slight_smile:

I will pin this browser tab to look at when my Kitchen Remodel slows down. Thank you so much! It seems like creating a group would be the context appropriate way to create this list of “ON” devices. I look forward to revisiting my code soon.

2 Likes

@pnbruckner + @NotoriousBDG:

I came across this old message, and I have been experimenting with more and more advanced code lately so I wanted to give this another shot. I took my code that updates custom variable, and swapped in a group.set instead. It works perfectly!

lights_on_update:
  sequence:
    # service: variable.set_variable
    # data:
    #   variable: lights_on
    #   value_template: >
    - service: group.set
      data_template:
        object_id: "lights_on"
        entities: >-
          {% macro get_lights_on() -%}
            {%- for group in states.light|groupby('state') -%}
              {%- for entity in group.list -%}
                {%- if entity.state == 'on'
                    and entity.entity_id != 'light.dummy'
                    and entity.entity_id != 'light.garage_entry_light'
                    and entity.entity_id != 'light.hue'
                    and entity.entity_id != 'light.play_room'
                    and entity.entity_id != 'light.kitchen_undercabinet'
                    and entity.entity_id != 'light.porch_light'
                    and entity.entity_id != 'light.shoe_closet_light'
                    and not ('gateway_light' in entity.entity_id)
                    and not ('hub'           in entity.entity_id)
                    and not (entity.entity_id).endswith('_led')
                    and not (entity.entity_id).endswith('nightlight')
                    and not (entity.entity_id).startswith('light.lamplinc') -%}
                  {{ entity.entity_id }}{{ ' ' }}
                {%- endif -%}
              {%- endfor -%}
            {%- endfor -%}
          {%- endmacro %}
          {{ get_lights_on()|trim|replace(' ', ',') }}

Now I will have to consider if I want to use a group instead of a variable. It would be nice to be able to turn off only the on lights when I say Goodnight I suppose.

If you don’t need it in a group, the below works to turn off any light that is on by using it as the entity_id in your light.turn_off call.

{% set group_id = 'group.all_lights' %} 
{% set on_states = ['on'] %} 
{{ states | selectattr('entity_id','in', state_attr(group_id, 'entity_id')) | selectattr('state','in',on_states) | map(attribute='entity_id') | join(', ') }}
1 Like

Very cool! I felt like there should be a way to use a filter to weed out the lights that were off. Thank you.

Check this out! I can take your code a step further and recreated my if statement filter as rejectattr('entity_id','in',ignore_list). This is awesome!

{% set group_id = 'group.all_lights' %} 
{% set on_states = ['on'] %}
{% set ignore_list = ['light.dummy','light.garage_entry_light','light.hue','light.play_room','light.kitchen_undercabinet','light.porch_light','light.shoe_closet_light','light.plug01_red_led','light.plug02_red_led','light.plug03_red_led','light.plug04_red_led','light.plug05_blue_led','light.sonoff_pow_01_green_led','light.sonoff_pow_02_green_led', 'light.sonoff_s31_01_green_led','light.sonoff_s31_02_green_led','light.upstairs_bathroom_nightlight'] %} 
{{ states | rejectattr('entity_id','in',ignore_list) | selectattr('entity_id','in', state_attr(group_id, 'entity_id')) | selectattr('state','in',on_states) | map(attribute='entity_id') | join(', ') }}
1 Like

Cool, I never knew about rejectattr and can certainly use that too.

Thanks!

1 Like