@5iver’s approach is exactly what I would have suggested.
I wrote up a DP that covers using a naming scheme like this to access related Items: Design Pattern: Associated Items
However, I’ve seen your original approach used by many before so I wanted to address a way of thinking about coding that can save you some complexity in the future even when tricks like Associated Items are not available.
So let’s work on the rule as written without that but just restructure what is written and see what we can do.
I like to apply Don’t Repeat Yourself (DRY) not only across rules but within Rules as well. I suspect that is the source of your discomfort with what you have in the OP. One way to apply DRY within a Rule is to only call Actions or methods that cause side effects (e.g. sendNotification, postUpdate, sendCommand, etc) once in the Rule. This will often require restructuring your Rule along the lines of:
- first determine if something needs to be done at all
- then calculate the new states or messages or whatever side effects need to be performed
- finally perform the side effects.
Looking at the original rule I see the overall task is to send an ON or OFF command to two other Items based on a received command. So what I would do is:
-
Since the Rule is triggered by a command we know that we have to do something in this Rule every time so 1. is already done.
-
The command that gets sent to the other Items is the same as receivedCommand so we will just use receivedCommand later in the rule. So the next part of 2. is to determine what Items to send the command to. there are lots of approaches including continuing to use the switch statement and assigning the Items to call to variables. There are other approaches I can think of but they all lead to Scott’s approach so I won’t go down that path right now.
-
Finally, we do the side effects which are in this case a sendCommand.
rule "Automated Temperature Control"
when
Item BR1_Climate_auto received command or
Item BR2_Climate_auto received command or
Item BR3_Climate_auto received command or
Item BR4_Climate_auto received command or
Item LR_Climate_auto received command or
Item GR_Climate_auto received command or
Item HO_Climate_auto received command
then
logDebug("autoclimate.rules", triggeringItem.name + " received a command: " + receivedCommand)
// 1. decide if we need to do something at all, in this case we always
// want to do something so nothing needs to be done here
// 2. Calculate what states need to change and what they need to change to
var temp = null
var humid = null
switch triggeringItem.name {
case "BR1_Climate_auto" : { temp = BR1_Temp_auto humid = BR1_Humid_auto }
case "BR2_Climate_auto" : { temp = BR2_Temp_auto humid = BR2_Humid_auto }
case "BR3_Climate_auto" : { temp = BR3_Temp_auto humid = BR3_Humid_auto }
case "BR4_Climate_auto" : { temp = BR4_Temp_auto humid = BR4_Humid_auto }
case "LR_Climate_auto" : { temp = LR_Temp_auto humid = LR_Humid_auto }
case "GR_Climate_auto" : { temp = GR_Temp_auto humid = GR_Humid_auto }
case "HO_Climate_auto" : { temp = HO_Temp_auto humid = HO_Humid_auto }
}
if(temp === null || humid === null) {
logError("autoclimate.rules", "Unexpectedly reached default case")
return;
}
// 3. Perform the actions that have side effects
temp.sendCommand(receivedCommand)
humid.sendCommand(receivedCommand)
logInfo("autoclimate.rules", triggeringItem.name + " Climate control has been disabled")
end
Besides being somewhat shorter, one reason that the above is better is that should you decide that you need to do something else before sending the command or provide some additional checking or the like before sending the command you only have to do it once and in one place in the Rule. That switch statement is still kind of long and ugly (hence Scott’s solution truly being the correct one) and I would look for ways to improve that but as I mentioned, all those roads lead to variations of Scott’s solution. And that isn’t the point of this post.
The point is to show how adjusting the structure of a Rule applying DRY can help one consolidate and overcome lots of repetitive code.