Setting a Timer to run Custom Routine

Hey guys, I’m running OpenHAB 2.4 and trying to get some Rules setup. I found a rule that someone built to work with my Schlage locks, which works great for alerts. However, I’m now trying to add so that if a lock has been unlocked for 20 minutes, I’ll get a notification.

In order to leave it extensible to do more on various timeouts, my thought was I would have it start a timer on any door unlock, then I’d be able to perform various action there, including checking all of the other lock statuses to confirm it wasn’t locked between times, log the event, and notify me (broadcast on openhab cloud).

However, I seem to be unclear on how subfunctions/routines work here. I only have a basic knowledge of scripting, but enough to get started.

What I have so far follows:

import org.eclipse.xtext.xbase.lib.Functions

val checkLockState = [
    gLock.members.forEach[thislock|
            logInfo("Rules",thislock+"Lock Timer")
    ]
    unlockedTimer = null
    true
]

val Functions$Function1<GenericItem,Boolean> alarmRawParser = [
inputItem |
val actionItem = gLock.members.findFirst[ item | item.name.toString == inputItem.name.toString.replace("_Alarm_Raw","") ]
logInfo("Rules", "Lock: Alarm events: {}=[{}]",actionItem.name,inputItem.state.toString)
switch (transform("JSONPATH","$.type",inputItem.state.toString)) {
    case "ACCESS_CONTROL" : {
        switch (transform("JSONPATH", "$.event", inputItem.state.toString)) {
            case "1", case "3", case "5" : {
                actionItem.postUpdate(ON)
                    sendBroadcastNotification(actionItem.name + " has been LOCKED.")
                logInfo("Rules", "Lock: Alarm events: {} updated to ON (locked)",actionItem.name)
            }
            case "2", case "4" : {
                actionItem.postUpdate(OFF)
                    sendBroadcastNotification(actionItem.name + " has been UNLOCKED.")
                logInfo("Rules", "Lock: Alarm events: {} updated to OFF (unlocked)",actionItem.name)
                    var Timer unlockedTimer = createTimer(now.plusMinutes(1),[checkLockState(inputItem)])
            }

//TRUNCATED - MORE CASES GO HERE
true
]

rule “Lock: Update lock states after Alarm Raw event”
when
Item Lock_OtherFrontDoor_Alarm_Raw received update or
Item Lock_FrontDoor_Alarm_Raw received update or
Item Lock_SideDoor_Alarm_Raw received update or
Item Lock_FrontDoor changed or
Item Lock_SideDoor changed or
Item Lock_OtherFrontDoor changed
then
if (triggeringItem.name.toString.contains(“Alarm”)) {
alarmRawParser.apply(triggeringItem as GenericItem)
}
else {
sendBroadcastNotification(triggeringItem.name.toString+" set to "+triggeringItem.state.toString)
}
end

It doesn’t seem to be working though and I see the following when I save the rule:

2019-06-15 11:15:41.788 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model ‘lock.rules’, using it anyway:

There is no context to infer the closure’s argument types from. Consider typing the arguments or put the closures into a typed context.

There is no context to infer the closure’s argument types from. Consider typing the arguments or put the closures into a typed context.

The value of the local variable unlockedTimer is not used

This expression is not allowed in this context, since it doesn’t cause any side effects.

2019-06-15 11:15:41.789 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model ‘lock.rules’

Any help would be greatly appreciated.

So, in the absence of a response on this, I figured a better option was to integrate it all into the timer command. Perhaps someone can provide advice as to whether this is a good idea or not? Since all the alarm events send the post command, I figure the switches that represent the lock status should always be accurate. Therefore, this is all triggered on those item updates:

rule "Lock: Update lock states after Alarm Raw event"
when
        Item Lock_OtherFrontDoor_Alarm_Raw received update or
                Item Lock_FrontDoor_Alarm_Raw received update or
                Item Lock_SideDoor_Alarm_Raw received update or
                Item Lock_FrontDoor changed or
                Item Lock_SideDoor changed or
                Item Lock_OtherFrontDoor changed
then

        if (triggeringItem.name.toString.contains("Alarm")) {
                alarmRawParser.apply(triggeringItem as GenericItem)
        }
        else {
                var String newLockState = "UNKNOWN"
                logInfo("Rules", triggeringItem.name.toString + " changed to " + triggeringItem.state.toString)
                if (triggeringItem.state == ON) {
                        newLockState = "LOCKED"
                }
                else if (triggeringItem.state == OFF) {
                        newLockState = "UNLOCKED"
                        unlockedTimer = createTimer(now.plusMinutes(20),[|
                                var unlockedDoors = 0
                                val StringBuilder doorStates = new StringBuilder("")
                                gLock.members.forEach[ lockItem |
                                        //logInfo("Rules","Checking "+lockItem.name+" - "+lockItem.state.toString)
                                        if(lockItem.state == OFF) {
                                                unlockedDoors = unlockedDoors + 1
                                        }
                                        doorStates.append(lockItem.name+" is "+lockItem.state.toString+".\n")
                                ]
                                if (unlockedDoors>0) {
                                        sendBroadcastNotification("Doors are still unlocked!")
                                        sendMail("[EMAIL_ADDRESS_HERE]","OpenHAB Alert","Doors are still unlocked!\n\n"+doorStates)
                                }
                        ])
                }
                else {
                        newLockState = "UNKNOWN"
                }
                //logInfo("Rules",newLockState)
                sendBroadcastNotification(triggeringItem.name+" set to "+newLockState)
                sendMail("[EMAIL_ADDRESS_HERE]","OpenHAB Alert",triggeringItem.name+" has been "+newLockState)
        }
                       newLockState = "LOCKED"
                }
                else if (triggeringItem.state == OFF) {
                        newLockState = "UNLOCKED"
                        unlockedTimer = createTimer(now.plusMinutes(20),[|
                                var unlockedDoors = 0
                                val StringBuilder doorStates = new StringBuilder("")
                                gLock.members.forEach[ lockItem |
                                        //logInfo("Rules","Checking "+lockItem.name+" - "+lockItem.state.toString)
                                        if(lockItem.state == OFF) {
                                                unlockedDoors = unlockedDoors + 1
                                        }
                                        doorStates.append(lockItem.name+" is "+lockItem.state.toString+".\n")
                                ]
                                if (unlockedDoors>0) {
                                        sendBroadcastNotification("Doors are still unlocked!")
                                        sendMail("[EMAIL_ADDRESS_HERE]","OpenHAB Alert","Doors are still unlocked!\n\n"+doorStates)
                                }
                        ])
                }
                else {
                        newLockState = "UNKNOWN"
                }
                //logInfo("Rules",newLockState)
                sendBroadcastNotification(triggeringItem.name+" set to "+newLockState)
                sendMail("[EMAIL_ADDRESS_HERE]","OpenHAB Alert",triggeringItem.name+" has been "+newLockState)
        }
end