Schlage BE469ZP - add a channel for the “Mechanical Transitions Count” and “Electronic Transitions Count”

Would it be possible to add a channel for the “Mechanical Transitions Count” and “Electronic Transitions Count” for the Schlage BE469ZP door lock? @chris

Here’s why I ask. I’m using these door locks, and it seems that they don’t truly report their state if operated via ZWave. Case in point, if I switch the item to lock the lock, and ZWave goes goofy and it doesn’t actually lock, my item still says it’s locked and thinks everything is groovy but it’s really not. I’ve applied the Alarm_Raw parsing rule that 5iver has a post detailing, but Alarm_Raw doesn’t update if the lock is operated by item. This creates a problem if one wants to use the lock’s actual position to verify the door actually locked or perform announcements via Alexa, for example. I could delay the Alexa announcement easily to “fake it”, but verifying the actual state change isn’t possible as far as i can tell. This may just be a limitation of the device, but was wondering if I could access the above mentioned parameters to check for a change during a given timeframe to verify the lock actually moved. If it didn’t move, I’d announce via Alexa or some other “attention getter”.

In this post, @5iver mentions that “Schlage finally realized… lock state!”. I either misundertand the definition of “report state”, or I’m missing something else that seems like it should be obvious.

Thanks in advance for your help!

1 Like

What version of OH and or which version of the zwave binding? When you send a command to the lock, does it ever not lock or unlock?

What do you have the command polling period set to on your locks? Command polling will request the device state a certain amount of time after a command is sent. The default is 1.5 seconds. The state of the locks won’t update until the bolt is turned, so it’s possible that the command polling is occuring before the lock has actually change states.

How many devices do you have in the mesh and how many neighbors do the locks have? Security is slow, and if the mesh is weak, you could be missing events. Or there could be retires that could delay them up to 15s.

If you send the command REFRESH to the lock, the binding will request the current state from the lock, but you shouldn’t need this. You also shouldn’t need to use alarm_raw to get the state of these locks when they are manually locked/unlocked.

Post your rule with the announcement. If you trigger on a state change, then you could start a timer that waits 15s, checks the lock state, and then sends the announcement.

In this post, @samiam reported that his BE469ZP was reporting state after manual control without needing the alarm_raw rule. The alarm_raw Channel is also useful for reading codes, knowing if the lock is jammed, etc., but these locks should not need it to learn the state of the lock.

I’m running OH 2.5.0 Build #1764 with ZWave binding version 2.5.0.201911290347. I had not observed that behavior since I’ve gotten things to a stable state, until just now I was locking/unlocking to check times to lock/unlock. If I click Lock, let the door lock, then click Unlock right after it locks, the lock doesn’t move. I know the item switched because Alexa announced the state change, which is triggered by a rule based on the item changing. Until tonight doing some testing to answer this question, typical time from item clicked to lock actuation was always between 2-3 seconds(counting 1 Mississippi, 2 Mississippi, very technical timing method :slight_smile:).

1500 milliseconds. “Timeout” is set to 0. I haven’t changed any of the parameters from default other than user codes.

I have 18 devices. Here’s a screenshot of the ZWave network viewer in Habmin. Nodes 2 and 21 are the locks. I have no idea if this looks good or bad, so any guidance on looking at this would be appreciated. I have wondered if battery devices having all those “connections” was good or not. All the nodes are powered switches, except the 2 locks. I have one multisensor but it’s currently plugged in and not on battery.

No idea how to send REFRESH, or that it even existed. Please tell me more about this. :slight_smile:

Switch MF_FrontDoorLock      "Front Door Deadbolt [MAP(lock.map):%s]" <lock>    (GSW_Deadbolts, gLock, mapdbPersist) [ "Switchable" ]   {channel="zwave:device:0c27d2da:node21:lock_door"}
String MF_FrontDoorLock_Alarm_Raw "Front Door Lock: Alarm Raw [%s]"   <shield>  (GSW_Deadbolts, gLockRaw, mapdbPersist) {channel="zwave:device:0c27d2da:node21:alarm_raw"}
Number MF_FrontDoorLock_BatLvl  "Front Door Lock Battery Level [%d %%]"<battery>(batterystatus, rrdPersist)             {channel="zwave:device:0c27d2da:node21:battery-level"}
Switch MF_BackDoorLock       "Back Door Deadbolt [MAP(lock.map):%s]"  <lock>    (GSW_Deadbolts, gLock, mapdbPersist) [ "Switchable" ]   {channel="zwave:device:0c27d2da:node2:lock_door"}     
String MF_BackDoorLock_Alarm_Raw "Back Door Lock: Alarm Raw [%s]"     <shield>  (GSW_Deadbolts, gLockRaw, mapdbPersist) {channel="zwave:device:0c27d2da:node2:alarm_raw"}
Number MF_BackDoorLock_BatLvl   "Back Door Lock Battery Level [%d %%]"<battery> (batterystatus, rrdPersist)             {channel="zwave:device:0c27d2da:node2:battery-level"}
Group:Switch:OR(OFF,ON) gLock    "Locks [MAP(lock.map):%s]"           <lock>
Group                   gLockRaw "Locks (raw) [%s]"                   <lock>
var Timer DoorAnnounce_timer1 = null
var Timer DoorAnnounce_timer2 = null


rule "Announce front door unlocked"
when
    Item MF_FrontDoorLock changed
then
    if (MF_FrontDoorLock.state == OFF && EnableAlexaAnnouncements.state == ON && AlexaSpeaking != ON){
        DoorAnnounce_timer1 = createTimer(now.plusSeconds(5)) [|
        AlexaSpeaking.sendCommand(ON)
        Echo_Kitchen_TTS_Volume.sendCommand(35)
        Echo_Kitchen_TTS.sendCommand('Front Door unlocked')
        Echo_MBR_TTS_Volume.sendCommand(25)
        Echo_MBR_TTS.sendCommand('Front Door unlocked')
        ]
    }
    else if (MF_FrontDoorLock.state == ON && EnableAlexaAnnouncements.state == ON && AlexaSpeaking != ON){
        DoorAnnounce_timer1 = createTimer(now.plusSeconds(5)) [|
        AlexaSpeaking.sendCommand(ON)
        Echo_Kitchen_TTS_Volume.sendCommand(35)
        Echo_Kitchen_TTS.sendCommand('Front Door locked')
        Echo_MBR_TTS_Volume.sendCommand(25)
        Echo_MBR_TTS.sendCommand('Front Door locked')
        ]
    }
    DoorAnnounce_timer1 = null
end
rule "Lock: Update lock states after alarm_raw event"
when
    Member of gLockRaw received update
then
    val actionItem = ScriptServiceUtil.getItemRegistry.getItem(triggeringItem.name.toString.replace("_Alarm_Raw",""))
    logInfo("Rules", "Lock: Alarm events: {}=[{}]",actionItem.name,triggeringItem.state.toString)
    //logInfo("Rules", "actionItem.name")
    //logInfo("Rules", actionItem.name)
    //logInfo("Rules", "triggeringItem.state.toString")
    //logInfo("Rules", triggeringItem.state.toString)
    //logInfo("Rules", StringBuilder.name, StringBuilder.state.toString)
    //logInfo("Rules", message)
    val StringBuilder message = new StringBuilder(actionItem.name)
    switch (transform("JSONPATH","$.type",triggeringItem.state.toString)) {
        case "ACCESS_CONTROL" : {
            switch (transform("JSONPATH", "$.event", triggeringItem.state.toString)) {
                case "1", case "3", case "5" : {
                    //logInfo("Rule Info", "Got to case 1")
                    actionItem.postUpdate(ON)
                    message.append(" updated to ON (locked)")
                    MF_FrontDoorLockState.sendCommand("LOCKED")
                }
                case "2", case "4" : {
                    //logInfo("Rule Info", "Got to case 2")
                    actionItem.postUpdate(OFF)
                    message.append(" updated to OFF (unlocked)")
                    MF_FrontDoorLockState.sendCommand("UNLOCKED")
                }
                case "6" : {
                    //logInfo("Rule Info", "Got to case 6")
                    actionItem.postUpdate(OFF)
                    message.append(" was unlocked with")
                    switch (transform("JSONPATH", "$.code", triggeringItem.state.toString)) {
                        case "1" : {
                            message.append(" Zeke's code")
                            sendNotification("*********@gmail.com", message.toString)
                        }
                        case "2" : {
                            message.append(" Jenny's code")
                            sendNotification("********@gmail.com", message.toString)
                        }
                        case "3" : {
                            message.append(" Haley's code")
                            sendNotification("*********@gmail.com", message.toString)
                        }
                        case "4" : {
                            message.append(" Katie's code")
                            sendNotification("*******@gmail.com", message.toString)
                        }
                    }
                }
                case "11" : {
                    //logInfo("Rule Info", "Got to case 11")
                    actionItem.postUpdate(OFF)// jammed could mean unlocked, so I do this for safety... you may want to send an alert here too
                    message.append(" is jammed, so setting lock to OFF (unlocked)")
                    sendNotification("*********@gmail.com", message.toString)
                }
                case "16" : {
                    //logInfo("Rule Info", "Got to case 16")
                    message.append(" keypad is disabled due to too many failed codes")
                    sendNotification("*****@gmail.com", message.toString)
                }
                default : {
                    //logInfo("Rule Info", "Got to case default")
                    message.append(" unknown door lock Event, ").append(triggeringItem.state.toString)
                    sendNotification("*****@gmail.com", message.toString)
                }
            }
            // if (transform("JSONPATH", "$.event", triggeringItem.previousState.state.toString) == "11" && transform("JSONPATH", "$.event", triggeringItem.state.toString) != "11") {
            //     message.append(" and is no longer jammed")
            // }
        }
        case "BURGLAR" : {
            //gSiren.sendCommand(ON)
            message.append(" has detected an intruder")
            sendNotification("*****@gmail.com", message.toString)
        }
        case "POWER_MANAGEMENT" : {
            message.append(" received a Power Management alarm, ").append(triggeringItem.state.toString)
            sendNotification("*****@gmail.com", message.toString)
        }
        default : {
            message.append(" received and unknown Type in alarmRawParser, ").append(triggeringItem.state.toString)
            sendNotification("*****@gmail.com", message.toString)
        }
    }
    //logInfo("Rules", "Got to last step")
    logInfo("Rules", "Lock: Alarm events: {}", message.toString)
    
end

I think after seeing a few things tonight with my locks misbehaving, there’s definitely more i have to learn about how these work. In my mind, a device can’t “report state” if it does so via changing the state of the “commanded” item to the state i changed it to. I tested again tonight to be sure i wasn’t confused, and if i comment out my Alarm_Raw rule, the state of my item MF_FrontDoorLock does change when the lock is manually actuated or actuated by pin code at the lock. At one point it was not, or so i thought, and I’ve been assuming since then that the Alarm_Raw rule was updating it. That being said, I’ll still use it for notifications of who’s code unlocked, etc.

This exercise also helped me see, i think, that essentially the behavior of the lock if it didn’t actually move would be: Item switched to Lock, lock doesn’t move for whatever reason, Item updated back to Unlocked by the door lock “reporting state”, aka switching the command item back to the opposite indication “status”. :slight_smile: I can work with that and create rules to check xx seconds after command for a failed action.

I also think from this exercise i may be seeing that my ZWave network isn’t healthy for some reason? Misconfigured somehow?

Check out the autoupdate = true/false on the Item. See doc here.

Hmmmm, ok I went and read that. Now I’m really intrigued. So is that telling me if I execute a sendCommand(ON), aka Lock, on my item MF_FrontDoorLock via a rule or by pressing it’s “button” in BasicUI that the state of MF_FrontDoorLock won’t actually change to ON, aka Locked, until the channel it’s linked to reports back the change? Or until some other “source”, such as the Alarm_Raw script perhaps, posts and update to the item?

I believe that what you say is correct if you set the autoupdate to false. I haven’t personally tried this on the lock, though.

@jswim788 Well, I just set autoupdate to false and it does work like you expected! That’s awesome! Now, I’m thinking I still have an issue with ZWave maybe, as a few times when locking/unlocking my back door the update never occurred. The button in BasicUI will say Lock but the text "indicator still says Unlocked and remains that way. I suppose I could’ve maybe not waited long enough, but at least once I waited 40-50 seconds and it didn’t change. Regardless, it it’s more than 1-2 then it’s entirely too long.

My back door lock is a little further from the controller, but only by maybe 15 feet. I doubt that’s the issue, but at this point… :slight_smile:

I suggest disabling this, which is what I have done for all of my devices, since they all report on their own. Command polling is really just for devices that do not report their own state.

This looks good… no dead nodes and the locks have plenty of routing neighbors. Just realize, this is not displaying routes… just neighbors (the devices can see each other).

Search the forum…

item_name.sendCommand("REFRESH")

Then comment out the parts that change the state of the locks.

In what way? The only way to tell is by putting the zwave binding in debug and looking at the logs.

Done. And I’ll add this to my list of “required reading” to search for more information about this setting.

Another “required reading” item… :slight_smile:

I actually already commented out those lines last night. For the benefit of any that might read this later, here’s a copy of my Alarm_Raw rule as left at the end of this

rule "Lock: Update lock states after alarm_raw event"
when
    Member of gLockRaw received update
then
    val actionItem = ScriptServiceUtil.getItemRegistry.getItem(triggeringItem.name.toString.replace("_Alarm_Raw",""))
    logInfo("Rules", "Lock: Alarm events: {}=[{}]",actionItem.name,triggeringItem.state.toString)
    //logInfo("Rules", "actionItem.name")
    //logInfo("Rules", actionItem.name)
    //logInfo("Rules", "triggeringItem.state.toString")
    //logInfo("Rules", triggeringItem.state.toString)
    //logInfo("Rules", StringBuilder.name, StringBuilder.state.toString)
    //logInfo("Rules", message)
    val StringBuilder message = new StringBuilder(actionItem.name)
    switch (transform("JSONPATH","$.type",triggeringItem.state.toString)) {
        case "ACCESS_CONTROL" : {
            switch (transform("JSONPATH", "$.event", triggeringItem.state.toString)) {
                case "1", case "3", case "5" : {
                    //logInfo("Rule Info", "Got to case 1")
                    //actionItem.postUpdate(ON)
                    message.append(" updated to ON (locked)")
                    //MF_FrontDoorLockState.sendCommand("LOCKED")
                }
                case "2", case "4" : {
                    //logInfo("Rule Info", "Got to case 2")
                    //actionItem.postUpdate(OFF)
                    message.append(" updated to OFF (unlocked)")
                    //MF_FrontDoorLockState.sendCommand("UNLOCKED")
                }
                case "6" : {
                    //logInfo("Rule Info", "Got to case 6")
                    //actionItem.postUpdate(OFF)
                    message.append(" was unlocked with")
                    switch (transform("JSONPATH", "$.code", triggeringItem.state.toString)) {
                        case "1" : {
                            message.append(" Zeke's code")
                            sendNotification("*********@gmail.com", message.toString)
                        }
                        case "2" : {
                            message.append(" Jenny's code")
                            sendNotification("zeke.board@gmail.com", message.toString)
                        }
                        case "3" : {
                            message.append(" Haley's code")
                            sendNotification("*********@gmail.com", message.toString)
                        }
                        case "4" : {
                            message.append(" Katie's code")
                            sendNotification("*********@gmail.com", message.toString)
                        }
                    }
                }
                case "11" : {
                    //logInfo("Rule Info", "Got to case 11")
                    //actionItem.postUpdate(OFF)// jammed could mean unlocked, so I do this for safety... you may want to send an alert here too
                    message.append(" is jammed, so setting lock to OFF (unlocked)")
                    sendNotification("*********@gmail.com", message.toString)
                }
                case "16" : {
                    //logInfo("Rule Info", "Got to case 16")
                    message.append(" keypad is disabled due to too many failed codes")
                    sendNotification("*********@gmail.com", message.toString)
                }
                default : {
                    //logInfo("Rule Info", "Got to case default")
                    message.append(" unknown door lock Event, ").append(triggeringItem.state.toString)
                    sendNotification("*********@gmail.com", message.toString)
                }
            }
            // if (transform("JSONPATH", "$.event", triggeringItem.previousState.state.toString) == "11" && transform("JSONPATH", "$.event", triggeringItem.state.toString) != "11") {
            //     message.append(" and is no longer jammed")
            // }
        }
        case "BURGLAR" : {
            //gSiren.sendCommand(ON)
            message.append(" has detected an intruder")
            sendNotification("*********@gmail.com", message.toString)
        }
        case "POWER_MANAGEMENT" : {
            message.append(" received a Power Management alarm, ").append(triggeringItem.state.toString)
            sendNotification("*********@gmail.com", message.toString)
        }
        default : {
            message.append(" received and unknown Type in alarmRawParser, ").append(triggeringItem.state.toString)
            sendNotification("*********@gmail.com", message.toString)
        }
    }
    //logInfo("Rules", "Got to last step")
    logInfo("Rules", "Lock: Alarm events: {}", message.toString)
    
end

I was thinking that i shouldn’t see the delays i was seeing from time to time, as well as sometimes the lock not reporting back it’s state after a command/actuation. I only saw one of the locks not report back it’s state intermittently(node 2) so this lead me to believe maybe it was a ZWave issue. I’ll do some reading on ZWave before i ask too many more questions about that though. I did enable DEBUG logging, but when i realized i had to be up for work in 5 hours i had to cease and desist, LOL.

Just FYI, my BE469 (not the Plus model) also seems to lose a RAW message now and then. It’s not frequent, but it is irritating. I’ve placed other nodes very close by which maybe helped a little bit, but did not solve this. (Close means within 1 to 3 feet with no walls in between.) I have no other known issues in my network. This happens infrequently enough that I think turning on the debug log would be too much - it may not occur again for another month or more.

Most of the time this is benign, but I use the unlock on the keypad to turn off the alarm system, and when that doesn’t go through family members get upset as the alarm starts sounding. (Go back outside, lock the door, unlock again, and you’ll be fine…)