This runs a very high risk of creating the XY Problem. That’s another reason I don’t recommend it. As many of us have indicated, you are trying to solve a specific problem with lambdas but your entire use of lambdas is suspect.
Then you might be happier coding in JSR223 Rules. Global lambdas are dangerous, error prone, and a huge code smell and should only be used as a last resort. The perceived elegance is far out weighted by the suppressed error reporting, non-thread safeness, and other limitations.
Wait, these are not global lambdas? Well, that addresses some of the issues with lambdas because new ones are created with every execution of the Rule, but they are really not needed. A far better approach is Design Pattern: How to Structure a Rule to avoid duplicated code.
rule "Thrigger Activites based on DayState changes"
when
// Time cron "0/30 0/1 * 1/1 * ? *" or // Run every 30 seconds for debugging purposes
Item Day_Activity changed
then
// 1: always run the Rule
// 2: calculate what the rule needs to to
var rule_name = "MyRules.Daystate"
var heater_control = false
var outlet_control = false
var outlet_state = OFF
var lights_control = false
switch Day_Activity.state {
// case "WAKEUP": // nothing to do
case "GETTING READY": heater_control = true // state is already defaulted to OFF
case "AT WORK": {
heater_control = true
outlet_control = true // state is already defaulted to OFF
light_control = true
}
case "AT HOME": {
outlet_control = true // state is already defaulted to OFF
heater_control = true
}
case "LUNCH",
case "DINNER": {
outlet_control = true
outlet_state = ON
}
case "IN BED": outlet_control = true // state is already defaulted to OFF
case "SLEEPING": {
light_control = true
outlet_control = true // state is already defaulted to OFF
}
}
// 3: do it
// heater
if(heater_control){
Sycamore_Heater.allMembers.filter[ i | i.state == ON].forEach(item | {
item.sendCommand(OFF)
logInfo(rule_name,"Forgot to turn off the {}. Turning it OFF ", item.label)
})
}
// outlet
if(outlet_control){
Sycamore_Outlet.allMembers.filter[ item | item.state != outlet_state && item.label.toString.contains("Left") ].forEach[ item |
item.sendCommand(outlet_state)
if ( outlet_state == ON ) { logInfo(rule_name,"We are probably cooking!!! Turning ON the Air Wick on {}.", item.label)}
if ( outlet_state == OFF ) { logInfo(rule_name,"Turning Off the Air Wick on {}.", item.label)}
]
}
// lights
if(light_control){
Sycamore_Lights.allMembers.forEach(item | {
if( item.state > 0 || item.state == ON) {
item.sendCommand(OFF)
logInfo(rule_name,"Forgot to turn off the {}. Turning it OFF ", item.label)
}
})
}
end
The above is fewer lines of code (fewer usually means easier to understand and maintain), fewer levels of context (i.e fewer indentation levels which also means easier to understand and maintain), has no repeated code that modifies state (e.g. sendCommand or postUpdate) which is what I think you were trying to avoid, and it doesn’t introduce the complexity and overhead of using lambdas.
Also notice I streamlined the outlet control by using a filter instead of an if statement inside the forEach.