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.

1 Like

@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.