One button, toggle three devices

I have two zigbee lights and a switch. I have an Ikea shortcut button, when the button is pressed, I’d like to do one of three things;

  1. If all devices are on or off, toggle them
  2. If any two of the devices are on, turn the third device on
  3. If any two of the devices are off, turn the third device off

I thought a template might help with this, but I cannot for the life of me make any sense of the documentation for templating to understand if I can infact use a template for this. Can someone point me in the right direction? I’d like to keep the automation as simple as I can.

This would be an automation. You’d use a template to filter out the devices that are on.

Here is a sensor to indicate the state of the three lights

# Set Numeric value for three lights
# 0 = All Three Off
# 1 = Two Off
# 2 = Two On
# 3 = All Three On
- platform: template
  sensors:
    light_state: 
      friendly_name: "Light State"
      unique_id: "Light State"
      value_template: >
        {% if states('light.light1') == 'on' %}
        {% set x = 1 %}
        {% else %}
        {% set x = 0 %}
        {% endif %}
        {% if states('light.light2') == 'on' %}
        {% set y = 1 %}
        {% else %}
        {% set y = 0 %}
        {% endif %}
        {% if states('light.light3') == 'on' %}
        {% set z = 1 %}
        {% else %}
        {% set z = 0 %}
        {% endif %}
        {{ (x + y + z) }}

You will have to use a choose in the action part of the automations to choose conditions 0,1,2,3 and then perform the appropriate action. I tested in my sensors.yaml which is included in my configuration.yaml (sensor: !include sensors.yaml). You will need sensor: at the top and indent 2 spaces if you load in your configuration.yaml. The entity to choose on will be

sensor.light_state

I would put the three devices in a group then use an automation like:


alias: "3 Devices 1 Button"
description: ''
trigger:
  - ### YOUR TRIGGER HERE 
condition: []
action:
  - service: homeassistant.turn_{{service_select}}
    target: 
      entity_id: >
        {{ expand('group.3_devices')
        |selectattr('state', 'ne', service_select)
        | map(attribute='entity_id') | list | join(', ') }}
mode: single
variables:
  counts: >
    {{ expand('group.3_devices') 
    | selectattr('state', 'eq', 'on') 
    | list | count }}
  service_select: >
    {{ 'on' if counts in (0, 2) else 'off' }}

If you don’t want to create a group, you can get the same result by substituting your version of expand('light.light_1', 'light.light_2', 'switch.switch_1') into the “entity_id” and “counts” templates where the example has expand('group.3_devices')

I don’t have an IKEA button, so I left the trigger blank for you to figure out…

Thanks for the suggestions, I’ve ended up with the following solution, I’ll look at Didgeridrew’s solution to see if it’s any easier to make sense of!

alias: Master Bedroom Toggle
description: ''
trigger:
  - platform: device
    domain: mqtt
    device_id: []
    type: action
    subtype: 'on'
    discovery_id: [] action_on
condition: []
action:
  - choose:
      - conditions:
          - condition: or
            conditions:
              - condition: device
                type: is_on
                device_id: []
                entity_id: light.master_bedroom_light
                domain: light
              - condition: device
                type: is_on
                device_id: []
                entity_id: light.[]_bed_lamp
                domain: light
        sequence:
          - type: turn_off
            device_id: []
            entity_id: light.master_bedroom_light
            domain: light
          - type: turn_off
            device_id: []
            entity_id: light.[]_bed_lamp
            domain: light
      - conditions:
          - condition: and
            conditions:
              - condition: device
                type: is_off
                device_id: []
                entity_id: light.master_bedroom_light
                domain: light
              - condition: device
                type: is_off
                device_id: []
                entity_id: light.[]_bed_lamp
                domain: light
              - condition: time
                after: '08:00'
                before: '20:00'
        sequence:
          - type: turn_on
            device_id: []
            entity_id: light.master_bedroom_light
            domain: light
      - conditions:
          - condition: and
            conditions:
              - condition: device
                type: is_off
                device_id: []
                entity_id: light.master_bedroom_light
                domain: light
              - condition: device
                type: is_off
                device_id: []
                entity_id: light.[]_bed_lamp
                domain: light
              - condition: time
                after: '20:00'
                before: '08:00'
        sequence:
          - type: turn_on
            device_id: []
            entity_id: light.[]_bed_lamp
            domain: light
    default: []
mode: single

Here is the sensor and the template to accomplish the same thing. I think it is cleaner but judge for yourself. If you keep templates is configuration.yaml you will need a sensor: before platform or if you want in a separate file: sensor: !include youfile.yam; in your configuration.yaml.

# ------------------------------------------------   
- platform: template
  sensors:
    light_action: 
      friendly_name: "Light Action"
      unique_id: "Light Action"
      value_template: >
        {% if states('light.study_cans_current_value') == 'on' %}
          {% set x = 1 %}
        {% else %}
          {% set x = 0 %}
        {% endif %}
        {% if states('light.bar_back_bar_cans') == 'on' %}
          {% set y = 1 %}
        {% else %}
          {% set y = 0 %}
        {% endif %}
        {% if states('light.bar_pendant_light') == 'on' %}
          {% set z = 1 %}
        {% else %}
          {% set z = 0 %}
        {% endif %}
        {% set w = (x + y + z) %}
        {% if w > 1 %} turn_on
        {% else %} turn_off
        {% endif%} 
    
# automation    
alias: Turn On and Off
description: ''
trigger:
  - platform: state
    entity_id: sensor.light_action
    from: turn_off
    to: turn_on
  - platform: state
    entity_id: sensor.light_action
    from: turn_on
    to: turn_off
condition: time
after: '08:00'
before: '20:00'
action:
  - service: light.{{ states('sensor.light_action') }}
    target:
      entity_id:
        - light.study_cans_current_value
        - light.bar_back_bar_cans
        - light.bar_pendant_light
mode: single