when
Item Z_LUX_GF_Hallway changed
then
logInfo("Z_LuxSetpoint_GF_Hallway", "GF Lux changed. Lux: "+Z_LUX_GF_Hallway.state+" - SetPoint: "+Z_LuxSetpoint_GF_Hallway.state+" - Strip Light: "+Hue_LivingRoom_StripLight.state)
if ((Z_LUX_GF_Hallway.state as DecimalType) < (Z_LuxSetpoint_GF_Hallway.state as DecimalType) && Twilight_Lux.state == ON)
{
sendCommand(Hue_LivingRoom_StripLight, ON)
logInfo("Z_LuxSetpoint_GF_Hallway", "GF Lux changed. Lux: "+Z_LUX_GF_Hallway.state+" - SetPoint: "+Z_LuxSetpoint_GF_Hallway.state+" - Strip Light: "+Hue_LivingRoom_StripLight.state)
sendMail("poe@email.address", "GF Lux < SetPoint", "GF Lux is below the SetPoint, StripLight is now ON")
}
end
Which works absolutely fine. However, I check my Lux status every 5 minutes, and this is causing the rule to trigger many times.
Is there a way to just run the rule one time?
For example, my Twilight_Lux item is a dynamic window that is enabled 3 hours before SunSet and then goes off at Midnight. It would be brilliant if this rule would only fire one time during this window…
I didn’t know anything about ‘a latch’ - but it looks ideal! Thank you @Benjy !!
Question is, what exactly does it do?? Is it essentially a ‘switch’ for rule on, and rule off… ie. when triggered the rule is ON and stays on until the Cron time turns it off (midnight)…?
and what difference does ‘knowing the time it’s active for’ make, I ask, given the start time will be forever moving.
I presume in your example, ‘ruleTriggered’ can be renamed???
This is an excellent design pattern. I’m going to include it when I write up there design patterns section of the guide.
When ruleTriggered is false, the logic of the rule runs. One line in that logic sets ruleTriggered to true. As long as ruleTriggered is true, the if condition will be false so the logic will not run.
ruleTriggered remains false until the rule at midnight runs to set it back to false. The first time the main rule with the logic runs after midnight it can now run the logic because ruleTriggered is false.
There are several ways to implement this in addition to the above. One way is to use a Timer instead of the rule that runs at midnight to reset the ruleTriggered flag. Another is to use a reentrantLock instead of the boolean flag, though that would tie up a thread in the tread pool so I wouldn’t recomend it except for relatively short periods of time.
You can name ruleTriggered anything you want. The band didn’t matter.
The Cron in the example sets ruleTriggered to false at 1am each day, but this is fine because you know that your lux item goes off at midnight, but say you didn’t know a fixed time and just wanted to stop a rule from working more than once every 3 hours you can use a timer as @rlkoshak says e.g. :
var boolean ruleLock = false
var Timer exampleTimer = null
rule "Example Rule Timeout"
when
Item someThing changed
then
// If ruleLock is false
if(!ruleLock){
// Do things here
//Stop this rule being triggered again
ruleLock = true
//Then Create a timer that unlocks it in three hours
exampleTimer = createTimer(now.plusHours(3)) [|
ruleLock = false
]
}
end
I added your original effort with the Cron, to my rules, unfortunately this prevented all other rules from running, for some reason. I could see my items changing status, but no rules were firing…