Sync/link a button and a switch

Hi,

I have a fairly simple scenario where I need a wall pushbutton to be in sync with a smart plug switch.

Surprisingly, I haven’t found much discussion here about it, I was guessing many people have that situation.

But I think my main “problem” is that this push button has a led light when ON, otherwise I could just use it as toggle and not care at all about this sync, probably most people fall in that category. This is actually a 3 gang wired zigbee switch, where other 2 buttons actually control stuff by having electrical wire connected to it, and the 3rd button is not connected anywhere, so I use it as a fake/virtual button to control another light connected to a smart plug.

So, I have the button item and the smartplug item in a group and I use this rule to maintain the sync:

rule "Kitchen Strip Button Update"
when
    Member of gKitchenStrip changed
then
    if(bLock)
        return;
    bLock = true
    val newState = triggeringItem.state
    gKitchenStrip.members.filter[j|j.name != triggeringItem.name].forEach[i|
  if(i.state != newState)
    {i.sendCommand(newState.toString)}
else 
    {i.postUpdate(newState)}]
    createTimer(now.plusSeconds(1), [ bLock = false ])
end

but the problem I have is that a member of this group gKitchenStrip, called KitchenStrip (the smartplug device itself) is also a member of gAllLights. When the lights are all switched OFF via that group, the kitchen strip sometimes blinks, or sometimes even switches ON if it was OFF previously. but only sometimes. so, 90% of the time everything works, but sometimes this light does not comply…with “all off” command, it can even do the opposite :slight_smile:

It seems that everything is fine when the light is controlled directly via smartplug switch and/or the wall button, erratic behavior only arises when some rules trigger the all lights out (leaving the house, going to sleep etc).

I also tried to control the light only via the group gKitchenStrip rather then the item directly, it also didnt produce stable behavior. I was thinking if I add the group gKitchenStrip to the gAllLights rather then the item itself it could improve it, but I’m not sure.

is there any better way to do this?

There is no easy way to achieve this. It’s fraught with the potential for infinite loops and timing problems. What makes it more challenging is that you have to command the button to keep the status light synced. It’s usually easier to keep them in sync when that’s not the case.

Your best approach will be to use a proxy Item to represent the light. Only this Item goes into your AllLights Group and only this Item appears on any UI and is used from any rule (except for the one rule that keeps the two devices in sync).

To make things a little less chaotic, I would disable autoupdate on the button and the strip Item.

rule "Kitchen Strip Sync"
when
    Item KitchenStripProxy received command // we only care about commands from the proxy 
    Item KitchenStrip changed // the device changed state independent from the proxy
    Item Button changed // the device changed state independent from the proxy
then
    // If using JS you could use sendCommandIfDifferent()
    if(triggeringItemName == "KitchenStripProxy") {
        if(KitchenStrip.state != receivedCommand) KitchenStrip.sendCommand(receivedCommand)
        if(Button.state != receivedCommand) Button.sendCommand(receivedCommand)
    }
    else {
        if(KitchenStripProxy.state != newState) KitchenStripProxy.sendCommand(newState)        
    }
end
1 Like