Two switches one light eg. staircase switch - rule

hmm when I do that, it’s complaining
eventho switch A and B are initialized, having OFF values, and when triggered from OH they works.

rule "Switch A"
when
    Item Switch_A changed
then
    if(Switch_B.state != Switch_A.state) Switch_B.sendCommand(Switch_A.state)
end
2019-08-01 00:13:16.068 [ome.event.ItemCommandEvent] - Item 'Switch_A' received command ON
2019-08-01 00:13:16.093 [nt.ItemStatePredictedEvent] - Switch_A predicted to become ON
2019-08-01 00:13:16.145 [vent.ItemStateChangedEvent] - Switch_A changed from OFF to ON
2019-08-01 00:13:16.139 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Switch A': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.sendCommand(org.eclipse.smarthome.core.items.Item,java.lang.Number) on instance: null

Are you certain the items are not NULL or UNDEF? Log out the states of both items.

I think this is just one of those things where you can’t send OnOffType state as command

Switch_B.sendCommand(Switch_A.state.toString)

to make state ON look like command ON

thank you milliontimes indeed, .toString did the trick

@rossko57 Thanks for opening the feature request on GitHub. Some thoughts which I like to share here first.

Is it? Some other user tested it and told just the opposite:

What happens if you use the getStateAs method?

Switch_B.sendCommand(Switch_A.getStateAs(OnOffType))

I’ve done this:

Switch  Switch_A    "A"  <light>       { channel="mqtt:topic:SwitchA:switch", channel="mqtt:topic:SwitchB:switch"[profile="follow"]}
Switch  Switch_B    "B"  <light>       { channel="mqtt:topic:SwitchB:switch", channel="mqtt:topic:SwitchA:switch"[profile="follow"]}

which resulted both switches toggling on/off in like every half second or so. Not sure why.
Maybe I’ll give it a shot once again. Maybe it’s looping because of MQTT slight delay?

edit … I mean, yeah :smiley:

2019-08-01 14:31:23.916 [vent.ItemStateChangedEvent] - Switch_A changed from ON to OFF
2019-08-01 14:31:24.023 [vent.ItemStateChangedEvent] - Switch_B changed from OFF to ON
2019-08-01 14:31:24.027 [vent.ItemStateChangedEvent] - Switch_A changed from OFF to ON
2019-08-01 14:31:24.288 [vent.ItemStateChangedEvent] - Switch_A changed from ON to OFF
2019-08-01 14:31:24.351 [vent.ItemStateChangedEvent] - Switch_A changed from OFF to ON
2019-08-01 14:31:24.353 [vent.ItemStateChangedEvent] - Switch_B changed from ON to OFF
2019-08-01 14:31:24.413 [vent.ItemStateChangedEvent] - Switch_B changed from OFF to ON
2019-08-01 14:31:24.584 [vent.ItemStateChangedEvent] - Switch_A changed from ON to OFF
2019-08-01 14:31:24.615 [vent.ItemStateChangedEvent] - Switch_B changed from ON to OFF
2019-08-01 14:31:24.667 [vent.ItemStateChangedEvent] - Switch_A changed from OFF to ON
2019-08-01 14:31:24.717 [vent.ItemStateChangedEvent] - Switch_B changed from OFF to ON
2019-08-01 14:31:24.839 [vent.ItemStateChangedEvent] - Switch_A changed from ON to OFF
2019-08-01 14:31:24.922 [vent.ItemStateChangedEvent] - Switch_A changed from OFF to ON
2019-08-01 14:31:25.004 [vent.ItemStateChangedEvent] - Switch_B changed from ON to OFF
2019-08-01 14:31:25.068 [vent.ItemStateChangedEvent] - Switch_B changed from OFF to ON
2019-08-01 14:31:25.247 [vent.ItemStateChangedEvent] - Switch_A changed from ON to OFF
2019-08-01 14:31:25.263 [vent.ItemStateChangedEvent] - Switch_A changed from OFF to ON
2019-08-01 14:31:25.267 [vent.ItemStateChangedEvent] - Switch_B changed from ON to OFF
2019-08-01 14:31:25.339 [vent.ItemStateChangedEvent] - Switch_B changed from OFF to ON
2019-08-01 14:31:25.481 [vent.ItemStateChangedEvent] - Switch_A changed from ON to OFF
2019-08-01 14:31:25.617 [vent.ItemStateChangedEvent] - Switch_A changed from OFF to ON
2019-08-01 14:31:25.664 [vent.ItemStateChangedEvent] - Switch_B changed from ON to OFF
2019-08-01 14:31:25.801 [vent.ItemStateChangedEvent] - Switch_B changed from OFF to ON
2019-08-01 14:31:25.913 [vent.ItemStateChangedEvent] - Switch_A changed from ON to OFF
2019-08-01 14:31:25.978 [vent.ItemStateChangedEvent] - Switch_B changed from ON to OFF
2019-08-01 14:31:25.984 [vent.ItemStateChangedEvent] - Switch_A changed from OFF to ON
2019-08-01 14:31:26.035 [vent.ItemStateChangedEvent] - Switch_B changed from OFF to ON
2019-08-01 14:31:26.237 [vent.ItemStateChangedEvent] - Switch_A changed from ON to OFF
2019-08-01 14:31:26.338 [vent.ItemStateChangedEvent] - Switch_A changed from OFF to ON
2019-08-01 14:31:26.403 [vent.ItemStateChangedEvent] - Switch_B changed from ON to OFF
2019-08-01 14:31:26.490 [vent.ItemStateChangedEvent] - Switch_B changed from OFF to ON
2019-08-01 14:31:26.615 [vent.ItemStateChangedEvent] - Switch_A changed from ON to OFF
2019-08-01 14:31:26.693 [vent.ItemStateChangedEvent] - Switch_B changed from ON to OFF

some observations:
It will crap itself after one of those switches is triggered, when they go from ON to OFF it turn OFF second of them, but OH keeps spamming MQTT with OFF
Mayhem starts when one switch is triggered to ON, which result to upper posted ON/OFF loop, mqtt spammed, switches are physically triggered.

Which I believe is because OH keep spamming OFF from first ON to OFF action.

Running 2.5.0-SNAPSHOT (#1650)

I believe with profiles you only define 1 item to control both channels, at least that is what I did with two lightbulbs and haven’t had any issues.

Switch SwitchA_B "A & B" <light> { channel="mqtt:topic:SwitchA:switch", channel="mqtt:topic:SwitchB:switch"[profile="follow"]} 

damn, you are kind of correct
it works… sort of

when it’s triggered from OH it’s obviously OK as it’s triggered by Swtich A

but when you press physically button on Switch B which is not defined, it won’t trigger Switch A
physical push of Switch A, triggers Swtich B just fine …
So yeah, it needs bit more love

Switch  Switch_A    "A"  <light>       { channel="mqtt:topic:SwitchA:switch", channel="mqtt:topic:SwitchB:switch"[profile="follow"]}

In my case I have this for my Lifx items:

Dimmer  lightdimV      "dimmer"  (gPersist)            { channel="lifx:whitelight:bedroom1:brightness", channel="lifx:whitelight:bedroom2:brightness" [profile="follow"] }
Switch  lightV         "Lifx bulbs"    (gPersist)      { channel="lifx:whitelight:bedroom1:brightness", channel="lifx:whitelight:bedroom2:brightness" [profile="follow"] }

yes because bulb is just passive item
but I need to have two or more wallswitches cooperate, which means there is no just one master and rest are following him, but every switch can act as master and rest have to follow it

@kriznik

I tested it with two Philips Hue bulbs and was successful. Maybe the MQTT is the problem?

here is my log:

2019-07-29 18:50:06.220 [ome.event.ItemCommandEvent] - Item 'Tint_Light3_Toggle' received command ON
2019-07-29 18:50:06.230 [vent.ItemStateChangedEvent] - Tint_Light3_Toggle changed from OFF to ON
2019-07-29 18:50:11.383 [vent.ItemStateChangedEvent] - Tint_Light3_Dimmer1 changed from 0 to 65
2019-07-29 18:50:11.386 [vent.ItemStateChangedEvent] - Tint_Light4_Toggle changed from OFF to ON
2019-07-29 18:50:11.387 [vent.ItemStateChangedEvent] - Tint_Light4_Dimmer1 changed from 0 to 66


2019-07-29 18:50:22.992 [ome.event.ItemCommandEvent] - Item 'Tint_Light3_Toggle' received command OFF
2019-07-29 18:50:22.996 [vent.ItemStateChangedEvent] - Tint_Light3_Toggle changed from ON to OFF
2019-07-29 18:50:31.426 [vent.ItemStateChangedEvent] - Tint_Light3_Dimmer1 changed from 65 to 0
2019-07-29 18:50:31.427 [vent.ItemStateChangedEvent] - Tint_Light4_Toggle changed from ON to OFF
2019-07-29 18:50:31.428 [vent.ItemStateChangedEvent] - Tint_Light4_Dimmer1 changed from 66 to 0


2019-07-29 18:50:42.790 [ome.event.ItemCommandEvent] - Item 'Tint_Light4_Toggle' received command ON
2019-07-29 18:50:42.793 [vent.ItemStateChangedEvent] - Tint_Light4_Toggle changed from OFF to ON
2019-07-29 18:50:51.476 [vent.ItemStateChangedEvent] - Tint_Light3_Dimmer1 changed from 0 to 65
2019-07-29 18:50:51.477 [vent.ItemStateChangedEvent] - Tint_Light3_Toggle changed from OFF to ON
2019-07-29 18:50:51.478 [vent.ItemStateChangedEvent] - Tint_Light4_Dimmer1 changed from 0 to 66


2019-07-29 18:51:04.372 [ome.event.ItemCommandEvent] - Item 'Tint_Light4_Toggle' received command OFF
2019-07-29 18:51:04.375 [vent.ItemStateChangedEvent] - Tint_Light4_Toggle changed from ON to OFF
2019-07-29 18:51:11.523 [vent.ItemStateChangedEvent] - Tint_Light3_Dimmer1 changed from 65 to 0
2019-07-29 18:51:11.525 [vent.ItemStateChangedEvent] - Tint_Light3_Toggle changed from ON to OFF
2019-07-29 18:51:11.529 [vent.ItemStateChangedEvent] - Tint_Light4_Dimmer1 changed from 66 to 0

as i have done more test runs during the day, OH simply keep sending mqtt cmnd even after state is already changed.
Which then is indeed causing troubles when you trigger opposite state as then you have two constant spamming threads one with OFF and second one with ON.

edit: I kind of believe it’s caused by combination of this follow rule and Tasmota stat/cmnd topics
is follow rule following stateTopic or commandTopic or both? it does look like both?
because in mqtt I can see this:

sonoff-touch-09/cmnd/POWER ON
sonoff-touch-09/stat/RESULT {"POWER":"ON"}
sonoff-touch-09/stat/POWER ON
sonoff-touch-08/cmnd/POWER ON
sonoff-touch-08/stat/RESULT {"POWER":"ON"}
sonoff-touch-08/stat/POWER ON
sonoff-touch-09/cmnd/POWER ON
sonoff-touch-09/stat/RESULT {"POWER":"ON"}
sonoff-touch-09/stat/POWER ON
sonoff-touch-08/cmnd/POWER ON
sonoff-touch-08/stat/RESULT {"POWER":"ON"}
sonoff-touch-08/stat/POWER ON
sonoff-touch-09/cmnd/POWER ON
....
....
....

we can see here that 09 was followed by 08 but then I think 09 reacted again to topic stat/POWER ON sent by 08 which is sent after receiving cmnd … and which caused another trigger and so on and on and on

@kriznik

As you can see in my logfile above, it works. My bulbs were switched ON and OFF both simultaneously (in real), but the eventbus was updated between 5 and 8.5 seconds later.

I totally believe you, no worries :wink:

1 Like

I find understanding exactly what follow profile does is headache provoking, but here’s what I got;

In the case where follow is used with no parameter…

Switch  mySwitch "blurb"  { channel="some:thing:channel" }

First, the ordinary OH linkage -
When Item mySwitch gets a state update, nothing (ordinarily) happens to some:thing channel (there are always exception bindings :crazy_face:)
When Item mySwitch gets a command, it gets passed to some:thing channel, to binding, and usually to device.
When some data arrives from device via binding to some:thing channel, it causes an Item state update.

It is possible to add a second channel to an Item

Switch  mySwitch "blurb"  { channel="some:thing:channel", channel="other:thing:channel" }

Here things work much the same as the ordinary way -
When Item mySwitch gets a state update, nothing (ordinarily) happens to either channel.
When Item mySwitch gets a command, it gets passed both to some:thing channel, to binding, to device, AND to other:thing channel, to other binding and device.
When some data arrives from device via binding to some:thing channel OR to other:thing channel, it causes an Item state update.

Okay, let’s apply follow profile to channel two

Switch  mySwitch "blurb"  { channel="some:thing:channel", channel="other:thing:channel" [profile="follow"] }

Here things work differently. The follow profile effectively reverses what the associated channel does, “follow” listens for state updates on the Item and converts them into commands on the channel, and at the same time blocks incoming updates from getting to the Item.
Let’s work it out -
When Item mySwitch gets a state update, nothing happens to some:thing channel. But other:thing channel gets the new state as a command, it’ll get sent to a real device likely. This is the “follow”.
When Item mySwitch gets a command, it gets passed to some:thing channel, to binding, to device. I’m not really sure what happens to other:thing channel, but I think nothing. But note that most likely the command will cause a state update to this Item one way or another, and then follow will kick into action.
When some data arrives from device via binding to some:thing channel it causes an Item state update. This update will invoke follow as already described, and we’ll send a command via other:thing channel
When some data arrives from device via binding to other:thing channel, nothing happens to this Item.

This explains a pair of cross-linked devices behaviour, where as in this case both accept commands and respond with update.
command -> device A (ignored by B)
or
someone presses the button on device A
A updates -> Item A, triggers ‘follow’ to make command -> device B
B updates -> Item B, triggers ‘follow’ to command -> device A
A updates -> Item A, triggers ‘follow’ to command -> device B

This happens because follow profile is too dim witted not to send a command if something is already in the desired state, and the device always responds with an update even if already in desired state.
I’m pretty sure follow kicks in for any update, and not just changes, but stand to be corrected on that.

The cure is a rule to add the needed intelligence.

Now, don’t ask me what follow profile does when you give it an Item as a parameter !!

yes so in other words, it’s better to use rules instead of following profile cos it’s following anything happening not comparing states, which in some cases can end up in infinite loop.

I’m pretty sure it will work just fine (I’ve tried) with dummy mqtt item which does not send confirmation message to mqtt to the topic monitored by OH.
Issue seems to be simply in fact that tasmota (and might be some others) basically doing:

--> received mqtt command
--> doing stuff
--> sending state to mqtt after command exectution

the last bit simply triggers following profile again, and whole process is repeated but on Swtich B, which then triggers Switch A and so on.

It’s nice feature tho, I’m not real fan of writing rules on everything, and tandem switches is something which is in many houses. Would be super great to use following profiles on this.

Info -

Yep, that works fine.

So does postUpdate with just a state, that’s a surprise.
mySwitch.postUpdate(otherSwitch.state)

Numbers work
myNumber.sendCommand(otherNumber.state)
Strings don’t work
myString.sendCommand(otherString.state)

The reason is described in the GitHub issue:

The postUpdate method is provided with a State as parameter while the sendCommand method is provided with a Command as parameter (a Command object is not a State object).

Addtiotinally the sendCommand is provided with a String or a Number as parameter but not with an OnOffType or any other State. The example using a Number item is working because it carries a DecimalType which extends Number - it will be converted internal accordingly.

To be honest that cannot result from a “follow” profile which only forwards a state sent to one item to another item.

Well i can reproduce this anytime you like for debuging.
And as well I can do it without loop by the rule in OH or NodeRed.
So yes follow profile causes loop with tasmota devices

To be fair, it’s TWO follows that make the loop. It’s what you needed for your desired action, but in this case cannot be used.