Please help me understand zwave lock inclusion/exclusion and secure install

I think I understand. I have copied your rule and added my values to it. It looks like this:

import org.eclipse.smarthome.model.script.ScriptServiceUtil

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)
    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 "21", case "18", case "24" : {
                    actionItem.postUpdate(ON)
                    message.append(" updated to ON (locked)")
                }
                case "22", case "19" : {
                    actionItem.postUpdate(OFF)
                    message.append(" updated to OFF (unlocked)")
                }
//                case "6" : {
//                    actionItem.postUpdate(OFF)
//                   message.append(" was unlocked with")
//                    switch (transform("JSONPATH", "$.code", triggeringItem.state.toString)) {
//                        case "1" : {
//                            message.append(" Scott's code")
//                        }
//                        case "2" : {
//                            message.append(" Lisa's code")
//                        }
//                    }
//                }
                case "26", case "17", case "23" : {
                    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)")
                }
//                case "26", case "17", case "23" : {
//                    message.append(" keypad is disabled due to too many failed codes")
//                }
                default : {
                    message.append(" unknown door lock Event, ").append(triggeringItem.state.toString)
                }
            }
            if (transform("JSONPATH", "$.event", triggeringItem.previousState(true).state.toString) == "26" && transform("JSONPATH", "$.event", triggeringItem.state.toString) != "26") {
                message.append(" and is no longer jammed")
            }
        }
//        case "BURGLAR" : {
//            //gSiren.sendCommand(ON)
//            message.append(" has detected an intruder")
//        }
        case "POWER_MANAGEMENT" : {
            message.append(" received a Power Management alarm, ").append(triggeringItem.state.toString)
        }
        default : {
            message.append(" received and unknown Type in alarmRawParser, ").append(triggeringItem.state.toString)
        }
    }
    logInfo("Rules", "Lock: Alarm events: {}", message.toString)
end

I turned the code I feel I don’t need into text.

I then created a lock.map under /etc/openhab2/transform, and copied

OFF=Unlocked
ON=Locked
undefined=Unknown
-=Unknown
NULL=Unknown

into it. The lock still ill does not update with manual activation. Any thoughts?

Put the binding into debug mode so we can see what the lock is sending (if anything) when manually operated. Enable debug logging as described in the post below, then operate the lock. If the lock is reporting its status when manually operated, you will see activity in the log file. Report back what you see in the log.

The 914TRL reports different events than the BE469, so you’ll need to adjust the switch/case statements. Here is an example


Thank you, all of you, for help and patience. I am really trying to understand all of this. I am more of a nuts and bolts kind of guy and this stuff, though very cool, has me feeling over my head.

I looked at doc about turning on the debug. It says to enter the console, which I am guessing is the process of SSH into openhabian. I paste

log:set DEBUG org.openhab.binding.zwave

But get an error -bash: log:set: command not found
So I am guessing I am not something correctly.

I did see that activity seems to be captured in the log viewer anyway. This is what it shows.

2019-06-29 20:57:17.211 [vent.ItemStateChangedEvent] - zwave_serial_zstick_Zstick_serial_sof changed from 3520 to 3521

2019-06-29 20:57:17.244 [vent.ItemStateChangedEvent] - zwave_serial_zstick_Zstick_serial_ack changed from 1273 to 1274

2019-06-29 20:57:17.251 [vent.ItemStateChangedEvent] - zwave_serial_zstick_Zstick_serial_sof changed from 3521 to 3522

2019-06-29 20:57:17.271 [vent.ItemStateChangedEvent] - zwave_serial_zstick_Zstick_serial_sof changed from 3522 to 3523

2019-06-29 20:57:17.291 [vent.ItemStateChangedEvent] - zwave_serial_zstick_Zstick_serial_sof changed from 3523 to 3524

2019-06-29 20:57:17.321 [vent.ItemStateChangedEvent] - zwave_device_Zstick_node6_alarm_number changed from 0 to 21

2019-06-29 20:57:17.326 [vent.ItemStateChangedEvent] - zwave_device_Zstick_node6_alarm_raw changed from {"type":"0","value":"0"} to {"type":"21","value":"1"}

2019-06-29 20:57:31.720 [vent.ItemStateChangedEvent] - zwave_serial_zstick_Zstick_serial_sof changed from 3524 to 3525

2019-06-29 20:57:31.758 [vent.ItemStateChangedEvent] - zwave_serial_zstick_Zstick_serial_ack changed from 1274 to 1275

2019-06-29 20:57:31.762 [vent.ItemStateChangedEvent] - zwave_serial_zstick_Zstick_serial_sof changed from 3525 to 3526

2019-06-29 20:57:31.784 [vent.ItemStateChangedEvent] - zwave_serial_zstick_Zstick_serial_sof changed from 3526 to 3527

2019-06-29 20:57:31.794 [vent.ItemStateChangedEvent] - zwave_serial_zstick_Zstick_serial_sof changed from 3527 to 3528

2019-06-29 20:57:31.831 [vent.ItemStateChangedEvent] - zwave_device_Zstick_node6_alarm_number changed from 21 to 22

2019-06-29 20:57:31.834 [vent.ItemStateChangedEvent] - zwave_device_Zstick_node6_alarm_raw changed from {"type":"21","value":"1"} to {"type":"22","value":"1"}

I am pretty sure I changed the case values correctly for my lock.

switch (transform("JSONPATH","$.type",triggeringItem.state.toString)) {
        case "ACCESS_CONTROL" : {
            switch (transform("JSONPATH", "$.event", triggeringItem.state.toString)) {
                case "18", case "21", case "24" : {
                    actionItem.postUpdate(ON)
                    message.append(" updated to ON (locked)")
                }
                case "19", case "21" : {
                    actionItem.postUpdate(OFF)
                    message.append(" updated to OFF (unlocked)")
                }

Thank you again, and let me know what to do to help

You were at a shell prompt, not the console.

This doesn’t look right.

                case "18", case "21", case "24" : {
...
                case "19", case "21" : {

One of those should be “22”.

You are correct, I changed it to

 case "19", case "22" : {

I went back and relized I had not saved my updated items. Now my items look like this:

Group:Switch:OR(OFF,ON)    gLock    "Locks [MAP(lock.map):%s]"    <lock>
Group    gLockRaw    "Locks (raw) [%s]"    <lock>
Switch    Z_Wave_Front_Door_Lock    "Lock (Front Entrance) [MAP(lock.map):%s]"    <lock>    (gLock)    {channel="zwave:device:Zstick:node6:lock_door"}
String 	  Z_Wave_Front_Door_Lock_Alarm_Raw    "Lock (Front Entrance): Alarm Raw [%s]"    <shield>    (gLockRaw)    {channel="zwave:device:Zstick:node6:alarm_raw"}

And my log gives me this:

2019-06-30 08:32:25.157 [vent.ItemStateChangedEvent] - zwave_serial_zstick_Zstick_serial_sof changed from 417 to 418

2019-06-30 08:32:25.176 [vent.ItemStateChangedEvent] - zwave_serial_zstick_Zstick_serial_ack changed from 145 to 146

2019-06-30 08:32:25.180 [vent.ItemStateChangedEvent] - zwave_serial_zstick_Zstick_serial_sof changed from 418 to 419

2019-06-30 08:32:25.195 [vent.ItemStateChangedEvent] - zwave_serial_zstick_Zstick_serial_sof changed from 419 to 420

2019-06-30 08:32:25.217 [vent.ItemStateChangedEvent] - zwave_serial_zstick_Zstick_serial_sof changed from 420 to 421

2019-06-30 08:32:25.254 [vent.ItemStateChangedEvent] - zwave_device_Zstick_node6_alarm_number changed from 21 to 22

2019-06-30 08:32:25.257 [vent.ItemStateChangedEvent] - Z_Wave_Front_Door_Lock_Alarm_Raw changed from {"type":"21","value":"1"} to {"type":"22","value":"1"}

2019-06-30 08:32:25.261 [vent.ItemStateChangedEvent] - zwave_device_Zstick_node6_alarm_raw changed from {"type":"21","value":"1"} to {"type":"22","value":"1"}

==> /var/log/openhab2/openhab.log <==

2019-06-30 08:32:25.266 [INFO ] [eclipse.smarthome.model.script.Rules] - Lock: Alarm events: Z_Wave_Front_Door_Lock=[{"type":"22","value":"1"}]

2019-06-30 08:32:25.282 [INFO ] [eclipse.smarthome.model.script.Rules] - Lock: Alarm events: Z_Wave_Front_Door_Lock received and unknown Type in alarmRawParser, {"type":"22","value":"1"}

I am guessing that this last line means that I have wrong in my lock.map file or something is not reading from my lock.map?

Hmm. Looking at this bit of code in the rule you posted earlier


    switch (transform("JSONPATH","$.type",triggeringItem.state.toString)) {
        case "ACCESS_CONTROL" : {
        [snip]
        case "POWER_MANAGEMENT" : {
        [snip]
        default : {

Isn’t this the value of triggeringItem.state?

{"type":"21","value":"1"}

If so, I think you need to get rid of those case statements, as well as the inner switch statement. For example:

switch (transform("JSONPATH","$.type",triggeringItem.state.toString)) {
    case "18", case "21", case "24" : {
        actionItem.postUpdate(ON)
        message.append(" updated to ON (locked)")
    }
    case "19", case "22" : {
        actionItem.postUpdate(OFF)
        message.append(" updated to OFF (unlocked)")
    }
    ...
    default : {
        message.append(" unknown door lock Event, ").append(triggeringItem.state.toString)
    }
}

I tried removing that line as you suggested, then I noticed I got some errors in my log. I put the rule back to the way I had it and I got even more errors. Here they are:

2019-06-30 20:36:44.156 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'home.rules' has errors, therefore ignoring it: [37,17]: missing '}' at 'case'

[44,17]: mismatched input 'default' expecting 'end'

Is [37,17] the column then line? What exactly does this error mean, there should be a } in column 37? What does the next error mean? In case it helps, here is what I am currently using for my rule:

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)
    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 "18", case "21", case "24" : {
                    actionItem.postUpdate(ON)
                    message.append(" updated to ON (locked)")
                }
                case "19", case "22" : {
                    actionItem.postUpdate(OFF)
                    message.append(" updated to OFF (unlocked)")
                }
/*                case "6" : {
                    actionItem.postUpdate(OFF)
                   message.append(" was unlocked with")
                    switch (transform("JSONPATH", "$.code", triggeringItem.state.toString)) {
                        case "1" : {
                            message.append(" Scott's code")
                        }
                        case "2" : {
                            message.append(" Lisa's code")
                        }
                    }
                }
                case "26", case "17", case "23" : {
                    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)")
                }
               case "26", case "17", case "23" : {
                    message.append(" keypad is disabled due to too many failed codes")
                }
                default : {
                    message.append(" unknown door lock Event, ").append(triggeringItem.state.toString)
                }
            }
            if (transform("JSONPATH", "$.event", triggeringItem.previousState(true).state.toString) == "26" && transform("JSONPATH", "$.event", triggeringItem.state.toString) != "26") {
                message.append(" and is no longer jammed")
            }
        }
        case "BURGLAR" : {
            //gSiren.sendCommand(ON)
            message.append(" has detected an intruder")
        }
        case "POWER_MANAGEMENT" : {
            message.append(" received a Power Management alarm, ").append(triggeringItem.state.toString)
        }*/
        default : {
            message.append(" received and unknown Type in alarmRawParser, ").append(triggeringItem.state.toString)
        }
    }
    logInfo("Rules", "Lock: Alarm events: {}", message.toString)
end

If your device is reporting json strings of the following form, please follow the guidance I provided above. Your rule will never work the way you have it defined with the json strings below.

{"type":"21","value":"1"}

mhilbush, thank you, thank you, thank you!!!

I modified my rule like said and now it works. It now looks like 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)
    val StringBuilder message = new StringBuilder(actionItem.name)
    switch (transform("JSONPATH","$.type",triggeringItem.state.toString)) {
                case "18", case "21", case "24" : {
                    actionItem.postUpdate(ON)
                    message.append(" updated to ON (locked)")
                }
                case "19", case "22" : {
                    actionItem.postUpdate(OFF)
                    message.append(" updated to OFF (unlocked)")
                }
 }
    logInfo("Rules", "Lock: Alarm events: {}", message.toString)
end

Your patience has been much appreciated. I would love to understand why this change fixed the issue. I have read what I could find JSON and don’t really understand it. If you are willing to direct me to any helpful informaiton, or just willing to share whatever knowledge you I would be love to try and learn from it.

Oh by the way, I like your BMW

The original rule was expecting a JSON document that probably looked something like this.

{ "type":  "ACCESS_CONTROL", "event": "18" }

That’s why the original rule used transform("JSONPATH","$.type",triggeringItem.state.toString) in the first switch statement, then transform("JSONPATH", "$.event", triggeringItem.state.toString) in the second switch statement once it determined it was of type ACCESS_CONTROL.

The first JSONPATH transform call basically says give me the value associated with the name type. The $ says to look in the root of the JSON document. The second call says give me the value associated with the name event, also in the root of the document.

I hope this makes sense.

There are a bunch of evaluators on the web where you can test your ideas independently of putting them in a rule. For example, https://jsonpath.com/.

Try putting $.type and {"type":"21","value":"1"} in that tool and you’ll see how it evaluates. Then compare it to $.type and { "type": "ACCESS_CONTROL", "event": "18" } and you’ll see the difference.

Thanks. The E30 M3 was one of the best cars ever made, IMO. I restored it back to stock condition, and don’t drive it on the track anymore. With 58,000 miles (93,000 km) on the clock, it spends way too much time in the garage, unfortunately. :frowning_face:

1 Like