Zwave - Yale YRD220 Lock

Chris compiles it from time to time and updates the dev thread link, which is pinned at the top. The link is in the first sentence.

https://community.openhab.org/t/oh2-z-wave-refactoring-and-testing-and-security

Go to the first post at the very top and download the jar. No compiling necessary.

I’ll do an update tonight - I think the only change is to add the extra parameter to the alarm channel.

It seems to be working great now. Thank you very much.

Now, if I could get it to change user codes and lock settings, without corrupting the settings, it would be absolutely perfect. :slight_smile:

I did a hard reset on the lock and removed it and added it back again, and only used Habmin to try to edit the settings. But it still corrupted the user codes and I had to reset the lock again. I am not very enthusiastic about trying it again. It is a lot of work resetting it and adding it back.

Interesting, I can confirm this behavior. This used to work though.

I have made a post about this issue with a workaround that seems to work for me:

@chris, the new level string works perfectly. It gives the slot for the user code and reveals all of the other granular notifications outlined in the support document. Thank you and nice work!

2 Likes

I am getting this error and none of my locks are updating status.

lRepositoryImpl] - Validation issues found in configuration model 'locks.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.
2018-04-23 22:17:22.553 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'locks.rules'
2018-04-23 22:17:23.905 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'locks.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.
2018-04-23 22:17:23.938 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'locks.rules'

The other error did go away though.

Which version of OH are you using? The second rule uses triggeringItem, which would only be available in an OH snapshot build, so you may need to change the rule. I do not get the validation warnings that you are getting and I’m using build 1263. What does VS Code show you?

I was on openHAB snapshot 2.3.0 Build #1259. I had not used VS Code. I imagine this is what you are talking about… https://code.visualstudio.com/docs?start=true ? I Just installed it but not really sure what to do with it…

I now updated to the 1263 snapshot… but still have same error.

2018-04-24 22:01:07.590 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'locks.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.
2018-04-24 22:01:07.601 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'locks.rules'

==> openhab.log <==
2018-04-24 21:52:27.877 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Lock: Update lock states after alarm_raw event': The name 'gLock' cannot be resolved to an item or type; line 6, column 22, length 5

Here is the particular item I am trying to get a status from as defined in the items file

Switch Door_DoorLock "Lock [MAP(lock.map):%s]" <lock> (gUS_Home,gLock,gSleep_Security) {channel="zwave:device:51112ebd:node42:lock_door"}
String Door_AlarmRaw "Lock: Alarm Raw [%s]" <shield> (gUS_Home) {channel="zwave:device:51112ebd:node42:alarm_raw"}

https://docs.openhab.org/configuration/editors.html#openhab-vscode

There must be a difference between the rule and lambda that I posted and what you have in your rule file. Or you do not have the JSONPATH transform service installed.

Transformation-jsonpath - 2.3.0.SNAPSHOT is installed. I will take another look at the rule but I am pretty sure it’s the same. Have already tried deleting and adding back a few times. Maybe something I need to edit in the file? For instance towards the bottom of the file I see some comments on notification types. Am I supposed to uncomment any of that after the “true”?

Nope. I put those in as a reference of the data I’ve seen from alarm_raw, in case someone wanted to handle them differently. If you post what you have in your rule file, I will take a look for you. VS Code with the OH extension will show you what in the rule file is causing the validation warning.

While writing a new rule, I noticed the same validation error and it made me think of your post. Did you create a gLock group? If not, the validation error could be coming from this line:

val actionItem = gLock.members.findFirst[ item | item.name.toString == inputItem.name.toString.replace("_Alarm_Raw","") ]

I’ve updated the example to include the gLock group in the items.

@5iver thanks for that. I was missing that gLock group item and just added it. Getting closer but still not working. I manually unlocked here for instance and get the following. When I update the rule now it no longer gives me an error.

2018-04-25 23:18:10.459 [vent.ItemStateChangedEvent] - Door_AlarmRaw changed from {"notification":"ACCESS_CONTROL__MANUAL_LOCK","level":"1","type":"ACCESS_CONTROL","event":"1","status":"255"} to {"notification":"ACCESS_CONTROL__MANUAL_UNLOCK","level":"1","type":"ACCESS_CONTROL","event":"2","status":"255"}

==> openhab.log <==
2018-04-25 23:18:10.702 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Lock: Update lock states after alarm_raw event': cannot invoke method public abstract java.lang.String org.eclipse.smarthome.core.items.Item.getName() on null

Also here is my Lambda and Rule ( basically a copy from above with a few of the SMS Notification, Kodi, and Alarm Notifications commented out.)

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","") ]
    logDebug("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)
                    logDebug("Rules", "Lock: Alarm events: {} updated to ON (locked)",actionItem.name)
                }
                case "2", case "4" : {
                    actionItem.postUpdate(OFF)
                    logDebug("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)) {
                        case "1" : {
                            message.append(" Scott's code")
                            if (Scott_Region.state != "Home") {
                                Scott_Region.sendCommand("Home")
                                message.append(" and presence state was updated")
                            }
                        }
                        case "2" : {
                            message.append(" Lisa's code")
                            if (Lisa_Region.state != "Home") {
                                Lisa_Region.sendCommand("Home")
                                message.append(" and presence state was updated")
                            }
                        }
                    }
                    Thread::sleep(100)//wait for Presence state to update so alarm doesn't trigger
                    actionItem.postUpdate(OFF)
                    logDebug("Rules", "Lock: {}",message.toString)
                    //SMS_Notification.sendCommand(message.toString)
                }
                case "11" : {
                    logDebug("Rules", "Lock: Alarm events: {} is jammed, so setting lock to OFF (unlocked)",actionItem.label)
                    actionItem.postUpdate(OFF)
                    //SMS_Notification.sendCommand(actionItem.label + " is jammed")
                    //Kodi_Notification.sendCommand(actionItem.label + " is jammed")
                }
                case "16" : {
                    val String message = actionItem.label + " keypad is disabled due to too many failed codes"
                    logDebug("Rules", "Lock: Alarm events: {}",message)
                    //SMS_Notification.sendCommand(message)
                    //Kodi_Notification.sendCommand(message)
                }
                default : {
                    val String message = "Unknown Event in alarmRawParser, " + inputItem.state.toString
                    logDebug("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"
                logDebug("Rules", "Lock: Alarm events: {}",message)
                //SMS_Notification.sendCommand(message)
                //Kodi_Notification.sendCommand(message)
            }
        }
        case "BURGLAR" : {
            //gSiren.sendCommand(ON)
            val String message = "Intruder at " + actionItem.label
            logDebug("Rules", "Lock: Alarm events: {}",message)
            //SMS_Notification.sendCommand(message)
            //Audio_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
            logDebug("Rules", "Lock: Alarm events: {}",message)
            //SMS_Notification.sendCommand(message)
        }
    }
    true
    /*
        {"notification":"ACCESS__MANUAL_LOCK",                          "type":"ACCESS_CONTROL","event":"1","status":"255"}
        {"notification":"ACCESS__MANUAL_UNLOCK",                        "type":"ACCESS_CONTROL","event":"2","status":"255"}
        unlocked with zwave? event 3
        locked with zwave? event 4
        {"notification":"ACCESS__KEYPAD_LOCK",  "code":"1",             "type":"ACCESS_CONTROL","event":"5","status":"255"}
        {"notification":"ACCESS__KEYPAD_UNLOCK","code":"1",             "type":"ACCESS_CONTROL","event":"6","status":"255"}
        {"notification":"ACCESS__LOCK_JAMMED",                          "type":"ACCESS_CONTROL","event":"11","status":"255"}
        {"notification":"ACCESS__KEYPAD_LOCK",                          "type":"ACCESS_CONTROL","event":"5","status":"255"}
        {"notification":"ACCESS_CONTROL__KEYPAD_TEMPORARILY_DISABLED",  "type":"ACCESS_CONTROL","event":"16","status":"255"}
        {"notification":"BURGLAR__TAMPER_UNKNOWN",                      "type":"BURGLAR","event":"2","status":"255"}
        {"notification":"HOME_SECURITY__INTRUSION_UNKNOWN",             "type":"BURGLAR","event":"2","status":"255"}
        {"notification":"POWER__REPLACE_BATTERY_SOON",                  "type":"POWER_MANAGEMENT","event":"10","status":"255"}
        {"notification":"POWER_MANAGEMENT__REPLACE_BATTERY_SOON",       "type":"POWER_MANAGEMENT","event":"10","status":"255"}
    */
]

rule "Lock: Update lock states after alarm_raw event"
when
        Item Door_AlarmRaw received update
then
        alarmRawParser.apply(triggeringItem as GenericItem)
end

Double check your item names with the example. The String item should end with _Alarm_Raw or the very first line of the lambda will error. You should also comment out the lines in the section for user codes… unless you have also Scott_Region and Lisa_Region. :wink:

Since I created the lock items with PaperUI, all may Alarm Raw items end in _AlarmRaw so I changed the line up top instead.

 val actionItem = gLock.members.findFirst[ item | item.name.toString == inputItem.name.toString.replace("_AlarmRaw","") ]

I assume this is ok. I am only testing with one lock at the moment.

Doesn’t look like it fixed the issue but I do see where the issue would have occurred since it did not match.

==> openhab.log <==
2018-04-26 01:19:27.633 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Lock: Update lock states after Alarm Raw event': cannot invoke method public abstract java.lang.String org.eclipse.smarthome.core.items.Item.getName() on null

Here is my rule now…

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("_AlarmRaw","") ]
    logDebug("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)
                    logDebug("Rules", "Lock: Alarm events: {} updated to ON (locked)",actionItem.name)
                }
                case "2", case "4" : {
                    actionItem.postUpdate(OFF)
                    logDebug("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)) {
/*                      case "1" : {
                            message.append(" Scott's code")
                            if (Scott_Region.state != "Home") {
                                Scott_Region.sendCommand("Home")
                                message.append(" and presence state was updated")
                            }
                        }
                        case "2" : {
                            message.append(" Lisa's code")
                            if (Lisa_Region.state != "Home") {
                                Lisa_Region.sendCommand("Home")
                                message.append(" and presence state was updated")
                            }
                        }
*/
                    }
                    Thread::sleep(100)//wait for Presence state to update so alarm doesn't trigger
                    actionItem.postUpdate(OFF)
                    logDebug("Rules", "Lock: {}",message.toString)
                    //SMS_Notification.sendCommand(message.toString)
                }
                case "11" : {
                    logDebug("Rules", "Lock: Alarm events: {} is jammed, so setting lock to OFF (unlocked)",actionItem.label)
                    actionItem.postUpdate(OFF)
                    //SMS_Notification.sendCommand(actionItem.label + " is jammed")
                    //Kodi_Notification.sendCommand(actionItem.label + " is jammed")
                }
                case "16" : {
                    val String message = actionItem.label + " keypad is disabled due to too many failed codes"
                    logDebug("Rules", "Lock: Alarm events: {}",message)
                    //SMS_Notification.sendCommand(message)
                    //Kodi_Notification.sendCommand(message)
                }
                default : {
                    val String message = "Unknown Event in alarmRawParser, " + inputItem.state.toString
                    logDebug("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"
                logDebug("Rules", "Lock: Alarm events: {}",message)
                //SMS_Notification.sendCommand(message)
                //Kodi_Notification.sendCommand(message)
            }
        }
        case "BURGLAR" : {
            //gSiren.sendCommand(ON)
            val String message = "Intruder at " + actionItem.label
            logDebug("Rules", "Lock: Alarm events: {}",message)
            //SMS_Notification.sendCommand(message)
            //Audio_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
            logDebug("Rules", "Lock: Alarm events: {}",message)
            //SMS_Notification.sendCommand(message)
        }
    }
    true
    /*
        {"notification":"ACCESS__MANUAL_LOCK",                          "type":"ACCESS_CONTROL","event":"1","status":"255"}
        {"notification":"ACCESS__MANUAL_UNLOCK",                        "type":"ACCESS_CONTROL","event":"2","status":"255"}
        unlocked with zwave? event 3
        locked with zwave? event 4
        {"notification":"ACCESS__KEYPAD_LOCK",  "code":"1",             "type":"ACCESS_CONTROL","event":"5","status":"255"}
        {"notification":"ACCESS__KEYPAD_UNLOCK","code":"1",             "type":"ACCESS_CONTROL","event":"6","status":"255"}
        {"notification":"ACCESS__LOCK_JAMMED",                          "type":"ACCESS_CONTROL","event":"11","status":"255"}
        {"notification":"ACCESS__KEYPAD_LOCK",                          "type":"ACCESS_CONTROL","event":"5","status":"255"}
        {"notification":"ACCESS_CONTROL__KEYPAD_TEMPORARILY_DISABLED",  "type":"ACCESS_CONTROL","event":"16","status":"255"}
        {"notification":"BURGLAR__TAMPER_UNKNOWN",                      "type":"BURGLAR","event":"2","status":"255"}
        {"notification":"HOME_SECURITY__INTRUSION_UNKNOWN",             "type":"BURGLAR","event":"2","status":"255"}
        {"notification":"POWER__REPLACE_BATTERY_SOON",                  "type":"POWER_MANAGEMENT","event":"10","status":"255"}
        {"notification":"POWER_MANAGEMENT__REPLACE_BATTERY_SOON",       "type":"POWER_MANAGEMENT","event":"10","status":"255"}
    */
]

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

Yes, that would work too! If it is still not working, what is the name for your lock Switch item? The lambda would expect it to be Door.

I understand it’s not very descriptive. I was just testing so made it simple. It is Door_AlarmRaw. I just changed it to say GarageDoor_AlarmRaw and updated rule.

rule "Lock: Update lock states after Alarm Raw event"
when
        Item GarageDoor_AlarmRaw received update

==> events.log <==
2018-04-26 07:26:32.405 [vent.ItemStateChangedEvent] - GarageDoor_AlarmRaw changed from {"notification":"ACCESS_CONTROL__MANUAL_LOCK","level":"1","type":"ACCESS_CONTROL","event":"1","status":"255"} to {"notification":"ACCESS_CONTROL__MANUAL_UNLOCK","level":"1","type":"ACCESS_CONTROL","event":"2","status":"255"}

==> openhab.log <==
2018-04-26 07:26:32.421 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Lock: Update lock states after Alarm Raw event': cannot invoke method public abstract java.lang.String org.eclipse.smarthome.core.items.Item.getName() on null

==> events.log <==
2018-04-26 07:26:36.120 [vent.ItemStateChangedEvent] - GarageDoor_AlarmRaw changed from {"notification":"ACCESS_CONTROL__MANUAL_UNLOCK","level":"1","type":"ACCESS_CONTROL","event":"2","status":"255"} to {"notification":"ACCESS_CONTROL__MANUAL_LOCK","level":"1","type":"ACCESS_CONTROL","event":"1","status":"255"}

==> openhab.log <==
2018-04-26 07:26:36.128 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Lock: Update lock states after Alarm Raw event': cannot invoke method public abstract java.lang.String org.eclipse.smarthome.core.items.Item.getName() on null


I was asking about the other item. It should be a Switch item and named GarageDoor, based on the current name of your String item. This is the item that you would toggle in a sitemap, and which the lambda is updating based on the info it is receiving through the alarm_raw channel. The error you are getting could be caused by this item not being created yet or if it is not in the gLock group.

I also just noticed your GarageDoor_AlarmRaw item is not in gLock either. You will need to add the two items to a group named gLock or modify the group used in the lambda.

Hmm, I must be confused. I have this switch configured here as well as in my items file. In the items file I have the group. I think what you are saying is that what I need is a proxy switch instead of redefining the same switch in items file? I’ll look it over tonight. I must have missed something. It didn’t make sense to me that I was redefining the switch again. So if I got this straight, in the items file the name I should define is the proxy switch name. And leave this as is in the paper you?

This is what I have in my items file currently. The z-wave channel is pointing to the thing switch that was created with with Paper UI as is the alarm raw respectively.

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

Switch GarageDoor_DoorLock "Lock (Garage Home) [MAP(lock.map):%s]" <lock> (gUS_GarageHome,gLock,gSleep_Security) {channel="zwave:device:56857ebd:node37:lock_door"}                                         

String GarageDoor_AlarmRa![Screenshot_20180426-125005_Chrome|243x500](upload://b6zDiRj7K2KTqkcrB41gQQxwwMk.jpg)w "Lock (Garage Home): Alarm Raw [%s]" <shield> (gUS_GarageHome) {channel="zwave:device:56857ebd:node37:alarm_raw"}                                                                    

Finally here is the item you were expecting in last post…