[SOLVED] ZWave schlage not triggering updates

  • Platform information:
    • Hardware: AMD A10, aeotec z stick gen 5
    • OS: Windows 10
    • Java Runtime Environment: zulu
    • openHAB version: 2.4
  • Issue of the topic: Schalge lock not triggering manual updates

Hi All
I am currently setting up 2 schlage (BE469) locks. I could include them securely with the Z Stick via Habmin. I can also control them via PaperUI and BasicUI without any issues.
When I manually operate the locks, there is no update at all. I have searched through the posts and found nothing that worked. There is nothing in the logs (even in the console)

Here is the settings for the lock in Habmin:

Here it is in BasicUI:

Commands from OH to locks:

23:22:03.861 [INFO ] [smarthome.event.ItemCommandEvent ] - Item ‘home_theater_node24_lock_door’ received command OFF
23:22:06.911 [INFO ] [smarthome.event.ItemStateChangedEvent] - home_theater_node24_lock_door changed from ON to OFF

I am not sure why the locks are not sending any events back to OH. The other zwave lights are all working fine.
Any clues or help would be appreciated.

Do you mean they are not sending updates after manual operation of the deadbolt or keypad? If so, this is normal, and you will need an Item linked to the alarm_raw Channel and a rule like this one, which also identifies which code was used…

Thanks Scott. I will look into this.

I got it working. The only thing that I could not solve is a Error:

[ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘Lock: Update lock states after Alarm Raw event’: cannot invoke method public abstract org.eclipse.smarthome.core.types.State org.eclipse.smarthome.core.persistence.HistoricItem.getState() on null

Here is my mapdb.persist

Strategies {
    default = everyChange
}

Items {
    * : strategy = everyChange, restoreOnStartup
}

For reference here is the lock.rules

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

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)
                    logInfo("Rules", "Lock: Alarm events: {} updated to ON (locked)",actionItem.name)
                }
                case "2", case "4" : {
                    actionItem.postUpdate(OFF)
                    logInfo("Rules", "Lock: Alarm events: {} updated to OFF (unlocked)",actionItem.name)
                }
                case "6" : {
                    val StringBuilder message = new StringBuilder(actionItem.name)
                    message.append(" was unlocked with")
                    switch (transform("JSONPATH", "$.code", inputItem.state.toString)) {
                    }
                    Thread::sleep(100)//wait for Presence state to update so alarm doesn't trigger
                    actionItem.postUpdate(OFF)
                    logInfo("Rules", "Lock: {}",message.toString)
                    //SMS_Notification.sendCommand(message.toString)
                }
                case "11" : {
                    logInfo("Rules", "Lock: Alarm events: {} is jammed, so setting lock to OFF (unlocked)",actionItem.label)
                    actionItem.postUpdate(OFF)
                    //SMS_Notification.sendCommand(actionItem.label + " is jammed")
                }
                case "16" : {
                    val String message = actionItem.label + " keypad is disabled due to too many failed codes"
                    logInfo("Rules", "Lock: Alarm events: {}",message)
                    //SMS_Notification.sendCommand(message)
                }
                default : {
                    val String message = "Unknown Event in alarmRawParser, " + inputItem.state.toString
                    logInfo("Rules", "Lock: Alarm events: {}",message)
                    //SMS_Notification.sendCommand(message)
                }
            }
            if (transform("JSONPATH", "$.event", inputItem.previousState(true).state.toString) == "11" && transform("JSONPATH", "$.event", inputItem.state.toString) != "11") {
                val String message = actionItem.label + " is no longer jammed"
                logInfo("Rules", "Lock: Alarm events: {}",message)
                //SMS_Notification.sendCommand(message)
            }
        }
        case "BURGLAR" : {
            val String message = "Intruder at " + actionItem.label
            logInfo("Rules", "Lock: Alarm events: {}",message)
            //SMS_Notification.sendCommand(message)
        }
        case "POWER_MANAGEMENT" : {
            val String message = "Power Management alarm for " + actionItem.label + ", " + inputItem.state.toString
            logDebug("Rules", "Lock: Alarm events: {}",message)
            //SMS_Notification.sendCommand(message)
        }
        default : {
            val String message = "Unknown Type in alarmRawParser, " + inputItem.state.toString
            logInfo("Rules", "Lock: Alarm events: {}",message)
            //SMS_Notification.sendCommand(message)
        }
    }
    true
]

rule "Lock: Update lock states after Alarm Raw event"
when
        Item Lock_EntranceFront_Alarm_Raw received update or
        Item Lock_MediaRoom_Alarm_Raw received update
then
        alarmRawParser.apply(triggeringItem as GenericItem)
end

The doorlock.items

Group:Switch:OR(OFF,ON) gLock "Locks [MAP(lock.map):%s]" <lock>

Switch Lock_EntranceFront "Front Entrance Door Lock [MAP(lock.map):%s]" <lock> (gLock) {channel="zwave:device:f2675c01:node20:lock_door"}
String Lock_EntranceFront_Alarm_Raw "Lock (Front Entrance): Alarm Raw [%s]" <shield> {channel="zwave:device:f2675c01:node20:alarm_raw"}

Switch Lock_MediaRoom "Media Room Door Lock [MAP(lock.map):%s]" <lock> (gLock) {channel="zwave:device:f2675c01:node24:lock_door"}
String Lock_MediaRoom_Alarm_Raw "Lock (Media Room): Alarm Raw [%s]" <shield> {channel="zwave:device:f2675c01:node24:alarm_raw"}

Thanks for all the help.

I didn’t spot anything in your version of the rule, but I suspect your lock may not have persistence data. Did you install the mapdb persistence service? You coud verify if there is data by restarting OH and checking the value of the alarm_raw Items.

Also, in my rule, I use the lock code to set a person’s presence to home as a fallback for our other presence detection stuff, and I used the sleep to wait for that to go through before unlocking the door to prevent sirens from going off. Unless you are doing something similar, you wouldn’t need the Thread::sleep(100).

Yes, I have mapdb setup. I can control the devices and also getting the updates when I manually use the locks. I see the updates in the console trace

21:07:50.312 [INFO ] [.eclipse.smarthome.model.script.Rules] - Lock: Alarm events: Lock_EntranceFront=[{"notification":"ACCESS_CONTROL__MANUAL_UNLOCK","level":"1","type":"ACCESS_CONTROL","event":"2","status":"255"}]
21:07:50.315 [INFO ] [.eclipse.smarthome.model.script.Rules] - Lock: Alarm events: Lock_EntranceFront updated to OFF (unlocked)
21:07:50.318 [ERROR] [untime.internal.engine.RuleEngineImpl] - Rule 'Lock: Update lock states after Alarm Raw event': cannot invoke method public abstract org.eclipse.smarthome.core.types.State org.eclipse.smarthome.core.persistence.HistoricItem.getState() on null
21:07:50.318 [INFO ] [eclipse.smarthome.model.script.Status] - Updated Lock_EntranceFront_LUD
21:07:55.320 [INFO ] [.eclipse.smarthome.model.script.Rules] - Lock: Alarm events: Lock_EntranceFront=[{"notification":"ACCESS_CONTROL__MANUAL_LOCK","level":"1","type":"ACCESS_CONTROL","event":"1","status":"255"}]
21:07:55.323 [INFO ] [.eclipse.smarthome.model.script.Rules] - Lock: Alarm events: Lock_EntranceFront updated to ON (locked)
21:07:55.325 [ERROR] [untime.internal.engine.RuleEngineImpl] - Rule 'Lock: Update lock states after Alarm Raw event': cannot invoke method public abstract org.eclipse.smarthome.core.types.State org.eclipse.smarthome.core.persistence.HistoricItem.getState() on null

I see the alarm_raw value in habamin

I will remove the sleep. Appreciate the help to get it working.

I don’t have an easy way to test this, and I haven’t looked in the code, but try changing this to

inputItem.previousState.state.toString

The original asks for a previousState that is different than the current, but when using MapDB it might be causing an error. If the errors stop, you’ll still need to test because this part of the rule may not work for you unless you setup another type of persistence.

Just found this too. Did you set a default persistence service?

Removing the “true” parameter in the previousState worked! I dont see the error being thrown any more.

Yeah, I saw the post you linked before I reached out here. I had added the default in the mapdb.persist.

1 Like

I just noticed something that could cause a problem. If you’re not going to use the switch/case here to identify the code slot used, then you should instead do something like this…

                case "6" : {
                    actionItem.postUpdate(OFF)
                    logInfo("Rules", "Lock: {} was unlocked with the code from slot number [{}]", actionItem.name, transform("JSONPATH", "$.code", inputItem.state.toString))

Or remove it entirely and do…

                case "2", case "4", case "6" : {
                    actionItem.postUpdate(OFF)
                    logInfo("Rules", "Lock: Alarm events: {} updated to OFF (unlocked)",actionItem.name)
                }

This is what I am going to do. We just have 1 code which the whole family uses.
I’ll test it out. Thanks.

One issue I had is that I couldn’t tell the difference between an update coming in from the lock or the persistence update. And since I have other rules/actions dependent on the lock being locked or unlocked, this created a problem. Perhaps there is a better solution, but what I did is not persist the raw item which solved the issue, yet I still wanted to be able to access the old event to do the jam check as in the original code. Therefore I created a hashmap at the top of the rule:

var Map<String, Number> messageOldEvents = newHashMap
var String lockSavedName

Then at the top of the ACCESS_CONTROL switch, I have this:

    // old method: val messageOldEvent = transform("JSONPATH","$.event",triggeringItem.previousState(true).state.toString)
    // should be null if not in hashmap, won't compare below
    var messageOldEvent = messageOldEvents.get(actionItem.name.toString)
    messageOldEvents.put(actionItem.name.toString, messageEvent)

And finally further below I can use messageOldEvent as desired:

    if (messageOldEvent == "11" && messageEvent != "11") {
        val String message = actionItem.label + " is no longer jammed"