Awesome! Thanks. This worked for me.
Just to toss in the way I’ve done this - never been a problem for me. I have the following code. In this case, the dining_room_table_a light is a single light in the chandelier, and the light.dining_room_table is the group. (I wanted some redundancy, so if alexa turned on the lights it would also set the switches to the correct state). Obviously, I have a similar code for the table_off state. I think having mode:single works with the system here - I don’t think it’s physically possible for things to get out of sync this way.
- id: 'DiningRoomTableon'
alias: Dining Room Table on
description: ''
trigger:
- platform: device
type: turned_on
device_id: 99300785192text9091984670
entity_id: switch.dining_room_table_1
domain: switch
- platform: device
type: turned_on
device_id: 3356022273text24728020666
entity_id: switch.dining_room_table_2
domain: switch
- platform: device
type: turned_on
device_id: 79370607906text37076040675
entity_id: light.dining_room_table_a
domain: light
condition: []
action:
- type: turn_on
device_id: 99300785192text9091984670
entity_id: switch.dining_room_table_1
domain: switch
- type: turn_on
device_id: 3356022273text24728020666
entity_id: switch.dining_room_table_2
domain: switch
- type: turn_on
device_id: 68013182361text88415920360
entity_id: light.dining_room_table
domain: light
mode: single
For the guys with the infinite loop.
I don’t know your exact setup so this might not work for you, but have you considered a master <> slave relation between you lights? This way you can avoid an infinite loop, as there is only one master, and the rest are slaves, that follow the master.
This problem has been bouncing around in my skull for a while. In my situation, I have a number of Insteon switches that are controlling zigbee, wled, or esphome based lights. Up until now I’ve been content with the switch controlling the light, and if the light gets shut-off or dimmed by HomeKit or Home Assistant independently of the switch, then they just get out of sync, in order to avoid the loop problem.
I realized tonight that if I set a condition on the automation that checks to see if the controlling entity has changed more recently than the target entity, then it should react accordingly and not cause loops because the other automation sees a change and wants to change its target. Eureka! It works, and no loops. Now both the switch and the light are in perfect sync.
- alias: Light Hot Tub Mirror Switch Off
trigger:
- platform: state
entity_id: light.hot_tub_flood_switch
to: 'off'
from: 'on'
condition: "{{ states.light.hot_tub_flood_switch.last_updated > states.light.hot_tub_flood.last_changed }}"
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: "{{ states.light.hot_tub_flood_switch.last_updated > states.light.hot_tub_flood.last_changed }}"
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: "{{ states.light.hot_tub_flood.last_updated > states.light.hot_tub_flood_switch.last_changed }}"
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: "{{ states.light.hot_tub_flood.last_updated > states.light.hot_tub_flood_switch.last_changed }}"
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) }}
Edit: Changed “last_changed” to “last_updated” since brightness doesn’t affect “last_changed” but it does affect “last_updated”.
This isn’t quite there yet. Sometimes there is a bit of looping when HA changes one of the entities, but it eventually stops for some reason.
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) }}
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
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 %}
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.
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.
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.
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.