[General] Sync switches

I would like to provide blueprints keeping switches in sync. The switches to sync can be selected on the UI.

There are templates for 2, 3 and 4 switches. Place them to a subfolder under config/homeassistant/blueprints/automation and after calling the service automation.reload on the UI the templates are selectable.

sync_2switch.yaml

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 %}


sync_3switch.yaml

blueprint:
  name: Sync three 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
    switch_entity3:
      name: Switch 3
      selector:
        entity:
          domain: switch
variables:
  switch_entity1: !input switch_entity1
  switch_entity2: !input switch_entity2
  switch_entity3: !input switch_entity3
  switch_entity12: 
    - !input switch_entity1
    - !input switch_entity2
  switch_entity13:
    - !input switch_entity1
    - !input switch_entity3
  switch_entity23:
    - !input switch_entity2
    - !input switch_entity3

trigger:
  - platform: state
    entity_id: 
      - !input switch_entity1
      - !input switch_entity2
      - !input switch_entity3
    from: 'on'
    to: 'off'
  - platform: state
    entity_id: 
      - !input switch_entity1
      - !input switch_entity2
      - !input switch_entity3
    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_entity23 }}
        {% elif trigger.entity_id == switch_entity2 %}
          {{ switch_entity13 }}
        {% elif trigger.entity_id == switch_entity3 %}
          {{ switch_entity12 }}
        {% endif %}

sync_4switch.yaml

blueprint:
  name: Sync four 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
    switch_entity3:
      name: Switch 3
      selector:
        entity:
          domain: switch
    switch_entity4:
      name: Switch 4
      selector:
        entity:
          domain: switch

variables:
  switch_entity1: !input switch_entity1
  switch_entity2: !input switch_entity2
  switch_entity3: !input switch_entity3
  switch_entity4: !input switch_entity4
  switch_entity123: 
    - !input switch_entity1
    - !input switch_entity2
    - !input switch_entity3
  switch_entity134:
    - !input switch_entity1
    - !input switch_entity3
    - !input switch_entity4
  switch_entity234:
    - !input switch_entity2
    - !input switch_entity3
    - !input switch_entity4
  switch_entity124:
    - !input switch_entity1
    - !input switch_entity2
    - !input switch_entity4

trigger:
  - platform: state
    entity_id: 
      - !input switch_entity1
      - !input switch_entity2
      - !input switch_entity3
      - !input switch_entity4
    from: 'on'
    to: 'off'
  - platform: state
    entity_id: 
      - !input switch_entity1
      - !input switch_entity2
      - !input switch_entity3
      - !input switch_entity4
    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_entity234 }}
        {% elif trigger.entity_id == switch_entity2 %}
          {{ switch_entity134 }}
        {% elif trigger.entity_id == switch_entity3 %}
          {{ switch_entity124 }}
        {% elif trigger.entity_id == switch_entity4 %}
          {{ switch_entity123 }}
        {% endif %}

EDIT [9th of Feb 2022]: Updated/Debounced blueprints to fix race condition when turning on and off within a very short time

8 Likes

Thank you very much. This is great. Exactly what I would need.
I would have a huge request. Could you please add the “Import Blueprint” link/button, or the link to Github? I am nood and i don’t know how to import the templates above.
Thank you in advance.

Thank you very much but I want to synchronize more than 4 switch numbers for example 5 6 7 switches please help

Great job, I spent hours finding ways that did not work in the end, your blueprint works great and easily
Thank you

Hi,
I am new to HA and this is my first Blueprint I am implementing. However, I am getting an error in the script. Am I missing something?
I pasted in the scripting error. Any help would be appreciated. - Thanks

1 Like

A massive thank you for this simple switching logic, makes for a much cleaner set of scenarios to sync up switches that is otherwise reasonably difficult to manage.

i’ve basically forked these scripts and edited some timing logic to better suit my needs, matched my own naming schemes internally, and added a 2 way inverse sync script to allow for a permanent OR state.

Gists are published for an easy add to HA instances.

Two Switches
Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.

3 Likes

Two Switches - Inverted

Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.

HI, I have a wall switch named switch.radio_button which fires script.radio. Script.radio turns on mediaplayer.onkyo + sets network mode and fires internet radio threw google cast integration - this works great.
I wanted to sync state of mediaplayer.onkyo and the wall button, after onkyo is turned on by remote controler or phisical button. This works …almost. Because every time sync is trigered, script.radio is also trigered.
Can you advice, how to use this blueprint, together with a condition, that sync should not triger the script?

@thatdoogieguy I have tried to import templates you posted here, but I’m getting this error in zigbee2mqtt - used for both switches

Publish 'set' 'state' to 'Ložnice vypínač' failed: 'Error: Command 0x847127fffe94eee6/2 genOnOff.off({}, {"sendWhen":"immediate","timeout":10000,"disableResponse":false,"disableRecovery":false,"disableDefaultResponse":false,"direction":0,"srcEndpoint":null,"reservedBits":0,"manufacturerCode":null,"transactionSequenceNumber":null,"writeUndiv":false}) failed (Timeout - 33270 - 2 - 35 - 6 - 11 after 10000ms)'

@Underknowledge posted this on discord, does not work (when modified for my switches etc.) - maybe it is the same errors

alias: Theoretical automation to group some switchen
trigger:
  - platform: state
    entity_id:
      - switch.1
condition:
  - condition: template
    value_template: "{{ trigger.from_state.state != trigger.to_state.state }}"
action:
  - service_template: switch.turn_{{ trigger.to_state.state }}
    target:
      entity_id:
        - switch.1

@glenhart same :confused: string does not match pattern of DEPRECATED^

seems that it should work when replacing service_template with service removes the complaint in the code validator, but switches do not sync

For some reason this also does not work for me altrought the logic in the code makes sense :confused:

this also does not work for me, so i guess time to learn :confused:

I guess the core issue in my case is

2022-09-04 17:31:16Publish 'set' 'state' to 'Ložnice vypínač' failed: 'Error: Command 0x847127fffe94eee6/2 genOnOff.off({}, {"sendWhen":"immediate","timeout":10000,"disableResponse":false,"disableRecovery":false,"disableDefaultResponse":false,"direction":0,"srcEndpoint":null,"reservedBits":0,"manufacturerCode":null,"transactionSequenceNumber":null,"writeUndiv":false}) failed (Timeout - 33270 - 2 - 87 - 6 - 11 after 10000ms)'

So I have paired the switch again and now it works, let’s see how long it will last

Dont worry to much bout it, when it looks good it the template editor it should be fine ™
the command helper is funky from time to time

After a lot of playing around with the blueprints in this thread, I was able to make a single blueprint that you can add 2 or more switches to to be synchronized. This eliminates needing multiple blueprints for 2, 3, 4, etc. switches. It will also only call the service to any switch that is not already in the matching state of the trigger switch.

This is my first blueprint, so please let me know any feedback on how this works for you.

Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.

blueprint:
  name: Sync Multiple Switches
  description: Sync the On/Off status of 2 or more switches
  domain: automation
  input:
    switch:
      name: Switches to Control
      selector:
        entity:
          multiple: true
          domain: switch
variables:
  switches: !input switch
trigger:
  - platform: state
    entity_id: !input switch
condition: 
  - "{{ trigger.to_state.context.parent_id == none }}"
  - "{{ trigger.to_state.state == 'on' or trigger.to_state.state == 'off' }}"
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: >
        {% set ts = namespace(switch=[]) %}
        {% for sw in switches %}
          {% if not is_state(sw,trigger.to_state.state) %}
            {% set ts.switch = ts.switch + [sw] %}
          {% endif %}
        {% endfor %}
        {{ ts.switch | list }}
5 Likes

Works like a charm for me with 2 switches @matrix2669 , thanks!

1 Like

Thank you for sharing your blueprint. I tried it and it is working when operating the switches manually, the other one will follow the same state. I have a problem when I change state of one of the switch from home assistant. If I set the switch to off, the automation is triggering many times and the switch goes off then back on. I can see 5 traces all at the same time in the automation traces, I don’t know if there are more only the last 5 traces are showing. I’m trying to wrap my head around what could cause this…

Oh and if I set again the off state soon after it does the bug then that switch stay off and the other one doesn’t have the same state it stay on while the one I was controlling is now off.

Oh and, and, I get the same behavior from OFF to ON.

Hallo and thank you indeed for this wonderfull blueprint.
I would like to use similar template (or just some script) for blocking switches eachother.
Example 1: 8 different switches if I turn any one from them to ON, all others must be turned OFF (or assured to be in the OFF state)
Example 2: using 2 separate Sonoff 4rellays devices (4 switches in the group of each Sonoff device can be blocked by the HW fuction of the device) but the two Sonoff devices can’t be blocked against each other, so I need - if any switch from the first device is turned to ON state, all switches from the other device must be turned to state OFF (or assured to be in the state OFF)

Can anyone plz help me with such config?
thx.
W.

You need to add the timeout, as the first post. [General] Sync switches

Hi.
I have made a little adjustment to @matrix2669 , it works with light also.

blueprint:
  name: Sync Multiple Switches
  description: Sync the On/Off status of 2 or more switches
  domain: automation
  input:
    switch:
      name: Switches to Control
      selector:
        entity:
          multiple: true
          domain:
          - switch
          - light
  source_url: https://gist.github.com/matrix2669/bb539014fb5ca8e6279a41c1121be677
variables:
  switches: !input switch
trigger:
- platform: state
  entity_id: !input switch
condition:
- '{{ trigger.to_state.context.parent_id == none }}'
- '{{ trigger.to_state.state == ''on'' or trigger.to_state.state == ''off'' }}'
action:
- service_template: '{% if trigger.to_state.state == ''on'' %} homeassistant.turn_on {% elif
    trigger.to_state.state == ''off'' %} homeassistant.turn_off {% endif %}

    '
  data_template:
    entity_id: "{% set ts = namespace(switch=[]) %} {% for sw in switches %}\n  {%
      if not is_state(sw,trigger.to_state.state) %}\n    {% set ts.switch = ts.switch
      + [sw] %}\n  {% endif %}\n{% endfor %} {{ ts.switch | list }}"