How to link 2 switches together, so state of one mirrors state of second

It helps to write the conditions properly. I also threw in a 1 second limit on changes to stop any potential loops. It prevents things from being rapidly synced if you rapidly change them, but that isn’t a big problem. I’ve tested this on a number of paired lights & switches and I think this works well.

- alias: Light Hot Tub Mirror Switch Off
  trigger:
    - platform: state
      entity_id: light.hot_tub_flood_switch
      to: 'off'
      from: 'on'
  condition:
    - condition: template
      value_template: "{{ states.light.hot_tub_flood_switch.last_updated > states.light.hot_tub_flood.last_updated }}"
    - condition: template
      value_template: "{{ (now() - states.light.hot_tub_flood.last_updated ).seconds > 1 }}"
  action:
    - service: light.turn_off
      entity_id: light.hot_tub_flood

- alias: Light Hot Tub Mirror Switch On
  trigger:
    - platform: state
      entity_id: light.hot_tub_flood_switch
  condition:
    - condition: template
      value_template: "{{ states.light.hot_tub_flood_switch.last_updated > states.light.hot_tub_flood.last_updated }}"
    - condition: template
      value_template: "{{ (now() - states.light.hot_tub_flood.last_updated ).seconds > 1 }}"
  action:
    service: light.turn_on
    entity_id: light.hot_tub_flood
    data_template:
      brightness: >
        {{ state_attr('light.hot_tub_flood_switch', 'brightness') | default(0, true) }}

- alias: Light Hot Tub Mirror Flood Off
  trigger:
    - platform: state
      entity_id: light.hot_tub_flood
      to: 'off'
      from: 'on'
  condition:
    - condition: template
      value_template: "{{ states.light.hot_tub_flood.last_updated > states.light.hot_tub_flood_switch.last_updated }}"
    - condition: template
      value_template: "{{ (now() - states.light.hot_tub_flood_switch.last_updated ).seconds > 1 }}"
  action:
    - service: light.turn_off
      entity_id: light.hot_tub_flood_switch

- alias: Light Hot Tub Mirror Flood On
  trigger:
    - platform: state
      entity_id: light.hot_tub_flood
  condition:
    - condition: template
      value_template: "{{ states.light.hot_tub_flood.last_updated > states.light.hot_tub_flood_switch.last_updated }}"
    - condition: template
      value_template: "{{ (now() - states.light.hot_tub_flood_switch.last_updated ).seconds > 1 }}"
  action:
    service: light.turn_on
    entity_id: light.hot_tub_flood_switch
    data_template:
      brightness: >
        {{ state_attr('light.hot_tub_flood', 'brightness') | default(0, true) }}
3 Likes

I see this is old, but still active, here is how I do it, no loops, can add many entities. The boolean ensures it runs once, more important if you have a bunch

alias: Pool Pumps On
description: 'Ensure both pumps are on/off at same time'
trigger:
  - platform: state
    entity_id: 'switch.pool_heat_circ_pump, switch.pool_pump'
    from: 'off'
    to: 'on'
condition:
  - condition: state
    entity_id: input_boolean.pool_pumps
    state: 'off'
action:
  - service: switch.turn_on
    data: {}
    entity_id: 'switch.pool_heat_circ_pump, switch.pool_pump'
  - service: input_boolean.turn_on
    data: {}
    entity_id: input_boolean.pool_pumps
mode: single

alias: Pool Pumps Off
description: 'Ensure both pumps are on/off at same time'
trigger:
  - platform: state
    entity_id: 'switch.pool_heat_circ_pump, switch.pool_pump'
    from: 'on'
    to: 'off'
condition:
  - condition: state
    entity_id: input_boolean.pool_pumps
    state: 'on'
action:
  - service: switch.turn_off
    data: {}
    entity_id: 'switch.pool_heat_circ_pump, switch.pool_pump'
  - service: input_boolean.turn_off
    data: {}
    entity_id: input_boolean.pool_pumps
mode: single
2 Likes

Im using this automation, works like a charm.

- alias: Bedroom2
  trigger:
  - platform: state
    entity_id: light.bedroom, light.bedroom2
    from: 'on'
    to: 'off'
  - platform: state
    entity_id: light.bedroom, light.bedroom2
    from: 'off'
    to: 'on'
  action:
    service_template: '{% if trigger.to_state.state == "on" %} light.turn_on {% elif
      trigger.to_state.state == "off" %} light.turn_off {% endif %}
      '
    data_template:
      entity_id: '{% if trigger.from_state.entity_id == "light.bedroom" %} light.bedroom2
        {% elif trigger.from_state.entity_id == "light.bedroom2" %} light.bedroom
        {% endif %}
3 Likes

Lol, you don’t have kids for sure…

I really like this scheme.
I wish I were better versed at templates to come up with some of these.
Thanks for sharing.
Works really well and is pretty elegant.

CFC

I have created a blueprint of this with selecting the entitys over the UI.

blueprint:
  name: Sync two switches
  description: Turn on a switch when other one is turend on and vice versa
  domain: automation
  input:
    switch_entity1:
      name: Switch 1
      selector:
        entity:
          domain: switch
    switch_entity2:
      name: Switch 2
      selector:
        entity:
          domain: switch
variables:
  switch_entity1: !input switch_entity1
  switch_entity2: !input switch_entity2
trigger:
  - platform: state
    entity_id: 
      - !input switch_entity1
      - !input switch_entity2
    from: 'on'
    to: 'off'
  - platform: state
    entity_id: 
      - !input switch_entity1
      - !input switch_entity2
    from: 'off'
    to: 'on'
condition: "{{ trigger.to_state.context.parent_id == none }}"
action:
  - wait_template: "{{ (as_timestamp(now()) - as_timestamp(this.attributes.last_triggered | default(0)) | int > 3) }}"
    timeout: 3
  - service_template: >
      {% if trigger.to_state.state == 'on' %}
      switch.turn_on
      {% elif trigger.to_state.state == 'off' %}
      switch.turn_off
      {% endif %}
    data_template: 
      entity_id: >
        {% if trigger.entity_id == switch_entity1 %}
        {{ switch_entity2 }}
        {% elif trigger.entity_id == switch_entity2 %}
        {{ switch_entity1 }}
        {% endif %}

This blueprint and adittional for 3 and 4 switches at [General] Sync switches

Creating blueprints is really a pain in the ass. As a guy programming all day in differnt languages I needed hours to get this working.

4 Likes

how do i import your blueprint

I just add it to a subfolder under config/homeassistant/blueprints/automation and after calling the service automation.reload on the UI it is selectable.

1 Like

Great job! Many thanks!

Just came across this thread again and thought I link to this solution which I think is much more elegant, works with more than 2 switches, and is shorter as well:
2 Switches - 1 Light - Configuration - Home Assistant Community (home-assistant.io)

My need is exactly the opposite of this. I have 2 pumps one being a backup of the other. The plumbers suggested it’d be a good practice to rotate their on/off status to increase their lifetime and for some other reasons.

I connected them to a sonoff wireless switch and wrote the following automation, which works. Sadly it’s super primitive and also prone to many fail cases such as any power failure during the automation or say if HA goes down during the automation for some reason. Is there a smart way to mirror the opposite states for two switches without having two automations?

Here’s my current code:

alias: Time - pumps
description: ""
trigger:
  - platform: time_pattern
    minutes: "2"
condition: []
action:
  - if:
      - condition: template
        value_template: "{{ now().hour >= 8 and now().hour < 14 }}"
    then:
      - if:
          - condition: template
            value_template: "{{ now().hour == 8 }}"
        then:
          - service: switch.turn_off
            data: {}
            target:
              entity_id: switch.pump_1
          - delay:
              seconds: 10
          - service: switch.turn_off
            data: {}
            target:
              entity_id: switch.pump_2
        enabled: true
    else:
      - if:
          - condition: template
            value_template: "{{ now().hour % 2 == 0 }}"
        then:
          - service: switch.turn_off
            data: {}
            target:
              entity_id: switch.pump_1
          - delay:
              seconds: 10
          - service: switch.turn_on
            data: {}
            target:
              entity_id: switch.pump_2
        else:
          - service: switch.turn_off
            data: {}
            target:
              entity_id: switch.pump_2
          - delay:
              seconds: 10
          - service: switch.turn_on
            data: {}
            target:
              entity_id: switch.pump_1
  - if:
      - condition: template
        value_template: >-
          {{ is_state('switch.pump_1', 'on') and
          is_state('switch.pump_2', 'on') }}
    then:
      - service: switch.turn_off
        data: {}
        target:
          entity_id:
            - switch.pump_1
            - switch.pump_2
        enabled: true
mode: single

Hello, I’m completely new to HA and automations. I have a running network of zigbee devices and more and more of them are coming.

I already have 15 ZBMINI switches operational, and now I wanted to use ZBMINI in the staircase switch scenarios, however it seems that the wiring I have doesn’t allow me for this use case (no direct L out to the light). Do you think, it would be possible to use a pair of ZBMINIL2 and somehow program mirroring automation for this use case?

Thanks!

Hi.
I know this is a long time ago.
But do I save this code in the automations.yaml file?

You could just add it to the end of the automations.yaml file then see if it appears in the Automations UI. As old as it is, there’s no assurance that the automation would work.

1 Like

Took a little fiddling to get the formatting right… But this works GREAT syncing Virtual switches in Smartthings and real switches in HA. This is a cool/easy way to get Alex/Google Voice Assistant to turn on and off devices in HA.