You can use the previousState and newState implicit variables to check if the temperature is lower than it was before. Here’s a rule I use to turn my 3D printer off after the temperature has dropped below 50°C.
var newTemp = newState as Number
var previousTemp = previousState as Number
if (newTemp < previousTemp && octoPrint_Temperature_Hotend.state > 40|°C && octoPrint_Temperature_Hotend.state < 50|°C)
{
octoPrint_3D_Printer.sendCommand(OFF)
}
I also have a condition that it must be above 40°C. The reason for this is that when I turn the printer back on, the hotend will be lower than 50°C (since it’s at room temperature). So if the temperature drops at all, it’ll trigger the rule and immediately turn the printer off while I’m setting up to print.
Personally, I wouldn’t use a timer. I’d make a gatekeeper item that gets turned ON when the rule runs, with expire metadata set to 20 minutes. Then I’d have the rule check if the gatekeeper is ON before triggering a notification. But that’s just how I like doing things.
You don’t need a timer for this. Save a timestamp when you alert as the global and then test whether it’s been 20 minutes since that timestamp before sending another one.
var lastAlert = now.minusMinutes(21) // make sure the first time it breaks the threshold an alert is sent
rule "Temp alert"
when
Item TempSensor changed
then
// If the temp is below the threshold nothing to do
if(TempSensor.state < 12 | °C) {
return;
}
// If we get to this point the temp is too high, send the alert if it's been long enough since the last one.
if(lastAlert.isBefore(now.minusMinutes(20)) {
// send the alert
lastAlert = now
}
end
Presumably the temperature sensor is periodically reporting new temps so that will drive the repeated alerts so we don’t need a looping timer for this.