Hello,
I needed an alarm clock with these features:
- Set different alarm times for each day of week, with adjustable “run time” (so to turn of stuff after a while)
- Define presets for Hour,Minute,Runtime (e.g. for people working early/late shifts)
- Must be usable for several family members if need be
- ability to individually greet persons once they reach the kitchen or bathroom
So here is what i came up with. It includes all items, rules,sitemaps and HABPanel Widgets needed for a single person. Maximum runtime is 180 Minutes with 10 Minute increments; change values as desired. If you want to reuse, basically you only need to copy&paste the items,rules and sitemap and replace PERSON1 with “dad” “mum” “kid” or whatever fits. Special case is the rule “react to move” where you would need to cut&paste only the If-clause and amend “PERSON1_WECKER_AKTIV.state” accordingly. So without further much ado here it is:
Items:
Group gPERSON1Wecker
//Wecker Montag
Switch PERSON1_WECKER_MO "Wecker Montag" <clock> (gPERSON1Wecker)
Number PERSON1_WECKER_MO_H "Weckzeit Montag Stunde [%s]" <calendar> (gPERSON1Wecker)
Number PERSON1_WECKER_MO_M "Weckzeit Montag Minute [%s]" <calendar> (gPERSON1Wecker)
Number PERSON1_WECKER_MO_RUN "Wecker Montag Laufzeit [%s]" <clock> (gPERSON1Wecker)
//Wecker Dienstag
Switch PERSON1_WECKER_DI "Wecker Dienstag" <clock> (gPERSON1Wecker)
Number PERSON1_WECKER_DI_H "Weckzeit Dienstag Stunde [%s]" <calendar> (gPERSON1Wecker)
Number PERSON1_WECKER_DI_M "Weckzeit Dienstag Minute [%s]" <calendar> (gPERSON1Wecker)
Number PERSON1_WECKER_DI_RUN "Wecker Dienstag Laufzeit [%s]" <clock> (gPERSON1Wecker)
//Wecker Mittwoch
Switch PERSON1_WECKER_MI "Wecker Mittwoch" <clock> (gPERSON1Wecker)
Number PERSON1_WECKER_MI_H "Weckzeit Mittwoch Stunde [%s]" <calendar> (gPERSON1Wecker)
Number PERSON1_WECKER_MI_M "Weckzeit Mittwoch Minute [%s]" <calendar> (gPERSON1Wecker)
Number PERSON1_WECKER_MI_RUN "Wecker Mittwoch Laufzeit [%s]" <clock> (gPERSON1Wecker)
//Wecker Donnerstag
Switch PERSON1_WECKER_DO "Wecker Donnerstag" <clock> (gPERSON1Wecker)
Number PERSON1_WECKER_DO_H "Weckzeit Donnerstag Stunde [%s]" <calendar> (gPERSON1Wecker)
Number PERSON1_WECKER_DO_M "Weckzeit Donnerstag Minute [%s]" <calendar> (gPERSON1Wecker)
Number PERSON1_WECKER_DO_RUN "Wecker Donnerstag Laufzeit [%s]" <clock> (gPERSON1Wecker)
//Wecker Freitag
Switch PERSON1_WECKER_FR "Wecker Freitag" <clock> (gPERSON1Wecker)
Number PERSON1_WECKER_FR_H "Weckzeit Freitag Stunde [%s]" <calendar> (gPERSON1Wecker)
Number PERSON1_WECKER_FR_M "Weckzeit Freitag Minute [%s]" <calendar> (gPERSON1Wecker)
Number PERSON1_WECKER_FR_RUN "Wecker Freitag Laufzeit [%s]" <clock> (gPERSON1Wecker)
//Wecker Samstag
Switch PERSON1_WECKER_SA "Wecker Samstag" <clock> (gPERSON1Wecker)
Number PERSON1_WECKER_SA_H "Weckzeit Samstag Stunde [%s]" <calendar> (gPERSON1Wecker)
Number PERSON1_WECKER_SA_M "Weckzeit Samstag Minute [%s]" <calendar> (gPERSON1Wecker)
Number PERSON1_WECKER_SA_RUN "Wecker Samstag Laufzeit [%s]" <clock> (gPERSON1Wecker)
//Wecker Sonntag
Switch PERSON1_WECKER_SO "Wecker Sonntag" <clock> (gPERSON1Wecker)
Number PERSON1_WECKER_SO_H "Weckzeit Sonntag Stunde [%s]" <calendar> (gPERSON1Wecker)
Number PERSON1_WECKER_SO_M "Weckzeit Sonntag Minute [%s]" <calendar> (gPERSON1Wecker)
Number PERSON1_WECKER_SO_RUN "Wecker Sonntag Laufzeit [%s]" <clock> (gPERSON1Wecker)
Switch PERSON1_WECKER_AKTIV "Wecker PERSON1 Aktiv" (gPERSON1Wecker)
Number PERSON1_WECKER_PRESETS "Wecker Preset Laden" <calendar> (gPERSON1Wecker)
Rules:
// Lucky OH2 users can remove these pesky imports
import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
import org.openhab.action.squeezebox.*
import org.joda.time.*
import org.openhab.model.script.actions.Timer
//end of removable imports for OH2 users
var Timer timerPERSON1Wecker = null
rule "Person1 preset laden"
when
Item PERSON1_WECKER_PRESETS received command
then
var int sollMinute
var int sollStunde
var int RunTime
switch (PERSON1_WECKER_PRESETS.state){
//early shift
case 1:{
sollStunde=4
sollMinute=0
RunTime=40
}
//late shift
case 2:{
sollStunde=10
sollMinute=0
RunTime=40
}
}
//set hour,minute,runtime items for each day
var i = 0
var DerTag= "NA"
//don't change saturday/sunday. set i max=7 and uncomment cases if you have to work weekends, you unlucky soul
while ((i=i+1) <= 5) {
switch i{
case 1: DerTag = "MO"
case 2: DerTag = "DI"
case 3: DerTag= "MI"
case 4: DerTag= "DO"
case 5: DerTag= "FR"
//case 6: DerTag= "SA"
//case 7: DerTag= "SO"
}
//set all hours
gPERSON1Wecker.members.filter(s|s.name == "PERSON1_WECKER_"+DerTag+"_H").forEach[s | s.postUpdate(sollStunde)]
//set all minutes
gPERSON1Wecker.members.filter(s|s.name == "PERSON1_WECKER_"+DerTag+"_M").forEach[s | s.postUpdate(sollMinute)]
//set runtimes
gPERSON1Wecker.members.filter(s|s.name == "PERSON1_WECKER_"+DerTag+"_RUN").forEach[s | s.postUpdate(RunTime)]
}
end
rule "Wecker PERSON1"
when
Time cron "0 0/1 * * * ?"
then
var Heute = ""
var boolean Wecken = false
var int sollMinute
var int sollStunde
var int RunTime
switch now.getDayOfWeek{
case 1: Heute = "MO"
case 2: Heute = "DI"
case 3: Heute= "MI"
case 4: Heute= "DO"
case 5: Heute= "FR"
case 6: Heute= "SA"
case 7: Heute= "SO"
}
if (gPERSON1Wecker.members.filter[s | s.name == "PERSON1_WECKER_"+Heute].head.state == ON) {
sollMinute = (gPERSON1Wecker.members.filter[s | s.name == "PERSON1_WECKER_"+Heute+"_M"].head.state as Number).intValue
sollStunde = (gPERSON1Wecker.members.filter[s | s.name == "PERSON1_WECKER_"+Heute+"_H"].head.state as Number).intValue
RunTime = (gPERSON1Wecker.members.filter[s | s.name == "PERSON1_WECKER_"+Heute+"_RUN"].head.state as Number).intValue
Wecken = true
}
if (sollMinute == now.getMinuteOfHour && sollStunde == now.getHourOfDay && Wecken==true) {
//WECKER_AKTIV to ON, so you can react to a move sensor downstairs or in the kitchen
// i use this for a squeezeboxspeak "Good morning. it is soandsomuch degrees"
// see rule "react to move"
//remove all references if you don't want/need this
sendCommand(PERSON1_WECKER_AKTIV,ON)
//Do Stuff here, like turn on lights,coffee machine and/or radio
timerPERSON1Wecker = createTimer(now.plusMinutes(RunTime)) [|
//turn lights,radio etc. of after defined time for day.
//sanity check turn off wecker_aktiv
sendCommand(PERSON1_WECKER_AKTIV,OFF)
timerPERSON1Wecker = null
]
}
end
rule "react to move"
when
Item your_move_sensor received update 1
then
//PERSON1 reached first floor/kitchen
if (PERSON1_WECKER_AKTIV.state==ON){
// example for squeezebox squeezeboxSpeak("Your_box", "Guten Morgen PERSON1. Es sind "+String::format("%.2f", (Terasse_temp.state as DecimalType).floatValue())+" Grad.", 80, true)
//wecker_aktiv to off, else speech would be repeated each time sensor is triggered
sendCommand(PERSON1_WECKER_AKTIV,OFF)
}
end
Sitemap:
sitemap PERSON1 label="PERSON1 Wecker"
{
Frame{
Switch item=PERSON1_WECKER_PRESETS mappings=[1="EARLY", 2="LATE"]
}
Frame {
Switch item=PERSON1_WECKER_MO mappings=[ON="AN", OFF="AUS"]
Setpoint item=PERSON1_WECKER_MO_H minValue=0 maxValue=23 step=1
Setpoint item=PERSON1_WECKER_MO_M minValue=0 maxValue=55 step=5
Setpoint item=PERSON1_WECKER_MO_RUN minValue=10 maxValue=180 step=10
}
Frame {
Switch item=PERSON1_WECKER_DI mappings=[ON="AN", OFF="AUS"]
Setpoint item=PERSON1_WECKER_DI_H minValue=0 maxValue=23 step=1
Setpoint item=PERSON1_WECKER_DI_M minValue=0 maxValue=55 step=5
Setpoint item=PERSON1_WECKER_DI_RUN minValue=10 maxValue=180 step=10
}
Frame {
Switch item=PERSON1_WECKER_MI mappings=[ON="AN", OFF="AUS"]
Setpoint item=PERSON1_WECKER_MI_H minValue=0 maxValue=23 step=1
Setpoint item=PERSON1_WECKER_MI_M minValue=0 maxValue=55 step=5
Setpoint item=PERSON1_WECKER_MI_RUN minValue=10 maxValue=180 step=10
}
Frame {
Switch item=PERSON1_WECKER_DO mappings=[ON="AN", OFF="AUS"]
Setpoint item=PERSON1_WECKER_DO_H minValue=0 maxValue=23 step=1
Setpoint item=PERSON1_WECKER_DO_M minValue=0 maxValue=55 step=5
Setpoint item=PERSON1_WECKER_DO_RUN minValue=10 maxValue=180 step=10
}
Frame {
Switch item=PERSON1_WECKER_FR mappings=[ON="AN", OFF="AUS"]
Setpoint item=PERSON1_WECKER_FR_H minValue=0 maxValue=23 step=1
Setpoint item=PERSON1_WECKER_FR_M minValue=0 maxValue=55 step=5
Setpoint item=PERSON1_WECKER_FR_RUN minValue=10 maxValue=180 step=10
}
Frame {
Switch item=PERSON1_WECKER_SA mappings=[ON="AN", OFF="AUS"]
Setpoint item=PERSON1_WECKER_SA_H minValue=0 maxValue=23 step=1
Setpoint item=PERSON1_WECKER_SA_M minValue=0 maxValue=55 step=5
Setpoint item=PERSON1_WECKER_SA_RUN minValue=10 maxValue=180 step=10
}
Frame {
Switch item=PERSON1_WECKER_SO mappings=[ON="AN", OFF="AUS"]
Setpoint item=PERSON1_WECKER_SO_H minValue=0 maxValue=23 step=1
Setpoint item=PERSON1_WECKER_SO_M minValue=0 maxValue=55 step=5
Setpoint item=PERSON1_WECKER_SO_RUN minValue=10 maxValue=180 step=10
}
}
Three things to add: First, this will work well on OH1.8(use Sitemap) and OH2 (use either Sitemap or HABPanel). Second,If you run several alarms, you might want to add a sanity check in PERSONx rule “Wecker PERSONx” if another timer is allready running and cancel it; i do this like so:
//cancel PERSON1 Timer if running...
if (timerPERSON1Wecker != null){
timerPERSON1Wecker.cancel()
timerPERSON1Wecker = null
}
Third&last, you should persist all items (gPERSON1Wecker* : strategy = everychange, restoreOnStartup) and initialise all days even if you don’t need them or you will get errors in your logs.
I hope you find this useful.
The result looks something like so:
Best regards,
-OLI
Edit: code shortened quite a bit by using group concepts.
Update: I have created Widgets(“Wecker” which can be configured per day and “WeckerSettings” for handling Presets) for HABPanel that can be used with these Item/Rule sets.
They look like this:
Clicking the Green Button toggles alarm for the day ON or OFF (turns Red when OFF)
The WeckerSetting-Widget will show and load the preset that is currently not active.
“Wecker” has these settings:

Wecker.widget.json (2.9 KB)