How to select lights that are OFF

Hi all,

I need help with a script.

I want a script to change the brightness of the lights in a particular area (defined by “room_id”) but ONLY those in that room that are currently on. I can’t get it to work.

It first should calculate the average brightness of the all the lights that are ON, and then it moves up or down depending on an external helper. I want it to do it every 1s, with transitions of 1s, until a signal of “stop” is received.

This part works, however, the script is unable to work only on the lights that are currently ON. It always turns ALL the lights on, also those that were OFF.

How can I select only the lights that are ON and work on them only?

Thanks.

alias: Brightness Adjust Smart Retry v1 (works only on 1st instance of loop)
description: >
  Continuously adjusts brightness up or down once per second using transitions.
  All lights are synchronized to the same brightness level. Uses fixed limits
  1–255. Ignores lights that are OFF. Works with room_id.
mode: restart
fields:
  entity_ids:
    description: Lights to adjust (optional when using room_id)
    required: false
    selector:
      entity:
        domain: light
        multiple: true
  room_id:
    description: Optional area whose lights will be controlled
    required: false
    selector:
      area: {}
  command:
    description: Start or stop loop
    required: true
    selector:
      select:
        options:
          - start
          - stop
  brightness_step:
    description: Amount to change brightness per step
    selector:
      number:
        min: 1
        max: 100
        step: 1
    default: 30
variables:
  lights_from_entities: "{{ entity_ids if entity_ids is defined else [] }}"
  lights_from_area: |
    {% if room_id is defined %}
      {% set area_lights = area_entities(room_id) | select('match','^light\.') | list %}
      {% set on_lights = expand(area_lights)
          | selectattr('state','eq','on')
          | map(attribute='entity_id')
          | list %}
      {{ on_lights }}
    {% else %}
      {{ [] }}
    {% endif %}
  all_lights_raw: "{{ (lights_from_entities + lights_from_area) | unique | list }}"
  lights: |
    {{ expand(all_lights_raw)
       | selectattr('state','eq','on')
       | map(attribute='entity_id')
       | list }}
  step_size: "{{ brightness_step | int }}"
  direction: "{{ states('input_text.brightness_direction') | lower }}"
  max_limit: 255
  min_limit: 1
sequence:
  - if:
      - condition: template
        value_template: "{{ command == 'stop' }}"
    then:
      - variables:
          current_dir: "{{ states('input_text.brightness_direction') }}"
      - action: input_text.set_value
        data:
          entity_id: input_text.brightness_direction
          value: |
            {% if current_dir == 'up' %}
              down
            {% else %}
              up
            {% endif %}
      - stop: Stopped brightness loop.
  - repeat:
      while:
        - condition: template
          value_template: "{{ command == 'start' }}"
      sequence:
        - variables:
            brightness_values: |
              {{ expand(lights)
                 | map(attribute='attributes.brightness')
                 | select('defined')
                 | list }}
            avg_brightness: >
              {{ (brightness_values | sum / (brightness_values | length)) | int
              }}
        - choose:
            - conditions:
                - condition: template
                  value_template: "{{ avg_brightness >= max_limit }}"
              sequence:
                - action: input_text.set_value
                  data:
                    entity_id: input_text.brightness_direction
                    value: down
            - conditions:
                - condition: template
                  value_template: "{{ avg_brightness <= min_limit }}"
              sequence:
                - action: input_text.set_value
                  data:
                    entity_id: input_text.brightness_direction
                    value: up
        - variables:
            direction: "{{ states('input_text.brightness_direction') }}"
            new_brightness: |
              {% if direction == 'up' %}
                {{ [255, avg_brightness + step_size] | min }}
              {% else %}
                {{ [1, avg_brightness - step_size] | max }}
              {% endif %}
        - repeat:
            for_each: "{{ lights }}"
            sequence:
              - action: light.turn_on
                data:
                  entity_id: "{{ repeat.item }}"
                  brightness: "{{ new_brightness }}"
                  transition: 1
        - delay:
            seconds: 1

This variable will only return the lights which are on

Could it be that you are using light groups? If one of the members of the light group is on, it will be included. And if the brightness of the light group is changed, it will be applied to all members of the group, regardless if they are on or off.

BTW, you can simplify that template:

  lights: |
    {{ all_lights_raw
       | select('is_state', 'on')
       | list }}
1 Like