What makes this solution different is that you have only a minimal set of items (3) per alarm, but still be able to restrict it to days. The Day item contains the a string which defines start and end day,e g. 15 is monday to friday.
Items
Number ALARM1_PERSON1_H "Hour [%s]"
Number ALARM1_PERSON1_M "Minute [%s]"
String ALARM1_PERSON1_D "Day"
Number ALARM2_PERSON1_H "Hour [%s]"
Number ALARM2_PERSON1_M "Minute [%s]"
String ALARM2_PERSON1_D "Day"
rule "ALARM PERSON1"
when
Time cron "0 * * * * ?"
then
var day_number = now.getDayOfWeek.toString
var minute_now = now.getMinuteOfHour
var hour_now = now.getHourOfDay
var ALARM1_PERSON1 = ((ALARM1_PERSON1_M.state as DecimalType).intValue == minute_now &&
(ALARM1_PERSON1_H.state as DecimalType).intValue == hour_now &&
day_number >= ALARM1_PERSON1_D.state.toString.substring(0,1) &&
day_number <= ALARM1_PERSON1_D.state.toString.substring(1,2))
var ALARM2_PERSON1 = ((ALARM2_PERSON1_M.state as DecimalType).intValue == minute_now &&
(ALARM2_PERSON1_H.state as DecimalType).intValue == hour_now &&
day_number >= ALARM2_PERSON1_D.state.toString.substring(0,1) &&
day_number <= ALARM2_PERSON1_D.state.toString.substring(1,2))
if(ALARM1_PERSON1 || ALARM2_PERSON1){
// do stuff, e.g. turn radio or light on
TIMER_PERSON1_ALARM=createTimer(now.plusMinutes(80)) [|
// turn off stuff
]
}
end
hi, can u help me? … i want to use ur alarm in my setup so i can on/off any item, i dont mind repeating the rule/sitemap for each item…how can i achieve this?
You could copy the items and rules for each item you want to switch, but there is probably a better solution.
Let’s say you have the items A and B, you could define A_ALARM and B_ALARM, put them in a group and check this group for all on items. Then remove “_ALARM” from their name and you have the item, that should turned on.
Salaam brother,
Once you come up with some code, if it doesn’t work, post it here and we’ll have a look at it to help, but we are not here to write code for you.
Take care
Hey, because this was todays top result from searching “openhab alarm clock” I would like to post my improved version. It it’s a mix of this and code from the android alarm-clock - version
Add your things to do in line 71 of the rule
items:
Number ALARM1_PERSON1_H "Wecker Stunde [%s]"
Number ALARM1_PERSON1_M "Wecker Minute [%s]"
String ALARM1_PERSON1_D "Wecker Wochentage"
Sitemap:
Frame label="Wecker" {
Selection item=ALARM1_PERSON1_D label="Tage" mappings=[0=" Aus ", 1=" Mo - Fr ", 2=" Sa - So ", 3=" Alle Tage "]`
Setpoint item=ALARM1_PERSON1_H label="Stunde" minValue=0 maxValue=23 step=1
Setpoint item=ALARM1_PERSON1_M label="Minuten" minValue=0 maxValue=55 step=5
}
Rule:
import java.time.ZonedDateTime
import java.time.DayOfWeek
val org.eclipse.xtext.xbase.lib.Functions$Function1<ZonedDateTime,ZonedDateTime> getNextAlarm= [ ZonedDateTime s |
var newTime = s
if(newTime < ZonedDateTime.now){
newTime = newTime.plusDays(1)
}
val DayOfWeek[] theWorkDays = newArrayList(DayOfWeek.MONDAY,DayOfWeek.TUESDAY,DayOfWeek.WEDNESDAY,DayOfWeek.THURSDAY,DayOfWeek.FRIDAY)
val DayOfWeek[] weekEndDays = newArrayList(DayOfWeek.SATURDAY,DayOfWeek.SUNDAY)
var dayIsValid = false
while (dayIsValid == false) {
switch(ALARM1_PERSON1_D.state as Number) {
case 1: dayIsValid = theWorkDays.contains(newTime.getDayOfWeek())
case 2: dayIsValid = weekEndDays.contains(newTime.getDayOfWeek())
case 3: dayIsValid = theWorkDays.contains(newTime.getDayOfWeek()) || weekEndDays.contains(newTime.getDayOfWeek())
}
if(dayIsValid == false){
newTime = newTime.plusDays(1)
}
}
newTime.withSecond(0)
]
var Timer timerAlarm = null
rule "Alarm Clock"
when
Item ALARM1_PERSON1_D changed or Item ALARM1_PERSON1_H changed or Item ALARM1_PERSON1_M changed
then
val settingsOffOrInvalid = (ALARM1_PERSON1_D.state === NULL || ALARM1_PERSON1_D.state == "0") || ALARM1_PERSON1_H.state === NULL || ALARM1_PERSON1_M === NULL || ALARM1_PERSON1_M.state === NULL
if(settingsOffOrInvalid && timerAlarm !== null){
logInfo("alarm", "Alarm canceled")
timerAlarm.cancel
timerAlarm = null
}
if(settingsOffOrInvalid){
logInfo("alarm", "no alarm set")
return
}
val newHour = (ALARM1_PERSON1_H.state as DecimalType).intValue
val newMinute = (ALARM1_PERSON1_M.state as DecimalType).intValue
var newZonedDateTime = ZonedDateTime.now
newZonedDateTime = newZonedDateTime.withHour(newHour)
newZonedDateTime = newZonedDateTime.withMinute(newMinute)
val newTime = getNextAlarm.apply(newZonedDateTime)
logInfo("alarm", newTime.toString)
val epoch = newTime.toInstant.toEpochMilli
if (timerAlarm !== null) {
logInfo("alarm", "Reschedule alarm")
timerAlarm.reschedule(new DateTime(epoch))
} else {
logInfo("alarm_NEW_ALARM", newTime.toString)
timerAlarm = createTimer(new DateTime(epoch), [ |
// Add you stuff to do here
val nextTime = ZonedDateTime.now.plusDays(1)
val newResheduleTime = getNextAlarm.apply(nextTime)
val innerepoch = newResheduleTime.toInstant.toEpochMilli
logInfo("alarm_FIRED_ALARM_RESCHEDULE", newResheduleTime.toString)
timerAlarm.reschedule(new DateTime(innerepoch))
])
}
end
there seems to be a typo in sitemap last symbol here: Alle Tage "]`
I quickly tried it and alarm doesn´t get triggerted, log shows:
Rule ‘Alarm Clock’: Could not cast 1 to java.lang.Number; line 17, column 16, length 32
Diddn´t got time to investigate, but doesen´t seem to run out of the box.
Hey everybody,
i built items and rules like tutorial in OH 3.
OH3 shows the correct alarm time und the log alse shows the correct alarm changes.
Bute my choosen things didn’t start at alarm time.
Did anyone find the error at my rule?
var Timer timerAlarm = null
rule "Alarm Clock"
when
Item S20AlarmClock changed
then
if (newState instanceof DateTimeType) {
val epoch = newState.toLocaleZone.zonedDateTime.toInstant.toEpochMilli
logInfo("alarm", "Scheduling alarm for {} ({})", newState.toLocaleZone, epoch)
if( timerAlarm !== null ) {
logInfo("alarm", "Reschedule alarm")
timerAlarm.reschedule(newState.toLocaleZone.zonedDateTime)
} else {
logInfo("alarm", "New alarm")
timerAlarm = createTimer(newState.toLocaleZone.zonedDateTime, [ |
// Turn on stuff, e.g. radio or light
Echo_Living_Room_Radio.sendCommand(ON)
Echo_Living_Room_Player.sendCommand('PLAY')
RadioPower.sendCommand(ON)
logInfo("alarm", "Alarm expired")
timerAlarm = null
])
}
} else {
if (timerAlarm !== null) {
timerAlarm.cancel
timerAlarm = null
}
logInfo("alarm", "Alarm canceled")
}
end