Openhabian- PI 3 - openHAB 2.2.0-1 (Release Build)
I trying to get a timer based rule to work correct , logic is when Garage door is left open for longer than 2 minutes send me a message , if door is closed within that time frame (less than 2 minutes) then cancel the timer
Timer triggers successfully but does not “cancel” when door is closed … hence even if door is closed with the 2 minute time frame i still get the pushover that its open for more than 2 minutes… i have tried may iterations such as :
Current code not working … no log errors …Please help
var Timer GarageTimer = null
rule "Garage Open Too Long"
when
Item GGDoorSensor1 received update OPEN
then
if (GarageTimer === null) {
GarageTimer = createTimer(now.plusSeconds(120)) [|
pushover("Garage Door 1 Open for more than 2 Minutes!!!!")
GarageTimer = null // reset the timer
]
}
end
rule "Garage Door Closed - Cancel Timer"
when
Item GGDoorSensor1 received update CLOSED
then
GarageTimer?.cancel
GarageTimer = null
end
import java.util.HashMap
var HashMap<String, Timer> tTimersWithCancel = newHashMap()
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// parameters:
// relatedItem = Item which should be changed if tiemr ends
// tTimersWithCancel = pointer to the timer variable
// timerlengthinseconds = timer time in sec.
// Length in sec. of the timer
// 0 = Timer should end now and timer end action should be done
// -1 = Timer should cancel and action should not be done
// newitemstate = State of the item after timer ends
//
val Procedures$Procedure4<GenericItem, HashMap<String, Timer>, Integer, String> startTimerWithCancel=[relatedItem, tTimersWithCancel, timerlengthinseconds, newitemstate |
// Timer should 3end before real end
// end action should be done
if(timerlengthinseconds == 0)
{
if(tTimersWithCancel.get(relatedItem.name) !== null)
tTimersWithCancel.get(relatedItem.name).reschedule(now)
return;
}
// Timer should be canceled
// end action should not be done
if(timerlengthinseconds < 0)
{
if(tTimersWithCancel.get(relatedItem.name) !== null)
{
tTimersWithCancel.get(relatedItem.name).cancel()
tTimersWithCancel.put(relatedItem.name, null)
tTimersWithCancel.remove(relatedItem.name)
logInfo("TIMERCHECK", "TimerWithCancel for Item " + relatedItem.label + " canceled. No action executed.")
}
return;
}
// Timer should be started
// wait a little bit, if two timers end on the same time not all of them are execute the commands
Thread::sleep(100)
// create the timer and do the action at the end of the timer
if(tTimersWithCancel.get(relatedItem.name) === null || tTimersWithCancel.get(relatedItem.name).hasTerminated)
{
logInfo("TIMERCHECK", "TimerWithCancel for Item " + relatedItem.label + " started with " + timerlengthinseconds + " sec.")
tTimersWithCancel.put(relatedItem.name, createTimer(now.plusSeconds(timerlengthinseconds)) [|
tTimersWithCancel.get(relatedItem.name).cancel()
tTimersWithCancel.put(relatedItem.name, null)
tTimersWithCancel.remove(relatedItem.name)
logInfo("TIMERCHECK", "TimerWithCancel for Item " + relatedItem.label + " reached end. Action " + newitemstate.toString + " executed.")
relatedItem.sendCommand(newitemstate.toString)
])
}
// timer is running, just reschedule with full value of time
else
{
logInfo("TIMERCHECK", "TimerWithCancel for Item " + relatedItem.label + " rescheduled with " + timerlengthinseconds + " sec.")
tTimersWithCancel.get(relatedItem.name).reschedule(now.plusSeconds(timerlengthinseconds))
}
]
In fact, the rule should work as expected. Maybe the trigger does not work correct (e.g. contact bouncing i.e. multiple trigger).
You should insert a few lines for logging. By the way, you could use one rule:
var Timer GarageTimer = null
rule "Garage Door"
when
Item GGDoorSensor1 changed
then
logInfo ("garage.door","GGDoor Sensor 1 is {}",GGDoorSensor1.state)
if (GGDoorSensor1.state == OPEN) {
if (GarageTimer === null)
logInfo ("garage.door","GarageTimer is null -> create timer!")
GarageTimer = createTimer(now.plusSeconds(120)) [|
pushover("Garage Door 1 Open for more than 2 Minutes!!!!")
GarageTimer = null // reset the timer
]
else
logInfo ("garage.door","GarageTimer is not null -> do nothing!")
}
else {
logInfo ("garage.door","so cancel GarageTimer!")
GarageTimer.cancel
GarageTimer = null
}
end