This is actually a really good question. I’ve written a lot around this sort of thing in the past but I don’t think I’ve ever made a single posting on this specific subject.
There are a number of ways you can go about this but my preferred approach would be to take advantage of Groups and Design Pattern: Associated Items.
So what we will do is encode the switch_id in the name of some more Design Pattern: Unbound Item (aka Virtual Item) s. Then we will use a Group to loop through and parse out the switch_id from the unbound Item’s name.
Items
Group:Switch LR_Lights_Ids
Switch Arduino_1 (LR_Lights_Ids)
Switch Arduino_2 (LR_Lights_Ids)
Group:Switch HALL_Lights_Ids
Switch Arduino_3 (LR_Lights_Ids, HALL_Lights_Ids) // the same switch can be in multiple groups
Rules
rule "LR Lights switch triggered"
when
Item LR_Lights received command // this is a better trigger for an actuator
then
LR_Lights_Ids.members.forEach[sw |
val id = sw.name.split("_").get(1) // get the switch ID based on the unbound Item's name
val state = if(receivedCommand == ON) 1 else 0 // get the new state based on the received command
Arduino.sendCommand("<setRelay;" + id + ";" + state + ">") // send the command to the Arduino
]
end
If you were to apply some of the principals Design Pattern: Working with Groups in Rules, if you put your existing Design Pattern: Proxy Item into a Group and have them configured with persistence you can create a single rule for all of your Rooms.
Items
Group:Switch Lights // I don't know the full set of Items in gSwitches so am showing a new Group instead
Switch LR_Lights (gSwitches, Lights)
Switch HALL_Lights (gSwitches, Lights)
Group:Switch Room_Relays
Group:Switch LR_Lights_Ids (Room_Relays)
Switch Arduino_1 (LR_Lights_Ids)
Switch Arduino_2 (LR_Lights_Ids)
Group:Switch HALL_Lights_Ids (Room_Relays)
Switch Arduino_3 (LR_Lights_Ids, HALL_Lights_Ids) // the same switch can be in multiple groups
rule "A switch was triggered"
when
Item LR_Lights received command or
Item HALL_Lights received command
then
// get the switch that triggered the rule
Thread::sleep(100) // give persistence a chance to catch up
val trigger = Lights.members.filter[light | light.lastUpdate != null].sortBy[lastUpdate].last
// get the Group of Arduino switch ID items
val arduinos = Room_Relays.findFirst[grp | grp.name = trigger.name + "_Ids"] as GroupItem
// Send the command to all of the Arduinos by ID
arduinos.members.forEach[sw |
val id = sw.name.split("_").get(1) // get the switch ID based on the unbound Item's name
val state = if(receivedCommand == ON) 1 else 0 // get the new state based on the received command
Arduino.sendCommand("<setRelay;" + id + ";" + state + ">") // send the command to the Arduino
]
end