You are correct, there is no XOR operator for Groups so you do have to write the logic as a Rule.
You probably haven’t seen this particularly problem addressed because almost no (perhaps none) commercial multi-switches work like this. This sort of logic is either built into the switches themselves or, more typically, built into how they are wired to the light. So the problem hasn’t come up.
Also, there is no logical XOR operator in Java and I couldn’t find anything about one being in Xtend either. In other words, I don’t think ^^
is a thing (I could be wrong). But I’m not really sure you need that nor am I certain XOR is the correct operator.
For the most part aren’t you just looking to turn the light on is any of the other switches are ON? This is typically how multi-switches work.
If that is the case you can do something like the following:
Put the Items into a Group. You can use Group:Switch:OR(ON,OFF) gStairwayLight
to show the Group’s state as ON if any of the three are ON and OFF only if all of the three are OFF. However, you still need the Rule but can write it as
NOTE: I’m just typing this in, it may not work as written.
rule "StairwayLight"
when
Item gStairwayLight received update
then
gStairwayLight.members.forEach[SwitchItem sw |
if(sw.state == ON) {
if(StairwayLight.state != ON) StairwayLight.sendCommand(ON)
return
}
]
// If we got this far, all the switches are OFF
if(StiarwayLight.state != OFF) StairwayLight.sendCommand(OFF)
end
However, if to only turn the light on if all the switches are ON. In that case you can just swap the logic around a bit.
Change the Group to Group:AND(ON,OFF) gStairwayLight
which will set the Group’s state of ON if all the switches are ON and OFF if any of the Switches are OFF.
Then the Rule becomes:
rule "StairwayLight"
when
Item gStairwayLight received update
then
gStairwayLight.members.forEach[SwitchItem sw |
if(sw.state == OFF) {
if(StairwayLight.state != OFF) StairwayLight.sendCommand(OFF)
return
}
]
// If we got this far, all the switches are ON
if(StairwayLight.state != ON) StairwayLight.sendCommand(ON)
end
However, if you really do mean XOR (i.e. if 0 < number of switches that are ON < total number of switches, turn on the light. The Group won’t really work in this case but a Rule would be:
rule "StairwayLight"
when
Item gStairwayLight received update
then
val numON = gStairwayLight.members.filter[SwitchItem sw|sw.state == ON].size
val newState = if(numOn != 0 && numON != gStairwayLight.members.size) ON else OFF
if(StairwayLight.state != newState) StairwayLight.sendCommand(newState)
end
EDIT: I did some more reading and the bitwise XOR can be used as a logic XOR as well so the command would be:
if(SwitchUpstairs.state == ON ^ SwitchDownstairs.state == ON ^ SwitchWeb.state == ON)
Which, if I have my order of operations right is equivalent to
if((SwitchUpstairs.state == ON ^ SwitchDownstairs.state) ^ SwitchWeb.state == ON)