Synchronize your alarm clock times with your lights with OpenHab in just 3 easy steps

Published by Oliver on

Are you having trouble waking up in the morning? Are you looking for a way synchronize your phone’s alarm clock with your lights? I found an easy way to this and it is quite helpful. Here is how I did it.

Why?

Most people nowadays use there phone to set an alarm time if they need to get up in the morning. I do the same thing. Sometimes you just seem to wake up at the wrong time though. I have been reading a lot about how light can impact your sleep and I know I have a fully controllable light setup. So one evening I drew the obvious conclusion: why not use that timer to automatically dimm up my lights some time before waking up to help with that?

What is needed?

Luckily this is not very hard to do if you have a similar setup to mine:

  • an OpenHab 2 setup (other software might have similar functionality, but this is what I am using)
  • an Android smartphone with an alarm software that uses the build-in alarm API and the official OpenHab App. There is an iOS version of the app but it seems to not support syncing the alarm times
  • Some dimm-able lights you can control via OpenHab

How to?

We only need a couple of steps to get this working.

First we need a couple of new items (in any *.items file) in our OpenHab config to save the alarm time as well as activation and deactivation of the feature.

/* Alarms */
Number AlarmClock "Smartphone Alarm" <time> // timestamp sent from the app (e.g. 123456789
DateTime AlarmClockTime "Next Alarm" <time> // time as an actual DateTime object (e.g. 16.04.2020 09:45:00)
Switch AlarmActivated <switch> // activates or deactivates the feature

Now we need to install the Android App from the Play Store (or any other store you prefer). In the App you need to go to the settings and scroll down to the settings about sending data to the server. There is one for sending the alarm time to the server. Click on it, activate the slider and set the item name to “AlarmClock“. That name should be the Number item defined in the items file above.

Settings for synchronising alarm times between your phone and openhab
Settings for the alarm sync in the OpenHab App (in my case the German version)

Now whenever you change the alarm time on your phone your “AlarmClock” item should also change accordingly. You can test this now by adding it to your dashboard if you feel like seeing this information.

Go to the *.sitemap file you want to use and add this. It also shows the next alarm time and allows you to deactivate the feature. Both will not work yet, we need one more step for this.

Frame label="Alarm" {
    Text item=AlarmClock // this is just for seeing your initial data, it can be removed later
    Text item=AlarmClockTime label="Next Alarm [%1$td.%1$tm.%1$ty %1$tH:%1$tM]"
    Switch item=AlarmActivated label="Alarm active"
}

In the last step we need a new rule to add the actual logic of this feature. It should do a couple of things starting with the conversion of the Number to an actual DateTime object. Then it should check the day of the week (I don’t want to wake up from the lights on the weekends for example even if I have an alarm set) and whether the feature is activated. Then finally it should set up a couple of timers which dim the lights up in steps 10 minutes before the actual alarm time. Here is the full code:

var DateTime alarmTime
var Timer timer1 = null
var Timer timer2 = null
var Timer timer3 = null
var Timer timer4 = null
var Timer timer5 = null
val validAlarmDays = newArrayList(1,2,3,4,5) // Monday 1, Sunday 7)

rule "Alarm Clock time"
when
    Item AlarmClock changed
then
    alarmTime = new DateTime((AlarmClock.state as Number).longValue) // conversion
    logDebug("Rule", "Alarm in millis is {}", (AlarmClock.state as Number).longValue)
    AlarmClockTime.postUpdate(alarmTime.toString)

    val Integer alarmDayOfWeek = alarmTime.getDayOfWeek()
    logDebug("Rule", "Next alarm is on day " + alarmDayOfWeek + " of the week, which is on a valid day: " + validAlarmDays.contains(alarmDayOfWeek))

    if (validAlarmDays.contains(alarmDayOfWeek)) {
        logDebug("Rule", "Starting dimm up timers at {}", alarmTime.minusMinutes(10))
        // start lights on dimmers
        timer1 = createTimer(alarmTime.minusMinutes(9)) [|
                if (AlarmActivated.state == ON) {
                    sendCommand(grDimmerWZ, 20)
                    logDebug("Rule", "Dimming alarm light to 20%")
                } else {
                    logDebug("Rule", "Not changing lights because the alarm is deactivated")
                }
            ]

        timer2 = createTimer(alarmTime.minusMinutes(8)) [|
                if (AlarmActivated.state == ON) {
                    sendCommand(grDimmerWZ, 40)
                    logDebug("Rule", "Dimming alarm light to 40%")
                } else {
                    logDebug("Rule", "Not changing lights because the alarm is deactivated")
                }
            ]

        timer3 = createTimer(alarmTime.minusMinutes(7)) [|
                if (AlarmActivated.state == ON) {
                    sendCommand(grDimmerWZ, 60)
                    logDebug("Rule", "Dimming alarm light to 60%")
                } else {
                    logDebug("Rule", "Not changing lights because the alarm is deactivated")
                }
            ]

        timer4 = createTimer(alarmTime.minusMinutes(6)) [|
                if (AlarmActivated.state == ON) {
                    sendCommand(grDimmerWZ, 80)
                    logDebug("Rule", "Dimming alarm light to 80%")
                } else {
                    logDebug("Rule", "Not changing lights because the alarm is deactivated")
                }
            ]

        timer5 = createTimer(alarmTime.minusMinutes(5)) [|
                if (AlarmActivated.state == ON) {
                    sendCommand(grDimmerWZ, 100)
                    logDebug("Rule", "Dimming alarm light to 100%")
                } else {
                    logDebug("Rule", "Not changing lights because the alarm is deactivated")
                }
            ]
    } 
end

Note that I have defined some log settings for my instance which always show “Rule” logs even in debug mode. They might not show up in your case.
Using timers for this is also very verbose in OpenHab. I used it because it seems quite clear this way but I might update the code to a cleaner version using this in the future.

Categories: OpenhabAutomation