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

Tags: #<Tag:0x00007f739e17fd18>

Read this :

You saved previous time with this perfectly workign answer. Thank you.

1 Like

Hello,
Here how i had it worked without delay problems.

Cheers

I have the same “infinite loop” issue with the provided answer above.

I “know” how the issue can be resolved (in terms of logic flow) but I don’t know how to write this in automation rule…

Maybe someone can turn this into a working rule:
So we keep the main logic by setting a mirror switch value to the “currently set” value. But we must set a flag on the mirror switch which will mean that the next assigned value will be from an automation rule (so we can ignore this).

Step by step:

  1. switch A gets clicked (off -> on)
  2. switch B sets custom “from_auto” flag to “1”
  3. switch B sets state to “on” (same as switch A)

[mirroring is “done” at this point. everything below is what causes the loop to happen when states were changed too quickly (when not using “from_auto”)]

  1. automation is fired for switch B as it’s state was changed (off -> on)
  2. automation condition must check if switch B has a “from_auto” attribute set to “1”
  3. [automation] IF no, then do switch.turn_on as usual mirroring flow…
  4. [automation] IF yes, then do not try to “mirror” this state (do no run switch.turn_on for mirroring to another switches)
  5. [automation] change switch B (current trigger.from_state.entity_id) attribute “from_auto” to “0” to return to the initial state

thats all… from_auto will control if the new state must be sent to “other” switches or not.

I hope someone can turn this into an automation rule.

I have a “virtual” bedside light that is actually a switch (wifi wall plug) and can also be switched via a 433MHz RF switch (connected to the Sonoff RF bridge). So it’s three things to sync for me: The light, the switch, and the state of the RF switch.

I use a more “brute-force” method by setting all three of the entities to whatever state I get when any changes:

  # Synchronize switches for bedside light
  - alias: Sync bedside light switches
    trigger:
      platform: state
      entity_id:
        - light.bedside # the light (which is actually switch3)
        - switch.switch3 # the physical switch
        - switch.rfbridge1_2 # RF switch
    action:
      service_template: >
        {% if trigger.to_state.state == "on" %}
        homeassistant.turn_on
        {% elif trigger.to_state.state == "off" %}
        homeassistant.turn_off
        {% endif %}
      entity_id:
        - light.bedside # the light (which is actually switch3)
        - switch.switch3 # the physical switch
        - switch.rfbridge1_2 # RF switch

This has been working without side effects for over a year now, and proved a good strategy for any entity that is to be controlled by more than one actuator (like my hallway lights that have 5 switches, one next to each door).

unfortunately it has the same infinite-loop effect too

you can’t skip events as then switches may stuck in different states.

1 second delay is not a solution. this was described above.

Hi @Delphir, not sure if you have solve it. I understand what you mean by infinite loop. This happens when you flick the switch multiple time too fast, it can happens also when the network is slow and switch2 delay in action causing the out of sync. So they trigger each other indefinitely.
I manage to find something that work though, see if it helps you.
I am more primitive, i use only GUI automation. If you use code, you can use this concept and use your own code if you like.
I use 4automations entries… on1trigger_on2, off1trigger_off2, on2trigger_on1, off2trigger_off1, the important thing is to add a condition to the action switch, make sure the action switch is in the correct state.

example for the 1st automation
trigger : switch1 on
condition: switch2 is off
action: turn on switch2.

You try this, it will not go into infinite loop… Convert this concept into code, as i only know how to use GUI…let me know if it works for you…

the loop happens not because of the wrong states, but because of the delay itself

look at this:

  1. switch2 current state = off
  2. switch1 on (trigger delayed [A])
  3. switch1 off (trigger delayed [B]) <<<<<<<< our expected final value
  4. trigger automation for switch1 on [A] = switch2 on (will fire an automation too [C])
  5. trigger automation for switch1 off [B] = switch2 off (will fire an automation too)
  6. trigger automation for switch2 on [C] !!! = switch1 on <<<<<<<<<< the actual final value and looping then

    and so on… here they start looping fast for the infinite amount of time. and each time the state of the another switch has an “opposite” value, so your “condition” will not solve the problem.

it would be handy to have a condition “NOT from automation” - this would solve the whole issue

Delphir, like i said in my post, i know the root cause is the delay, please check. It is the delay causing the 2switches out of sync, and always in opposite state, and they start triggering each other to change state without first checking the opp switch for their state. I know it is not the condition that cause this problem. I am saying by adding a condition to check the opp switch before firing the action, it does prevent the infinite loop. I am not just giving a hypothetical theory, i tried it in my automation. It prevent them from infinite toggling…I physicaly flick the switch onoff more than 10time in succession, it doesnt happen anymore… so i place my sucessful trial here and hopefully someone need this piece of information. I am not sure if you have tried it before you conclude. peace…:blush:

By the way i am not good at code, i use 4automations to pair 2 switches. And I also have infinite loop issue like you, causing by network delay. Now I am all settled after i add in the condition. hope it help…

Sorry, maybe i didnt explain properly, i try again just in case you didnt understand…

  1. switch2 current state = off
  2. switch1 current state = off
  3. switch1 trigger on but check condition of switch2 first.
  4. if condition of switch2, is off, then fire the action to turn on switch2
  5. if condition of switch2 is on, do nothing.

hope you can understand…

My solution uses two automations. Both switches are MQTT with physical switches. I’ve tried flipping the physical switches as fast as I can and I never get out of sync or have blinking lights.

My other automation is the same as this, but with the switch names reversed.

- alias: "Family North Sync" # Synchronize north and south lights
  trigger:
    - platform: state
      entity_id: switch.family_recessed_north
  action:
    - choose:
        - conditions: 
            - condition: state
              entity_id: switch.family_recessed_north
              state: 'on'
          sequence:
            - service: switch.turn_on
              entity_id: switch.family_recessed_south
      default:
        - service: switch.turn_off
          entity_id: switch.family_recessed_south

Hi I am new to HA. Can you tell me where I should put this code? automation.yaml or configuration.ymal? How is the automation id get generated? Many thanks,

sorry guys, i cannot put my switches, working as a mirror, can you help?

- id: '1606786491838'
  alias: Quarto R/C Switch  ON
  description: ''
  trigger:
    - platform: state
      entity_id: switch.sonoff_100021a80a, switch.sonoff_10002181de
      from: 'on'
      to: 'off'
    - platform: state
      entity_id: switch.sonoff_100021a80a, switch.sonoff_10002181de
      from: 'off'
      to: 'on'
  action:
    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.from_state.entity_id == "switch.sonoff_100021a80a" %}
        switch.sonoff_10002181de
        {% elif trigger.from_state.entity_id == "switch.sonoff_10002181de" %}
        switch.sonoff_100021a80a
        {% endif %}
  mode: single

This is under automations.yaml