AlarmClock doesn´t fire

hi, I´m trying to get AlarmDroid Alarms into OH as described here: https://www.openhab.org/docs/apps/android.html#alarm-clock
Unfortunately my Alarm never fires, when the Alarm on my phone goes on.

the rule:

var Timer timerAlarm = null

rule "Alarm Clock"
when
    Item AlarmClock changed
then
        Thread::sleep(1000) //for test purpose
        if (AlarmClock.state as Number == 0) {
        if (timerAlarm !== null) {
            timerAlarm.cancel
            timerAlarm = null
        }
        logInfo("alarm", "All alarms are cancelled")
    } else {
        var epoch = new DateTime((AlarmClock.state as Number).longValue)
        logInfo("alarm", "Scheduling alarm for " +  epoch.toString)

        if (timerAlarm !== null) {
            logInfo("alarm", "Reschedule alarm")
            timerAlarm.reschedule(epoch)
        } else {
            logInfo("alarm", "New Alarm")
            timerAlarm = createTimer(epoch, [ |
                    // Turn on stuff, e.g. radio or light
                    VSwitch2.sendCommand(ON)
                    logInfo("alarm", "alarm is expired")
                ]
            )
        }
    }
end

When I set the Alarm I receive:
2019-12-08 21:31:06.233 [ome.event.ItemCommandEvent] - Item ‘AlarmClock’ received command 1575837120000

2019-12-08 21:31:06.236 [vent.ItemStateChangedEvent] - AlarmClock changed from 0 to 1575837120000

==> /var/log/openhab2/openhab.log <==

2019-12-08 21:31:07.237 [INFO ] [eclipse.smarthome.model.script.alarm] - Scheduling alarm for 2019-12-08T21:32:00.000+01:00

2019-12-08 21:31:07.238 [INFO ] [eclipse.smarthome.model.script.alarm] - New Alarm

==> /var/log/openhab2/events.log <==

 2019-12-08 21:31:25.448 [vent.ItemStateChangedEvent] - CurrentTime changed from 2019-12-08T21:30:25.322+0100 to 2019-12-08T21:31:25.325+0100

  2019-12-08 21:31:54.823 [ome.event.ItemCommandEvent] - Item 'AlarmClock' received command 0

2019-12-08 21:31:54.827 [vent.ItemStateChangedEvent] - AlarmClock changed from 1575837120000 to 0

==> /var/log/openhab2/openhab.log <==

2019-12-08 21:31:55.828 [INFO ] [eclipse.smarthome.model.script.alarm] - All alarms are cancelled

same behavior for AlarmDroid and Samsung Alarm.
the original rule had a “k” inside the lambda part:

timerAlarm = createTimer(epoch,
                [ k |
                    // Turn on stuff, e.g. radio or light
                    Light.sendCommand(ON)
                    logInfo("alarm", "alarm is expired")
                ]

but that “k” throws a “Type mismatch: cannot convert from (Object)=>void to Procedure0” in VSC, anyhow it doesn´t work with or without k…
whats wrong?

The latest version supports using a DateTime item for receiving the alarm clock. When updating the docs, I’ll let you know and you can try the updated rule: https://github.com/openhab/openhab-android/issues/1618

1 Like

@mueller-ma Do you already have a draft for the new rule? Otherwise this is where I ended:

Example item definition:

DateTime AlarmClock

Example rule:

var Timer timerAlarm = null

rule "Alarm Clock"
when
    Item AlarmClock changed
then
    val epoch = (newState as DateTimeType).toLocaleZone.zonedDateTime.toInstant.toEpochMilli
    if( epoch <= 0 ) {
        if( timerAlarm !== null ) {
            timerAlarm.cancel
            timerAlarm = null
        }
        logInfo("alarm", "Alarm canceled")
    } else {
        logInfo("alarm", "Scheduling alarm for {} ({})", (newState as DateTimeType).toLocaleZone, epoch)
        if( timerAlarm !== null ) {
            logInfo("alarm", "Reschedule alarm")
            timerAlarm.reschedule(new DateTime(epoch))
        } else {
            logInfo("alarm", "New alarm")
            timerAlarm = createTimer(new DateTime(epoch), [ |

                // TODO your stuff

                logInfo("alarm", "alarm", "Alarm expired")
                timerAlarm = null
            ])
        }
    }
end

No, I haven’t had a draft yet. Thanks for your example, I’ll have a closer look at it.

Android sends shortly (~0,7s) before the actual alarm time the command 0
2020-02-14 19:39:59.269 [ome.event.ItemCommandEvent] - Item 'AlarmClock' received command 0
which will delete reset the timerAlarm.

A
Thread::sleep(1000)
before
timerAlarm.cancel
will prevent setting the timerAlarm to null, before it can be active. It’s a quick and dirty bug fix and I’m sure there is a more elegant solution.

2 Likes

@cweitkamp Did you update your rule already to handle AlarmClock being UNDEF? The 2.12.0-release versions sends UNDEF if no alarm is active.

No, I did not. Currently I cannot see a huge benefit when changing something compared to what I have. my rule is working nicely even with the new App version.

If you cancel an alarm in the app, the rule throws a NPE and won’t cancel the time, I guess.

I see. Thinking about it I expect that too. Can you verify that it is working?

I am on 2.12.1 - 23th of March and a leading logInfo() in my rule always shows: “Changed to 1970-01-01T00:00:00.000+0000’”.

I think I found a case where 0 is sent instead of UNDEF. Which Android version does your smart phone have?

Android 10.

I am at the exact same spot and played around with the rule all morning.

I copy/pasted the rule from the documentation, deleted the “k” in the createtimer section and it worked right away except for the part when canceling a timer.

In that case I would get [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘Alarm Clock’: Could not cast UNDEF to java.lang.Number;

After reading this thread I found out that only some versions of the app create that error!
Phone1: Version 2.12.1 sends the correct value and the rule works.
Phone2: Version 2.12.11 beta sends the UNDEF value

Fortunately I have to use Phone 1 for this application but it would be great to have the bug fixed or find a simple workaround.

I’ll open a PR to fix this in the next few days and then we can have a look at the rule again.

Perfect. Thanks. Keep me posted.

I just uploaded 2.12.14-beta which contains the fix.

Your fix is working :wink:. Got the Android App update today. And guess what … my rule failed. Here is a new draft of my modified rule:

DSL

var Timer timerAlarm = null

rule "Alarm Clock"
when
    Item AlarmClock 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(new DateTime(epoch))
        } else {
            logInfo("alarm", "New alarm")
            timerAlarm = createTimer(new DateTime(epoch), [ |

                // TODO your stuff

                logInfo("alarm", "alarm", "Alarm expired")
                timerAlarm = null
            ])
        }
    } else {
        if( timerAlarm !== null ) {
            timerAlarm.cancel
            timerAlarm = null
        }
        logInfo("alarm", "Alarm canceled")
    }
end

FTR: This is one of my last DSL rules. I am switching to JSR223 Python. Let me know if you like to see the migrated rule too.

AFAIK the docs are currently using DSL rules, so it should be fine.

Im bumping this one. Trying to get this code to work on my newly setup of Openhab 3 but I can’t get it to work.

This is what I get:

2020-12-29 01:05:40.537 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'EriksAlarmClock' changed from 2020-12-29T09:45:00.000+0000 to UNDEF

2020-12-29 01:05:45.347 [INFO ] [org.openhab.core.model.script.alarm ] - Scheduling alarm for 2020-12-29T10:45:00.000+0100 (1609235100000)

2020-12-29 01:05:45.352 [INFO ] [org.openhab.core.model.script.alarm ] - New alarm

2020-12-29 01:05:45.356 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'static-1' failed: An error occurred during the script execution: null in static

I don’t understand? Is this supported in Openhab 3: createTimer(new DateTime(epoch)
I’ve read about different time conversion but I can’t figure out what I would have to do to get it to work.

No, it is not supported anymore. DateTime was part of Joda library which has been removed and everything has been aligned to use ZonedDateTime. The respective rule in OH3 should be slightly easier than before because you can just pass value of the Item’s state to the createTimer(). I updated it:

DSL (openHAB 3 version)

var Timer timerAlarm = null

rule "Alarm Clock"
when
    Item AlarmClock changed
then
    if( newState instanceof DateTimeType ) {
        logInfo("alarm", "Scheduling alarm for {} ({})", newState.toLocaleZone, newState)
        if( timerAlarm !== null ) {
            logInfo("alarm", "Reschedule alarm")
            timerAlarm.reschedule(newState.toLocaleZone.zonedDateTime)
        } else {
            logInfo("alarm", "New alarm")
            timerAlarm = createTimer(newState.toLocaleZone.zonedDateTime, [ |

                // TODO your stuff

                logInfo("alarm", "alarm", "Alarm expired")
                timerAlarm = null
            ])
        }
    } else {
        if( timerAlarm !== null ) {
            timerAlarm.cancel
            timerAlarm = null
        }
        logInfo("alarm", "Alarm canceled")
    }
end

Okay I understand. That looks easier than the code I had before. :slight_smile:
I tried it but I still get an error: :frowning:

Script execution of rule with UID 'static-1' failed: An error occurred during the script execution: Could not invoke method: org.openhab.core.model.script.actions.ScriptExecution.createTimer(java.time.ZonedDateTime,org.eclipse.xtext.xbase.lib.Procedures$Procedure0) on instance: null in static