All of the options you have suggested are possible…
Area-based
You can call your service on an area ID if you want to target all applicable entities in the Area. When using the UI editor, the area_id
will be selectable by it’s friendly name, otherwise it can be found using the Template editor: {{area_id("Living Room")}}
.
service: light.toggle
data: {}
target:
area_id: 0352e80e71464487b396c5599c886de0
This will have the same issue when the lights have mixed states
Group-based
A light group’s ‘on’ state is based on whether ‘any’ of it’s component entities’ states are ‘on’.
trigger:
- platform: mqtt
topic: "living_room/switch/light"
condition: []
action:
- service: light.turn_{{ iif( is_state('light.living_room_group', 'off'), 'on', 'off' ) }}
data: []
target:
entity_id: light.living_room_group
This will turn all lights ‘off’ if any are ‘on’ but only turn them ‘on’ when all are ‘off’.
Proportional toggle
trigger:
- platform: mqtt
topic: "living_room/switch/light"
condition: []
action:
- variables:
count_on: >
{{ state_attr('light.living_room_group', 'entity_id') | select('is_state','on') | list | count }}
count_off: >
{{ state_attr('light.living_room_group', 'entity_id') | select('is_state','off') | list | count }}
light_action: "{{ iif( count_on >= count_off, 'off', 'on' ) }}"
- service: "light.turn_{{ light_action }}"
data: []
target:
entity_id: light.living_room_group
This will turn all lights in the group ‘off’ when the number of lights which are ‘on’ is greater than or equal to the number of lights that are ‘off’, otherwise it will turn all lights ‘on’.
A similar set of variables could be used to do the same based on the light entities in a given area:
- variables:
lights: >
{{ expand(area_entities("living room")) | selectattr('domain', 'eq', 'light')| list }}
count_on: "{{ lights | select('state','eq', 'on') | list | count }}"
count_off: "{{ lights | selectattr('state','eq', 'off') | list | count }}"
light_action: "{{ iif( count_on >= count_off, 'off', 'on' ) }}"
Just be aware that some integrations will classify things in the light
domain that you might not expect to be switching on/off with your room lights and you would need to reject those specific entities from the list created for the lights
variable. Examples of this include indicator lights on ESPHome devices or screens controlled by the Browser Mod integration. Also, light groups may throw off the true ratio of ‘on’ vs. ‘off’.
EDIT: Corrected missing quotes mentioned below and updated templates to exchange expand
for preferred select
method.