From 71fc8e7f5fba321605300dc4eb7350165235173e Mon Sep 17 00:00:00 2001 From: Duncan McKee Date: Mon, 16 Nov 2015 18:52:08 -0500 Subject: [PATCH 1/2] Fix Z-Wave Lock SecurityException DVCSMP-1265 --- .../zwave-lock.src/zwave-lock.groovy | 72 +++++++++---------- 1 file changed, 33 insertions(+), 39 deletions(-) diff --git a/devicetypes/smartthings/zwave-lock.src/zwave-lock.groovy b/devicetypes/smartthings/zwave-lock.src/zwave-lock.groovy index d6d05e4..2d216c3 100644 --- a/devicetypes/smartthings/zwave-lock.src/zwave-lock.groovy +++ b/devicetypes/smartthings/zwave-lock.src/zwave-lock.groovy @@ -66,6 +66,23 @@ metadata { import physicalgraph.zwave.commands.doorlockv1.* import physicalgraph.zwave.commands.usercodev1.* +def updated() { + try { + def cmds = [] + if (!device.currentState("lock")) { + cmds << zwave.doorLockV1.doorLockOperationGet() + } + if (!device.currentState("battery")) { + cmds << zwave.batteryV1.batteryGet() + } + if (cmds) { + response(secureSequence(cmds)) + } + } catch (e) { + log.warn "updated() threw $e" + } +} + def parse(String description) { def result = null if (description.startsWith("Err")) { @@ -286,7 +303,7 @@ def zwaveEvent(physicalgraph.zwave.commands.alarmv2.AlarmReport cmd) { } break case 167: - if (!state.lastbatt || (new Date().time) - state.lastbatt > 12*60*60*1000) { + if (!state.lastbatt || now() - state.lastbatt > 12*60*60*1000) { map = [ descriptionText: "$device.displayName: battery low", isStateChange: true ] result << response(secure(zwave.batteryV1.batteryGet())) } else { @@ -431,7 +448,7 @@ def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) { } else { map.value = cmd.batteryLevel } - state.lastbatt = new Date().time + state.lastbatt = now() createEvent(map) } @@ -499,15 +516,15 @@ def refresh() { cmds << "delay 4200" cmds << zwave.associationV1.associationGet(groupingIdentifier:2).format() // old Schlage locks use group 2 and don't secure the Association CC cmds << secure(zwave.associationV1.associationGet(groupingIdentifier:1)) - state.associationQuery = new Date().time - } else if (new Date().time - state.associationQuery.toLong() > 9000) { + state.associationQuery = now() + } else if (secondsPast(state.associationQuery, 9)) { log.debug "setting association" cmds << "delay 6000" cmds << zwave.associationV1.associationSet(groupingIdentifier:2, nodeId:zwaveHubNodeId).format() cmds << secure(zwave.associationV1.associationSet(groupingIdentifier:1, nodeId:zwaveHubNodeId)) cmds << zwave.associationV1.associationGet(groupingIdentifier:2).format() cmds << secure(zwave.associationV1.associationGet(groupingIdentifier:1)) - state.associationQuery = new Date().time + state.associationQuery = now() } log.debug "refresh sending ${cmds.inspect()}" cmds @@ -523,47 +540,24 @@ def poll() { cmds << "delay 6000" cmds << secure(zwave.associationV1.associationGet(groupingIdentifier:1)) cmds << "delay 6000" - state.associationQuery = new Date().time + state.associationQuery = now() } else { // Only check lock state if it changed recently or we haven't had an update in an hour def latest = device.currentState("lock")?.date?.time if (!latest || !secondsPast(latest, 6 * 60) || secondsPast(state.lastPoll, 55 * 60)) { cmds << secure(zwave.doorLockV1.doorLockOperationGet()) - state.lastPoll = (new Date()).time - } else if (!state.MSR) { - cmds << zwave.manufacturerSpecificV1.manufacturerSpecificGet().format() - } else if (!state.fw) { - cmds << zwave.versionV1.versionGet().format() - } else if (!state.codes) { - state.pollCode = 1 - cmds << secure(zwave.userCodeV1.usersNumberGet()) - } else if (state.pollCode && state.pollCode <= state.codes) { - cmds << requestCode(state.pollCode) - } else if (!state.lastbatt || (new Date().time) - state.lastbatt > 53*60*60*1000) { + state.lastPoll = now() + } else if (!state.lastbatt || now() - state.lastbatt > 53*60*60*1000) { cmds << secure(zwave.batteryV1.batteryGet()) - } else if (!state.enc) { - encryptCodes() - state.enc = 1 } } - log.debug "poll is sending ${cmds.inspect()}" - device.activity() - cmds ?: null -} - -private def encryptCodes() { - def keys = new ArrayList(state.keySet().findAll { it.startsWith("code") }) - keys.each { key -> - def match = (key =~ /^code(\d+)$/) - if (match) try { - def keynum = match[0][1].toInteger() - if (keynum > 30 && !state[key]) { - state.remove(key) - } else if (state[key] && !state[key].startsWith("~")) { - log.debug "encrypting $key: ${state[key].inspect()}" - state[key] = encrypt(state[key]) - } - } catch (java.lang.NumberFormatException e) { } + if (cmds) { + log.debug "poll is sending ${cmds.inspect()}" + cmds + } else { + // workaround to keep polling from stopping due to lack of activity + sendEvent(descriptionText: "skipping poll", isStateChange: true, displayed: false) + null } } @@ -672,7 +666,7 @@ private Boolean secondsPast(timestamp, seconds) { return true } } - return (new Date().time - timestamp) > (seconds * 1000) + return (now() - timestamp) > (seconds * 1000) } private allCodesDeleted() { From 8ae9b06022e061102e50ef5339e4212912746d14 Mon Sep 17 00:00:00 2001 From: Duncan McKee Date: Tue, 17 Nov 2015 18:08:44 -0500 Subject: [PATCH 2/2] Z-Wave Lock: fix double updated() commands DVCSMP-1265 --- .../zwave-lock.src/zwave-lock.groovy | 43 ++++++------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/devicetypes/smartthings/zwave-lock.src/zwave-lock.groovy b/devicetypes/smartthings/zwave-lock.src/zwave-lock.groovy index 2d216c3..fc44982 100644 --- a/devicetypes/smartthings/zwave-lock.src/zwave-lock.groovy +++ b/devicetypes/smartthings/zwave-lock.src/zwave-lock.groovy @@ -68,15 +68,9 @@ import physicalgraph.zwave.commands.usercodev1.* def updated() { try { - def cmds = [] - if (!device.currentState("lock")) { - cmds << zwave.doorLockV1.doorLockOperationGet() - } - if (!device.currentState("battery")) { - cmds << zwave.batteryV1.batteryGet() - } - if (cmds) { - response(secureSequence(cmds)) + if (!state.init) { + state.init = true + response(secureSequence([zwave.doorLockV1.doorLockOperationGet(), zwave.batteryV1.batteryGet()])) } } catch (e) { log.warn "updated() threw $e" @@ -85,7 +79,7 @@ def updated() { def parse(String description) { def result = null - if (description.startsWith("Err")) { + if (description.startsWith("Err 106")) { if (state.sec) { result = createEvent(descriptionText:description, displayed:false) } else { @@ -97,6 +91,8 @@ def parse(String description) { displayed: true, ) } + } else if (description == "updated") { + return null } else { def cmd = zwave.parse(description, [ 0x98: 1, 0x72: 2, 0x85: 2, 0x86: 1 ]) if (cmd) { @@ -518,7 +514,6 @@ def refresh() { cmds << secure(zwave.associationV1.associationGet(groupingIdentifier:1)) state.associationQuery = now() } else if (secondsPast(state.associationQuery, 9)) { - log.debug "setting association" cmds << "delay 6000" cmds << zwave.associationV1.associationSet(groupingIdentifier:2, nodeId:zwaveHubNodeId).format() cmds << secure(zwave.associationV1.associationSet(groupingIdentifier:1, nodeId:zwaveHubNodeId)) @@ -532,24 +527,14 @@ def refresh() { def poll() { def cmds = [] - if (state.assoc != zwaveHubNodeId && secondsPast(state.associationQuery, 19 * 60)) { - log.debug "setting association" - cmds << zwave.associationV1.associationSet(groupingIdentifier:2, nodeId:zwaveHubNodeId).format() - cmds << secure(zwave.associationV1.associationSet(groupingIdentifier:1, nodeId:zwaveHubNodeId)) - cmds << zwave.associationV1.associationGet(groupingIdentifier:2).format() - cmds << "delay 6000" - cmds << secure(zwave.associationV1.associationGet(groupingIdentifier:1)) - cmds << "delay 6000" - state.associationQuery = now() - } else { - // Only check lock state if it changed recently or we haven't had an update in an hour - def latest = device.currentState("lock")?.date?.time - if (!latest || !secondsPast(latest, 6 * 60) || secondsPast(state.lastPoll, 55 * 60)) { - cmds << secure(zwave.doorLockV1.doorLockOperationGet()) - state.lastPoll = now() - } else if (!state.lastbatt || now() - state.lastbatt > 53*60*60*1000) { - cmds << secure(zwave.batteryV1.batteryGet()) - } + // Only check lock state if it changed recently or we haven't had an update in an hour + def latest = device.currentState("lock")?.date?.time + if (!latest || !secondsPast(latest, 6 * 60) || secondsPast(state.lastPoll, 55 * 60)) { + cmds << secure(zwave.doorLockV1.doorLockOperationGet()) + state.lastPoll = now() + } else if (!state.lastbatt || now() - state.lastbatt > 53*60*60*1000) { + cmds << secure(zwave.batteryV1.batteryGet()) + state.lastbatt = now() //inside-214 } if (cmds) { log.debug "poll is sending ${cmds.inspect()}"