Does the KNX binding support transformations? I ask because if I were implementing this with something like MQTT I would create a separate Switch or Contact to represent each RFID I care about. The actual RFID would be encoded in the MQTT binding config. So when a given RFID is presented, a Switch for that specific RFID would switch to ON or OPEN.
Next, put those Items associated with a IDs that should unlock the door into the same group and your Rule would look something like:
rule "Known RFID present"
when
Item RFIDs received update
then
val idsPresent = RFIDs.members.filter[id | id.state == ON]
if(idsPresent.size == 0) {
// no IDs present, lock the door?
}
else if(door.state != OPEN) { // door is not already unlocked
// unlock the door
}
end
With an approach like this you can add and revoke access to specific IDs simply by adding/removing Items to and from the RFIDs group. You can further do special things for individual RFIDs by creating a new Rule triggered just by that one RFID’s Item.
Personally, even if you cannot do this with the KNX binding like one could with MQTT and transformations, I would probably create a Rule to parse the RFID and sendCommand to individual Items like this anyway. Something like:
rule "rfid seen"
when
Item rfid-code received update
then
// Get the Item associated with this RFID
val idItem = AllRFIDs.members.findFirst[id | id.name == "RFID_"+rfid-code.state.toString]
if(idItem != null) idItem.sendCommand(ON)
else logInfo("access", "Received unknown/unauthorized RFID: " + rfid-code.state.toString)
end
So with this approach, you still get to add/revoke RFIDs from the access list only now the actual ID is encoded in the Item name rather than the binding config. Then keep the rules above to actually process the events.
In the short run this is probably a little more complex to implement than a switch statement, but, like Ray, I prefer to make updates in the .items rather than .rules when all I’m doing is adding, removing, or modifying something like an access list.
The full code:
Items:
String rfid-code { knx config }
Group:Switch AllRFIDs
Group:Switch AuthRFIDs
Group:Switch UnauthRFIDs
Switch RFID_1234 (AllRFIDs,AuthRFIDs) { expire="1m,command=OFF" }
Switch RFID_5678 (AllRFIDs,AuthRFIDs) { expire="1m,command=OFF" }
Switch RFID_9012 (AllRFIDs,UnauthRFIDs) { expire="1m,command=OFF" }
Switch DoorLock { ??? }
rule "rfid seen"
when
Item rfid-code received update
then
// Get the Item assocaited with this RFID
val idItem = AllRFIDs.members.findFirst[if | id.name == "RFID_"+rfid-code.state.toString]
// Unknown ID
if(idItem == null) logWarn("access", "Unknown RFID: " + rfid-code.state.toString)
// Known ID
else idItem.sendCommand(ON)
end
rule "Authorized rfid seen or left"
when
Item AuthRFIDs received update
then
// should we lock or unlock?
val newState = if(AuthRFIDs.members.filter[id | id.state == ON].size > 0) ON else OFF
if(DoorLock.state != newState) DoorLock.sendCommand(newState)
end
rule "Unauthorized rfid seen"
when
Item UnauthRFIDs received update
then
// generate an alert if desired or simply ignore
end
rule "Specific rfid seen"
when
Item RFID_1234 received command ON
then
createTimer(now.plusMinutes(1), [ | say("Welcome home Halloween!")]
end