How to store additional info in ITEM?

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
1 Like