I cannot get the correct state with selectattr

Following up on a very comprehensive answer by @Didgeridrew to a question on a problem of mine, I stumbled upon another problem

I ended up with the following script to count the number of lights on and off in an area

mixed_switch:
    sequence:
        -   alias: set variables
            variables:
                lights: >
                    {{ expand(area_entities("salon_centre")) | selectattr('domain', 'eq', 'switch')| list }}
                count_on: "{{ lights | selectattr('state','eq', 'on') | list | count }}"
                count_off: "{{ lights | selectattr('state','eq', 'off') | list | count }}"
                light_action: "{{ iif( count_on >= count_off, 'off', 'on' ) }}"
        -   alias: debug variables
            service: persistent_notification.create
            data:
                message: "{{lights}} {{count_on}} {{count_off}} {{light_action}}"
                title: "debug"
        -   alias: turn all lamps on or off
            service: homeassistant.turn_{{ light_action }}
            target:
                area_id: salon_centre

The output of the “debug” section is as follows (I reformatted for clarity)

[
  <template TemplateState(<state switch.salon_blanche_entree_gauche=off; device_class=outlet, icon=mdi:floor-lamp, friendly_name=blanche entrée gauche @ 2023-01-29T15:28:10.498726+01:00>)>, 
  <template TemplateState(<state switch.salon_lampe_haute=off; icon=mdi:lamp, friendly_name=salon lampe haute @ 2023-01-29T15:15:40.553449+01:00>)>, 
  <template TemplateState(<state switch.salon_tableau=off; device_class=outlet, friendly_name=salon_tableau @ 2023-01-29T15:26:03.766786+01:00>)>
] 
0 0 off

The first list is correct - I put these three switched in the test area salon_centre. They are all switch and all are off.

{{count_off}} should therefore be equal to 3. If I understand the sequence correctly (“Match entries where state is off, list them, then count the elements”) then it seems to be fine.

Would you have any ideas why it is not?

I don’t know exactly why the previous template did not work, but one work around is to have the lights variable pass just the entity ids then use expand() again to render the count_on and count_off variables.

mixed_switch:
  variables:
    lights: |
      {{ expand(area_entities('salon_centre')) | selectattr('domain', 'eq', 'switch')
      | map(attribute = 'entity_id') | list }}
    count_on: |
      {{ expand(lights) | selectattr('state','eq', 'on') | list | count }}
    count_off: |
      {{ expand(lights) | selectattr('state','eq', 'off') | list | count }}
    light_action: |
      {{ iif( count_on >= count_off, 'off', 'on' ) }}
  sequence:
    - alias: debug variables
      service: persistent_notification.create
        data:
          message: "{{lights}} {{count_on}} {{count_off}} {{light_action}}"
          title: "debug"
    - alias: turn all lamps on or off
      service: homeassistant.turn_{{ light_action }}
      target:
        area_id: salon_centre

Especially since you are using the homeassistant.turn_on/off services, you may want to use the lights variable as your target instead of targeting all the entities in the area that respond to that type of service call.

....
    - alias: turn all lamps on or off
      service: homeassistant.turn_{{ light_action }}
      target:
        entity_id: "{{ lights }}"

As mentioned in the previous post there can be entities in an area under the switch and/or light domain that you might not expect to be classified as such that you may need to reject from your lights variable. In my case, I could not use this script as shown above because many of the devices in my living room have other switch entities… so every time the script triggered a turn ‘on’ the devices would restart or be put in “do not disturb” mode, etc. My lights variable would need to look more like:

  lights: |
    {{ expand(area_entities('living room')) | selectattr('domain', 'eq', 'switch')
    | rejectattr('entity_id', 'search', 'restart | disturb | repeat | shuffle') 
    | map(attribute='entity_id') | list }}

This worked! Thank you very much!

When using the area (which I was not until now) I think I will only add the relevant entities to the area it is, in order to avoid just what you mentioned. I will give that a try this week.

Thanks again!