Amazon Echo: Rules DSL - Cannot invoke "org.eclipse.xtext.common.types.JvmType.eIsProxy()" because "type" is null in AmazonEcho

Hello all,

I’m trying to create a rule that triggers when an Alexa alarm is changed. I’m running Openhab 4.0.1 on Kubernetes, using the image on Docker Hub.

Here’s my rule (very much simplified for debug purposes:

rule "Master Bedroom Alarm"
when
    Item Master_Bedroom_Echo_Show_Next_Alarm changed
then
    logInfo("AmazonEcho.rules", "Alexa alarm changed to ", Master_Bedroom_Echo_Show_Next_Alarm.state.toString)
end

I get this error in the logs:

15:30:58.484 [INFO ] [ab.core.model.script.AmazonEcho.rules] - Alexa alarm changed to
15:30:58.485 [ERROR] [.internal.handler.ScriptActionHandler] - Script execution of rule with UID 'AmazonEcho-1' failed: An error occurred during the script execution: Cannot invoke "org.eclipse.xtext.common.types.JvmType.eIsProxy()" because "type" is null in AmazonEcho

I can’t work out if I’m handling the DateTime incorrectly, or if there’s another problem. My item seems OK:

openhab> openhab:items list Master_Bedroom_Echo_Show_Next_Alarm
Master_Bedroom_Echo_Show_Next_Alarm (Type=DateTimeItem, State=UNDEF, Label=Next Alarm, Category=, Tags=[Point], Groups=[Master_Bedroom_Echo_Show])
openhab>
openhab> openhab:items list Master_Bedroom_Echo_Show_Next_Alarm
Master_Bedroom_Echo_Show_Next_Alarm (Type=DateTimeItem, State=2023-08-06T06:00:00.000+1000, Label=Next Alarm, Category=, Tags=[Point], Groups=[Master_Bedroom_Echo_Show])
openhab> openhab:status Master_Bedroom_Echo_Show_Next_Alarm
2023-08-06T06:00:00.000+1000

Any help is greatly appreciated.

Cheers, Jon

I figured this out. My log statement was incorrect, and my DateTime was too. This works:

        logInfo("AmazonEcho.rules", "Master Bedroom alarm set to {}", Master_Bedroom_Echo_Show_Next_Alarm.state.toString)
        val AlarmTime = (Master_Bedroom_Echo_Show_Next_Alarm.state as DateTimeType).getZonedDateTime()

So all up, here’s my rule that is triggered when I set/cancel an Alexa alarm. It sets a timer to turn the bathroom heating on 30 minutes before the alarm goes off. When that timer expires, the heating is turned on, and another timer is created to turn it off an hour later.

// #-----------------------------------
// # Rules to handle Amazon Echo events
// #-----------------------------------

var Timer bathroomHeatDelayTimer = null
var Timer bathroomHeatOnTimer = null

rule "Master Bedroom Alarm"
// Set a timer to start the bathroom heaters half an hour before 
// my alarm goes off.
when
    Item Master_Bedroom_Echo_Show_Next_Alarm changed
then
    // If there's already a timer running, cancel it (handles alarm change/cancel.)
    if (bathroomHeatDelayTimer !== null) {
        logInfo("AmazonEcho.rules", "Existing bathroom heat delay timer cancelled")
        bathroomHeatDelayTimer.cancel
        bathroomHeatDelayTimer = null
    }

    if (Master_Bedroom_Echo_Show_Next_Alarm.state.toString == "UNDEF") {
        // Alarm has been cancelled
        logInfo("AmazonEcho.rules", "Alexa alarm cancelled")
    }
    else {
        // Alarm has been set
        logInfo("AmazonEcho.rules", "Master Bedroom alarm set to {}", Master_Bedroom_Echo_Show_Next_Alarm.state.toString)
        val AlarmTime = (Master_Bedroom_Echo_Show_Next_Alarm.state as DateTimeType).getZonedDateTime()
        
        logInfo("AmazonEcho.rules", "Bathroom heat timer set to {}", AlarmTime.minusMinutes(30))
        bathroomHeatDelayTimer = createTimer(AlarmTime.minusMinutes(30), [ |
            if (OccupancyMode.state==ON) {
                logInfo("AmazonEcho.rules", "Bathroom heat delay timer expired - Bathroom floor/towel rail on")

                // Switch heat on
                UpstairsBathroomFloorHeat_LightChannel.sendCommand(ON)
                UpstairsBathroomTowelRail_LightChannel.sendCommand(ON)

                // Also set a time to swtch heat off after 60 minutes, regardless of occupancy
                bathroomHeatOnTimer = createTimer(now.plusMinutes(60), [ |
                    logInfo("AmazonEcho.rules", "Bathroom heat timer expired - Bathroom floor/towel rail off")
                    UpstairsBathroomFloorHeat_LightChannel.sendCommand(OFF)
                    UpstairsBathroomTowelRail_LightChannel.sendCommand(OFF)
                    bathroomHeatOnTimer.cancel
                    bathroomHeatOnTimer = null
                ])
            }
            bathroomHeatDelayTimer.cancel
            bathroomHeatDelayTimer = null
        ])
    }
end