Control interaction between two switches (semaphor)

I'm trying to set up a fairly straightforward automation between a "primary" switch and a "secondary" switch. [But there's more context at the end.]

  • By default, they are "paired" - pressing the button on the primary will switch the secondary to match.
  • pressing the button (once) on the secondary will unpair them, so the primary will no longer affect the secondary.
  • pressing the button (again) on the secondary will pair them again, so from then on pressing the primary will control the secondary.

However, I can't figure out how to distinguish when the secondary changes state due to the primary being pressed vs. when it changes state due to it being pressed directly.

Here's the naive setup.

The primary rules them all:

image

The secondary throws the ring in the fire:

image

The simple thing to do would be to introduce another "guard" variable to the primary rule, indicating that it is running. However, that trips over some immediate race conditions (the guard typically gets unset before the secondary switch finishes changing), so I have to add a delay for unsetting it. Which, of course, is vulnerable to all kinds of real-world race conditions, including the primary getting pressed again, the secondary actually getting pressed while the guard is waiting, etc.

And it's actually more complicated than that. This test bed is just to isolate the problem. What I'm really trying to do is set up a fairly complicated rule, which will slowly raise a dimmer (among other things), and there are other switches involved - so the race conditions get more and more complicated.

I think what I really need is for the "unpair" rule to know whether the switch is changing because somebody actually hit the button, or because a rule told it to. It seems to me that should be a basic property of the triggers, but I can't find anything that lets me figure it out. Am I missing something?

Help?

Would it work to have your second variable be set to true by the first rule when your primary switch is changed and then be set to false by the second rule. In other words, the second rule would check the value of the variable and, if true, set it to false, otherwise change the other variable.

If I understand what you're suggesting, I don't think so. I'm not trying to create a "flip/flop" between them; I want the second switch to be able to declare itself independent. So the second rule shouldn't really care about the first rule - when it changes runs, it takes control over the switch until it runs again.

Does your switch report "physical" events? This would be the easiest way. You can look at Events on the device page. There are digital events, e.g., when the switch is activated by an automation, and physical events, e.g. when the switch is physically switched. Not all devices report physical. If it does, you can trigger from this the rule that pairs/unpairs.

Thanks, Bruce - it does report "[physical]", so that sounds like what I'm looking for. But I'm not sure how to do it. I changed the trigger to respond to physical:

image

...but when the I press the switch the rule doesn't fire. (I confirmed that the logging is set appropriately by adding back in the trigger for any change.)

I feel like I must be missing something obvious?