Hi guys,
I implemented a version of the alarm example (n.2) explained in the wiki page. Instead of one Timer, in the rule, I’m creating 4 timers, the first timer (timer0) uses the alarm time set by sitemap and the other 3 timers are created adding offset values (editable by sitemap) to the alarm time. Everything is working fine but sometimes the first timers is triggered with a delay until 15 minutes, but the others are triggered in time.
The second and the fourth timers (timer2, timer4) have been always triggered so far, but he third one (timer1) sometimes is not triggered.
Here’s my rule:
/************** Alarm ***********/
import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
import org.openhab.action.squeezebox.*
import java.util.concurrent.locks.ReentrantLock
var Timer timer0
var Timer timer1
var Timer timer2
var Timer timer3
var java.util.concurrent.locks.ReentrantLock lock1 = new java.util.concurrent.locks.ReentrantLock()
rule "Alarm"
when
Item alarmTimeHour changed or
Item alarmTimeMinutes changed or
Item alarmOffset1Minutes changed or
Item alarmOffset2Minutes changed or
Item alarmOffset3Minutes changed or
then
if(alarmEnabled.state != Uninitialized && alarmTimeHour.state != Uninitialized && alarmTimeMinutes.state != Uninitialized && alarmOffset1Minutes.state != Uninitialized && alarmOffset2Minutes.state != Uninitialized && alarmOffset3Minutes.state != Uninitialized && alarmTuesday.state != Uninitialized && alarmWensday.state != Uninitialized && alarmThursday.state != Uninitialized && alarmFriday.state != Uninitialized && alarmSaturday.state != Uninitialized && alarmSunday.state != Uninitialized)
{
// If the UI to change the Alarm time is clicked several times the code below
// is subject to race conditions. Therefore we make sure that all events
// are processed one after the other.
lock1.lock()
try {
var String msg = ""
logInfo("rules","Alarm has been changed.")
// Copy the Alarm-Time from the UI to local variables
var hour = alarmTimeHour.state as DecimalType
var minute = alarmTimeMinutes.state as DecimalType
// Combine the hour and minutes to one string to be displayed in the
// user interface
if (hour < 10) { msg = "0" }
msg = msg + alarmTimeHour.state.format("%d") + ":"
if (minute < 10) { msg = msg + "0" }
msg = msg + alarmTimeMinutes.state.format("%d")
postUpdate(alarmTimeMessage,msg)
logInfo("rules","New alarm time: "+msg)
// calculate the alarm time [min]
var int alarm1
alarm1 = (alarmTimeHour.state as DecimalType).intValue * 60 +
(alarmTimeMinutes.state as DecimalType).intValue
alarm1 = alarm1.intValue
// calculate current time [min]
var int hour1
hour1 = now.getMinuteOfDay
hour1 = hour1.intValue
// calculate the difference between the requested alarm time and
// current time (again in minutes)
var int delta1
delta1 = (alarm1 - hour1)
delta1 = delta1.intValue
// add one day (1440 minutes) if alarm time for today already passed
if (hour1 > alarm1) { delta1 = delta1 + 1440 }
// set the others timer based on the offsets
var int delta2
delta2 = delta1 + (alarmOffset1Minutes.state as DecimalType).intValue
var int delta3
delta3 = delta1 + (alarmOffset2Minutes.state as DecimalType).intValue
var int delta4
delta4 = delta1 + (alarmOffset3Minutes.state as DecimalType).intValue
// check if there is already an alarm timer0; cancel it if present
if (timer0 != null) {
timer0.cancel
timer0 = null
}
// create a new timer using the calculated delta [min]
timer0 = createTimer(now.plusMinutes(delta1)) [|
// This code will be executed if the timer triggers
// ************************************************
// check if alarm clock is enabled and armed for this weekday
if(alarmEnabled.state == ON)
{
var Number day = now.getDayOfWeek
if (((day == 1) && (alarmMonday.state == ON)) ||
((day == 2) && (alarmTuesday.state == ON)) ||
((day == 3) && (alarmWensday.state == ON)) ||
((day == 4) && (alarmThursday.state == ON)) ||
((day == 5) && (alarmFriday.state == ON)) ||
((day == 6) && (alarmSaturday.state == ON)) ||
((day == 7) && (alarmSunday.state == ON))) {
// The things to do if the alarm clock is enabled for this day of week:
callScript("alarm1")
}//if
}//if enabled
// Re-Arm the timer to trigger again tomorrow (same time)
timer0.reschedule(now.plusHours(24))
]
logInfo("rules","Alarm, timer0 set.")
// check if there is already an alarm timer1; cancel it if present
if (timer1 != null) {
timer1.cancel
timer1 = null
}
// create a new timer using the calculated delta [min]
timer1 = createTimer(now.plusMinutes(delta2)) [|
// This code will be executed if the timer triggers
// ************************************************
// check if alarm clock is enabled and armed for this weekday
if(alarmEnabled.state == ON)
{
var Number day = now.getDayOfWeek
if (((day == 1) && (alarmMonday.state == ON)) ||
((day == 2) && (alarmTuesday.state == ON)) ||
((day == 3) && (alarmWensday.state == ON)) ||
((day == 4) && (alarmThursday.state == ON)) ||
((day == 5) && (alarmFriday.state == ON)) ||
((day == 6) && (alarmSaturday.state == ON)) ||
((day == 7) && (alarmSunday.state == ON))) {
// The things to do if the alarm clock is enabled for this day of week:
callScript("alarm2")
}
}
// Re-Arm the timer to trigger again tomorrow (same time)
timer1.reschedule(now.plusHours(24))
]
logInfo("rules","Alarm, timer1 set.")
// check if there is already an alarm timer2; cancel it if present
if (timer2 != null) {
timer2.cancel
timer2 = null
}
// create a new timer using the calculated delta [min]
timer2 = createTimer(now.plusMinutes(delta3)) [|
// This code will be executed if the timer triggers
// ************************************************
// check if alarm clock is enabled and armed for this weekday
if(alarmEnabled.state == ON)
{
var Number day = now.getDayOfWeek
if (((day == 1) && (alarmMonday.state == ON)) ||
((day == 2) && (alarmTuesday.state == ON)) ||
((day == 3) && (alarmWensday.state == ON)) ||
((day == 4) && (alarmThursday.state == ON)) ||
((day == 5) && (alarmFriday.state == ON)) ||
((day == 6) && (alarmSaturday.state == ON)) ||
((day == 7) && (alarmSunday.state == ON))) {
// The things to do if the alarm clock is enabled for this day of week:
callScript("alarm3")
}
}
// Re-Arm the timer to trigger again tomorrow (same time)
timer2.reschedule(now.plusHours(24))
]
logInfo("rules","Alarm, timer2 set.")
// check if there is already an alarm timer3; cancel it if present
if (timer3 != null) {
timer3.cancel
timer3 = null
}
// create a new timer using the calculated delta [min]
timer3 = createTimer(now.plusMinutes(delta4)) [|
// This code will be executed if the timer triggers
// ************************************************
// check if alarm clock is enabled and armed for this weekday
if(alarmEnabled.state == ON)
{
var Number day = now.getDayOfWeek
if (((day == 1) && (alarmMonday.state == ON)) ||
((day == 2) && (alarmTuesday.state == ON)) ||
((day == 3) && (alarmWensday.state == ON)) ||
((day == 4) && (alarmThursday.state == ON)) ||
((day == 5) && (alarmFriday.state == ON)) ||
((day == 6) && (alarmSaturday.state == ON)) ||
((day == 7) && (alarmSunday.state == ON))) {
// The things to do if the alarm clock is enabled for this day of week:
callScript("alarm4")
}
}
// Re-Arm the timer to trigger again tomorrow (same time)
timer3.reschedule(now.plusHours(24))
]
logInfo("rules","Alarm, timer3 set.")
} finally {
// release the lock - we are ready to process the next event
lock1.unlock()
}
end
}//IF
end
Do you have any suggestion to solve the issues?
Thank you.
P.S. I’m running openhab 1.8.1 on ubuntu.