From 8a66742bb538204b6f89f8573bce6bf83d10f20b Mon Sep 17 00:00:00 2001 From: David Sainte-Claire Date: Tue, 1 Nov 2016 13:30:35 -0700 Subject: [PATCH 01/17] added device watch implementation for ecobee based on the code from lyric --- .../ecobee-thermostat.groovy | 23 ++++++++++++++++++- .../ecobee-connect.src/ecobee-connect.groovy | 1 + 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/devicetypes/smartthings/ecobee-thermostat.src/ecobee-thermostat.groovy b/devicetypes/smartthings/ecobee-thermostat.src/ecobee-thermostat.groovy index adf6433..296e381 100644 --- a/devicetypes/smartthings/ecobee-thermostat.src/ecobee-thermostat.groovy +++ b/devicetypes/smartthings/ecobee-thermostat.src/ecobee-thermostat.groovy @@ -23,6 +23,7 @@ metadata { capability "Sensor" capability "Refresh" capability "Relative Humidity Measurement" + capability "Health Check" command "generateEvent" command "raiseSetpoint" @@ -38,6 +39,7 @@ metadata { attribute "maxCoolingSetpoint", "number" attribute "minCoolingSetpoint", "number" attribute "deviceTemperatureUnit", "string" + attribute "deviceAlive", "enum", ["true", "false"] } tiles { @@ -120,6 +122,21 @@ metadata { } +void installed() { + // The device refreshes every 5 minutes by default so if we miss 2 refreshes we can consider it offline + // Using 12 minutes because in testing, device health team found that there could be "jitter" + sendEvent(name: "checkInterval", value: 60 * 12, data: [protocol: "cloud", hubHardwareId: device.hub.hardwareID], displayed: false) +} + +// Device Watch will ping the device to proactively determine if the device has gone offline +// If the device was online the last time we refreshed, trigger another refresh as part of the ping. +def ping() { + def isAlive = device.currentValue("deviceAlive") == "true" ? true : false + if (isAlive) { + refresh() + } +} + // parse events into attributes def parse(String description) { log.debug "Parsing '${description}'" @@ -164,7 +181,11 @@ def generateEvent(Map results) { } else if (name=="humidity") { isChange = isStateChange(device, name, value.toString()) event << [value: value.toString(), isStateChange: isChange, displayed: false, unit: "%"] - } else { + } else if (name == "deviceAlive") { + isChange = isStateChange(device, name, value.toString()) + event['isStateChange'] = isChange + event['displayed'] = false + } else { isChange = isStateChange(device, name, value.toString()) isDisplayed = isChange event << [value: value.toString(), isStateChange: isChange, displayed: isDisplayed] diff --git a/smartapps/smartthings/ecobee-connect.src/ecobee-connect.groovy b/smartapps/smartthings/ecobee-connect.src/ecobee-connect.groovy index d8c2179..9b4c178 100644 --- a/smartapps/smartthings/ecobee-connect.src/ecobee-connect.groovy +++ b/smartapps/smartthings/ecobee-connect.src/ecobee-connect.groovy @@ -842,6 +842,7 @@ private void storeThermostatData(thermostats) { minCoolingSetpoint: (stat.settings.coolRangeLow / 10), maxCoolingSetpoint: (stat.settings.coolRangeHigh / 10), autoMode: stat.settings.autoHeatCoolFeatureEnabled, + deviceAlive: stat.runtime.connected == true ? "true" : "false", auxHeatMode: (stat.settings.hasHeatPump) && (stat.settings.hasForcedAir || stat.settings.hasElectric || stat.settings.hasBoiler), temperature: (stat.runtime.actualTemperature / 10), heatingSetpoint: stat.runtime.desiredHeat / 10, From 3a377ba1479feeb42805738603edc9098a811ee9 Mon Sep 17 00:00:00 2001 From: David Sainte-Claire Date: Tue, 1 Nov 2016 23:04:45 -0700 Subject: [PATCH 02/17] added code formatting based on pull request comments --- .../ecobee-thermostat.src/ecobee-thermostat.groovy | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/devicetypes/smartthings/ecobee-thermostat.src/ecobee-thermostat.groovy b/devicetypes/smartthings/ecobee-thermostat.src/ecobee-thermostat.groovy index 296e381..198fc0a 100644 --- a/devicetypes/smartthings/ecobee-thermostat.src/ecobee-thermostat.groovy +++ b/devicetypes/smartthings/ecobee-thermostat.src/ecobee-thermostat.groovy @@ -182,9 +182,9 @@ def generateEvent(Map results) { isChange = isStateChange(device, name, value.toString()) event << [value: value.toString(), isStateChange: isChange, displayed: false, unit: "%"] } else if (name == "deviceAlive") { - isChange = isStateChange(device, name, value.toString()) - event['isStateChange'] = isChange - event['displayed'] = false + isChange = isStateChange(device, name, value.toString()) + event['isStateChange'] = isChange + event['displayed'] = false } else { isChange = isStateChange(device, name, value.toString()) isDisplayed = isChange From 492315b78ace6394abc7e9f4e390b200cf86c804 Mon Sep 17 00:00:00 2001 From: Parijat Das Date: Thu, 22 Sep 2016 17:42:56 +0530 Subject: [PATCH 03/17] Added health check for Leviton DZPA1 Plug-in Appliance Module and GE Plug-In Outdoor Smart Switch (GE 12720) (Z-Wave) along with the README.md --- .../zwave-switch-generic.src/.st-ignore | 2 + .../zwave-switch-generic.src/README.md | 39 +++++++++++++++++++ .../zwave-switch-generic.groovy | 15 +++++++ 3 files changed, 56 insertions(+) create mode 100644 devicetypes/smartthings/zwave-switch-generic.src/.st-ignore create mode 100644 devicetypes/smartthings/zwave-switch-generic.src/README.md diff --git a/devicetypes/smartthings/zwave-switch-generic.src/.st-ignore b/devicetypes/smartthings/zwave-switch-generic.src/.st-ignore new file mode 100644 index 0000000..f78b46e --- /dev/null +++ b/devicetypes/smartthings/zwave-switch-generic.src/.st-ignore @@ -0,0 +1,2 @@ +.st-ignore +README.md diff --git a/devicetypes/smartthings/zwave-switch-generic.src/README.md b/devicetypes/smartthings/zwave-switch-generic.src/README.md new file mode 100644 index 0000000..72ba38d --- /dev/null +++ b/devicetypes/smartthings/zwave-switch-generic.src/README.md @@ -0,0 +1,39 @@ +# Z-wave Switch + + + +Works with: + +* [Leviton Appliance Module (DZPA1-1LW)](https://support.smartthings.com/hc/en-us/articles/205881176-Leviton-Appliance-Module-DZPA1-1LW-) +* [GE Plug-In Outdoor Smart Switch (GE 12720) (Z-Wave)](https://support.smartthings.com/hc/en-us/articles/200903080-GE-Plug-In-Outdoor-Smart-Switch-GE-12720-Z-Wave-) + +## Table of contents + +* [Capabilities](#capabilities) +* [Health](#device-health) + +## Capabilities + +* **Actuator** - represents that a Device has commands +* **Health Check** - indicates ability to get device health notifications +* **Switch** - can detect state (possible values: on/off) +* **Polling** - represents that poll() can be implemented for the device +* **Refresh** - _refresh()_ command for status updates +* **Sensor** - detects sensor events + +## Device Health + +A Category C5 Leviton Appliance Module (DZPA1-1LW) and GE Plug-In Outdoor Smart Switch (GE 12720) (Z-Wave) polled by the hub. +As of hubCore version 0.14.38 the hub sends up reports every 15 minutes regardless of whether the state changed. +Device-Watch allows 2 check-in misses from device plus some lag time. So Check-in interval = (2*15 + 2)mins = 32 mins. +Not to mention after going OFFLINE when the device is plugged back in, it might take a considerable amount of time for +the device to appear as ONLINE again. This is because if this listening device does not respond to two poll requests in a row, +it is not polled for 5 minutes by the hub. This can delay up the process of being marked ONLINE by quite some time. + +## Troubleshooting + +If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the device is out of range. +Pairing needs to be tried again by placing the device closer to the hub. +Instructions related to pairing, resetting and removing the device from SmartThings can be found in the following link: +* [Leviton Appliance Module (DZPA1-1LW) Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/205881176-Leviton-Appliance-Module-DZPA1-1LW-) +* [GE Plug-In Outdoor Smart Switch (GE 12720) (Z-Wave) Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/200903080-GE-Plug-In-Outdoor-Smart-Switch-GE-12720-Z-Wave-) \ No newline at end of file diff --git a/devicetypes/smartthings/zwave-switch-generic.src/zwave-switch-generic.groovy b/devicetypes/smartthings/zwave-switch-generic.src/zwave-switch-generic.groovy index 798b89d..411440f 100644 --- a/devicetypes/smartthings/zwave-switch-generic.src/zwave-switch-generic.groovy +++ b/devicetypes/smartthings/zwave-switch-generic.src/zwave-switch-generic.groovy @@ -14,12 +14,15 @@ metadata { definition (name: "Z-Wave Switch Generic", namespace: "smartthings", author: "SmartThings") { capability "Actuator" + capability "Health Check" capability "Switch" capability "Polling" capability "Refresh" capability "Sensor" fingerprint inClusters: "0x25", deviceJoinName: "Z-Wave Switch" + fingerprint mfr:"001D", prod:"1A02", model:"0334", deviceJoinName: "Leviton Appliance Module" + fingerprint mfr:"0063", prod:"4F50", model:"3031", deviceJoinName: "GE Plug-in Outdoor Switch" } // simulator metadata @@ -50,6 +53,11 @@ metadata { } } +def updated(){ +// Device-Watch simply pings if no device events received for checkInterval duration of 32min = 2 * 15min + 2min lag time + sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID]) +} + def parse(String description) { def result = null def cmd = zwave.parse(description, [0x20: 1, 0x70: 1]) @@ -126,6 +134,13 @@ def poll() { ]) } +/** + * PING is used by Device-Watch in attempt to reach the Device + * */ +def ping() { + refresh() +} + def refresh() { delayBetween([ zwave.switchBinaryV1.switchBinaryGet().format(), From 4115d8c65f33494a2cc71b784187639b27fe5a22 Mon Sep 17 00:00:00 2001 From: Zach Varberg Date: Wed, 2 Nov 2016 11:06:13 -0500 Subject: [PATCH 04/17] Pass unhandled messages up to the cloud Currently these DTHs return null when they parse a message that they don't have specific handling for. This ends up sending the message up to the cloud as an event, which prevented us from potentially parsing that message in the cloud. By instead returning an empty map we can instead send the message up to the cloud to be parsed there. This allows us to add handling in the cloud for new message without requiring and AppEngine deploy for them to work. This resolves: https://smartthings.atlassian.net/browse/DPROT-200 --- .../smartpower-dimming-outlet.groovy | 7 ++-- .../smartpower-outlet.groovy | 10 ++++-- .../smartsense-garage-door-multi.groovy | 2 +- .../smartsense-moisture-sensor.groovy | 2 +- .../smartsense-motion-sensor.groovy | 2 +- .../smartsense-motion-temp-sensor.groovy | 2 +- .../smartsense-motion.groovy | 34 +++++++++++-------- .../smartsense-multi-sensor.groovy | 2 +- .../smartsense-open-closed-sensor.groovy | 2 +- .../smartsense-temp-humidity-sensor.groovy | 2 +- 10 files changed, 38 insertions(+), 27 deletions(-) diff --git a/devicetypes/smartthings/smartpower-dimming-outlet.src/smartpower-dimming-outlet.groovy b/devicetypes/smartthings/smartpower-dimming-outlet.src/smartpower-dimming-outlet.groovy index 27e9734..a4c240a 100644 --- a/devicetypes/smartthings/smartpower-dimming-outlet.src/smartpower-dimming-outlet.groovy +++ b/devicetypes/smartthings/smartpower-dimming-outlet.src/smartpower-dimming-outlet.groovy @@ -69,15 +69,17 @@ metadata { def parse(String description) { log.debug "description is $description" + def event = [:] def finalResult = isKnownDescription(description) if (finalResult != "false") { log.info finalResult if (finalResult.type == "update") { log.info "$device updates: ${finalResult.value}" + event = null } else if (finalResult.type == "power") { def powerValue = (finalResult.value as Integer)/10 - sendEvent(name: "power", value: powerValue) + event = createEvent(name: "power", value: powerValue) /* Dividing by 10 as the Divisor is 10000 and unit is kW for the device. AttrId: 0302 and 0300. Simplifying to 10 @@ -87,13 +89,14 @@ def parse(String description) { */ } else { - sendEvent(name: finalResult.type, value: finalResult.value) + event = createEvent(name: finalResult.type, value: finalResult.value) } } else { log.warn "DID NOT PARSE MESSAGE for description : $description" log.debug parseDescriptionAsMap(description) } + return event } // Commands to device diff --git a/devicetypes/smartthings/smartpower-outlet.src/smartpower-outlet.groovy b/devicetypes/smartthings/smartpower-outlet.src/smartpower-outlet.groovy index d96dd77..192f75a 100644 --- a/devicetypes/smartthings/smartpower-outlet.src/smartpower-outlet.groovy +++ b/devicetypes/smartthings/smartpower-outlet.src/smartpower-outlet.groovy @@ -79,6 +79,7 @@ def parse(String description) { log.debug "description is $description" def finalResult = zigbee.getKnownDescription(description) + def event = [:] //TODO: Remove this after getKnownDescription can parse it automatically if (!finalResult && description!="updated") @@ -88,10 +89,11 @@ def parse(String description) { log.info "final result = $finalResult" if (finalResult.type == "update") { log.info "$device updates: ${finalResult.value}" + event = null } else if (finalResult.type == "power") { def powerValue = (finalResult.value as Integer)/10 - sendEvent(name: "power", value: powerValue, descriptionText: '{{ device.displayName }} power is {{ value }} Watts', translatable: true ) + event = createEvent(name: "power", value: powerValue, descriptionText: '{{ device.displayName }} power is {{ value }} Watts', translatable: true) /* Dividing by 10 as the Divisor is 10000 and unit is kW for the device. AttrId: 0302 and 0300. Simplifying to 10 power level is an integer. The exact power level with correct units needs to be handled in the device type @@ -100,7 +102,7 @@ def parse(String description) { } else { def descriptionText = finalResult.value == "on" ? '{{ device.displayName }} is On' : '{{ device.displayName }} is Off' - sendEvent(name: finalResult.type, value: finalResult.value, descriptionText: descriptionText, translatable: true) + event = createEvent(name: finalResult.type, value: finalResult.value, descriptionText: descriptionText, translatable: true) } } else { @@ -109,10 +111,11 @@ def parse(String description) { if (cluster && cluster.clusterId == 0x0006 && cluster.command == 0x07){ if (cluster.data[0] == 0x00) { log.debug "ON/OFF REPORTING CONFIG RESPONSE: " + cluster - sendEvent(name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) + event = createEvent(name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) } else { log.warn "ON/OFF REPORTING CONFIG FAILED- error code:${cluster.data[0]}" + event = null } } else { @@ -120,6 +123,7 @@ def parse(String description) { log.debug "${cluster}" } } + return event } def off() { diff --git a/devicetypes/smartthings/smartsense-garage-door-multi.src/smartsense-garage-door-multi.groovy b/devicetypes/smartthings/smartsense-garage-door-multi.src/smartsense-garage-door-multi.groovy index 73b0fcf..8454b9c 100644 --- a/devicetypes/smartthings/smartsense-garage-door-multi.src/smartsense-garage-door-multi.groovy +++ b/devicetypes/smartthings/smartsense-garage-door-multi.src/smartsense-garage-door-multi.groovy @@ -86,7 +86,7 @@ metadata { def parse(String description) { log.debug "parse($description)" - def results = null + def results = [:] if (!isSupportedDescription(description) || zigbee.isZoneType19(description)) { // Ignore this in favor of orientation-based state diff --git a/devicetypes/smartthings/smartsense-moisture-sensor.src/smartsense-moisture-sensor.groovy b/devicetypes/smartthings/smartsense-moisture-sensor.src/smartsense-moisture-sensor.groovy index b426cd8..61fefc3 100644 --- a/devicetypes/smartthings/smartsense-moisture-sensor.src/smartsense-moisture-sensor.groovy +++ b/devicetypes/smartthings/smartsense-moisture-sensor.src/smartsense-moisture-sensor.groovy @@ -102,7 +102,7 @@ def parse(String description) { } log.debug "Parse returned $map" - def result = map ? createEvent(map) : null + def result = map ? createEvent(map) : [:] if (description?.startsWith('enroll request')) { List cmds = enrollResponse() diff --git a/devicetypes/smartthings/smartsense-motion-sensor.src/smartsense-motion-sensor.groovy b/devicetypes/smartthings/smartsense-motion-sensor.src/smartsense-motion-sensor.groovy index de99678..3244898 100644 --- a/devicetypes/smartthings/smartsense-motion-sensor.src/smartsense-motion-sensor.groovy +++ b/devicetypes/smartthings/smartsense-motion-sensor.src/smartsense-motion-sensor.groovy @@ -106,7 +106,7 @@ def parse(String description) { } log.debug "Parse returned $map" - def result = map ? createEvent(map) : null + def result = map ? createEvent(map) : [:] if (description?.startsWith('enroll request')) { List cmds = enrollResponse() diff --git a/devicetypes/smartthings/smartsense-motion-temp-sensor.src/smartsense-motion-temp-sensor.groovy b/devicetypes/smartthings/smartsense-motion-temp-sensor.src/smartsense-motion-temp-sensor.groovy index 057ec7e..c3e4e7c 100644 --- a/devicetypes/smartthings/smartsense-motion-temp-sensor.src/smartsense-motion-temp-sensor.groovy +++ b/devicetypes/smartthings/smartsense-motion-temp-sensor.src/smartsense-motion-temp-sensor.groovy @@ -90,7 +90,7 @@ def parse(String description) { } log.debug "Parse returned $map" - def result = map ? createEvent(map) : null + def result = map ? createEvent(map) : [:] if (description?.startsWith('enroll request')) { List cmds = enrollResponse() diff --git a/devicetypes/smartthings/smartsense-motion.src/smartsense-motion.groovy b/devicetypes/smartthings/smartsense-motion.src/smartsense-motion.groovy index bbb1b7d..5cf3743 100644 --- a/devicetypes/smartthings/smartsense-motion.src/smartsense-motion.groovy +++ b/devicetypes/smartthings/smartsense-motion.src/smartsense-motion.groovy @@ -44,7 +44,7 @@ metadata { } def parse(String description) { - def results + def results = [:] if (isZoneType19(description) || !isSupportedDescription(description)) { results = parseBasicMessage(description) } @@ -57,21 +57,25 @@ def parse(String description) { private Map parseBasicMessage(description) { def name = parseName(description) - def value = parseValue(description) - def linkText = getLinkText(device) - def descriptionText = parseDescriptionText(linkText, value, description) - def handlerName = value - def isStateChange = isStateChange(device, name, value) + if (name != null) { + def value = parseValue(description) + def linkText = getLinkText(device) + def descriptionText = parseDescriptionText(linkText, value, description) + def handlerName = value + def isStateChange = isStateChange(device, name, value) - def results = [ - name: name, - value: value, - linkText: linkText, - descriptionText: descriptionText, - handlerName: handlerName, - isStateChange: isStateChange, - displayed: displayed(description, isStateChange) - ] + def results = [ + name : name, + value : value, + linkText : linkText, + descriptionText: descriptionText, + handlerName : handlerName, + isStateChange : isStateChange, + displayed : displayed(description, isStateChange) + ] + } else { + results = [:] + } log.debug "Parse returned $results.descriptionText" return results } diff --git a/devicetypes/smartthings/smartsense-multi-sensor.src/smartsense-multi-sensor.groovy b/devicetypes/smartthings/smartsense-multi-sensor.src/smartsense-multi-sensor.groovy index bc8092d..2c1c2e3 100644 --- a/devicetypes/smartthings/smartsense-multi-sensor.src/smartsense-multi-sensor.groovy +++ b/devicetypes/smartthings/smartsense-multi-sensor.src/smartsense-multi-sensor.groovy @@ -127,7 +127,7 @@ def parse(String description) { map = parseIasMessage(description) } - def result = map ? createEvent(map) : null + def result = map ? createEvent(map) : [:] if (description?.startsWith('enroll request')) { List cmds = enrollResponse() diff --git a/devicetypes/smartthings/smartsense-open-closed-sensor.src/smartsense-open-closed-sensor.groovy b/devicetypes/smartthings/smartsense-open-closed-sensor.src/smartsense-open-closed-sensor.groovy index 8e697f1..8c779d8 100644 --- a/devicetypes/smartthings/smartsense-open-closed-sensor.src/smartsense-open-closed-sensor.groovy +++ b/devicetypes/smartthings/smartsense-open-closed-sensor.src/smartsense-open-closed-sensor.groovy @@ -93,7 +93,7 @@ def parse(String description) { } log.debug "Parse returned $map" - def result = map ? createEvent(map) : null + def result = map ? createEvent(map) : [:] if (description?.startsWith('enroll request')) { List cmds = enrollResponse() diff --git a/devicetypes/smartthings/smartsense-temp-humidity-sensor.src/smartsense-temp-humidity-sensor.groovy b/devicetypes/smartthings/smartsense-temp-humidity-sensor.src/smartsense-temp-humidity-sensor.groovy index 0caa602..e0dc7e2 100644 --- a/devicetypes/smartthings/smartsense-temp-humidity-sensor.src/smartsense-temp-humidity-sensor.groovy +++ b/devicetypes/smartthings/smartsense-temp-humidity-sensor.src/smartsense-temp-humidity-sensor.groovy @@ -84,7 +84,7 @@ def parse(String description) { } log.debug "Parse returned $map" - return map ? createEvent(map) : null + return map ? createEvent(map) : [:] } private Map parseCatchAllMessage(String description) { From 969852602c163f4064736c90ba2635ede50f5994 Mon Sep 17 00:00:00 2001 From: Zach Varberg Date: Mon, 31 Oct 2016 11:23:48 -0500 Subject: [PATCH 05/17] ETI Clear binding table entries to other devices This adds support for ETI devices which have a firmware bug in which the binding table is not properly cleared on network leave. So the DTH will on configure (and refresh) look at the binding table and remove any entries to not the current hub. This resolves: https://smartthings.atlassian.net/browse/DVCSMP-2175 --- ...zigbee-white-color-temperature-bulb.groovy | 104 ++++++++++++++++-- 1 file changed, 92 insertions(+), 12 deletions(-) diff --git a/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy b/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy index 15a83f6..d7db5bd 100644 --- a/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy +++ b/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy @@ -83,24 +83,105 @@ def parse(String description) { } } else { - def cluster = zigbee.parse(description) + Map bindingTable = parseBindingTableResponse(description) + if (bindingTable) { + List cmds = [] + bindingTable.table_entries.inject(cmds) { acc, entry -> + // The binding entry is not for our hub and should be deleted + if (entry["dstAddr"] != zigbeeEui) { + acc.addAll(removeBinding(entry.clusterId, entry.srcAddr, entry.srcEndpoint, entry.dstAddr, entry.dstEndpoint)) + } + acc + } + // There are more entries that we haven't examined yet + if (bindingTable.numTableEntries > bindingTable.startIndex + bindingTable.numEntriesReturned) { + def startPos + if (cmds) { + log.warn "Removing binding entries for other devices: $cmds" + // Since we are removing some entries, we should start in the same spot as we just read since values + // will fill in the newly vacated spots + startPos = bindingTable.startIndex + } else { + // Since we aren't removing anything we move forward to the next set of table entries + startPos = bindingTable.startIndex + bindingTable.numEntriesReturned + } + cmds.addAll(requestBindingTable(startPos)) + } + sendHubCommand(cmds.collect { it -> + new physicalgraph.device.HubAction(it) + }, 2000) + } else { + def cluster = zigbee.parse(description) - if (cluster && cluster.clusterId == 0x0006 && cluster.command == 0x07) { - if (cluster.data[0] == 0x00) { - log.debug "ON/OFF REPORTING CONFIG RESPONSE: " + cluster - sendEvent(name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) + if (cluster && cluster.clusterId == 0x0006 && cluster.command == 0x07) { + if (cluster.data[0] == 0x00) { + log.debug "ON/OFF REPORTING CONFIG RESPONSE: " + cluster + sendEvent(name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) + } + else { + log.warn "ON/OFF REPORTING CONFIG FAILED- error code:${cluster.data[0]}" + } } else { - log.warn "ON/OFF REPORTING CONFIG FAILED- error code:${cluster.data[0]}" + log.warn "DID NOT PARSE MESSAGE for description : $description" + log.debug "${cluster}" } } - else { - log.warn "DID NOT PARSE MESSAGE for description : $description" - log.debug "${cluster}" - } } } +def parseBindingTableResponse(description) { + Map descMap = zigbee.parseDescriptionAsMap(description) + if (descMap["clusterInt"] == 0x8033) { + def header_field_lengths = ["transactionSeqNo": 1, "status": 1, "numTableEntries": 1, "startIndex": 1, "numEntriesReturned": 1] + def field_values = [:] + def data = descMap["data"] + header_field_lengths.each { k, v -> + field_values[k] = Integer.parseInt(data.take(v).join(""), 16); + data = data.drop(v); + } + + List table = [] + if (field_values.numEntriesReturned) { + def table_entry_lengths = ["srcAddr": 8, "srcEndpoint": 1, "clusterId": 2, "dstAddrMode": 1] + for (def i : 0..(field_values.numEntriesReturned - 1)) { + def entryMap = [:] + table_entry_lengths.each { k, v -> + def val = data.take(v).reverse().join("") + entryMap[k] = val.length() < 8 ? Integer.parseInt(val, 16) : val + data = data.drop(v) + } + + switch (entryMap.dstAddrMode) { + case 0x01: + entryMap["dstAddr"] = data.take(2).reverse().join("") + data = data.drop(2) + break + case 0x03: + entryMap["dstAddr"] = data.take(8).reverse().join("") + data = data.drop(8) + entryMap["dstEndpoint"] = Integer.parseInt(data.take(1).join(""), 16) + data = data.drop(1) + break + } + table << entryMap + } + } + field_values["table_entries"] = table + return field_values + } + return [:] +} + +def requestBindingTable(startPos=0) { + return ["zdo mgmt-bind 0x${zigbee.deviceNetworkId} $startPos"] +} + +def removeBinding(cluster, srcAddr, srcEndpoint, destAddr, destEndpoint) { + return ["zdo unbind unicast 0x${zigbee.deviceNetworkId} {${srcAddr}} $srcEndpoint $cluster {${destAddr}} $destEndpoint"] +} + + def off() { zigbee.off() } @@ -130,8 +211,7 @@ def configure() { // enrolls with default periodic reporting until newer 5 min interval is confirmed sendEvent(name: "checkInterval", value: 3 * 10 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) - // OnOff minReportTime 0 seconds, maxReportTime 5 min. Reporting interval if no activity - refresh() + refresh() + requestBindingTable(0) + ["delay 2000"] } def setColorTemperature(value) { From bd1ace96ded912fa4f34699735f92e016a6a9410 Mon Sep 17 00:00:00 2001 From: Juan Pablo Risso Date: Fri, 4 Nov 2016 16:41:41 -0400 Subject: [PATCH 06/17] DVCSMP-2178 - Add thermostats to Logitech Harmony (#1408) --- .../logitech-harmony-connect.groovy | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/smartapps/smartthings/logitech-harmony-connect.src/logitech-harmony-connect.groovy b/smartapps/smartthings/logitech-harmony-connect.src/logitech-harmony-connect.groovy index 3cf64e1..9df77ca 100644 --- a/smartapps/smartthings/logitech-harmony-connect.src/logitech-harmony-connect.groovy +++ b/smartapps/smartthings/logitech-harmony-connect.src/logitech-harmony-connect.groovy @@ -24,6 +24,12 @@ * switches | switch | on, off | on, off * motionSensors | motion | | active, inactive * contactSensors | contact | | open, closed + * thermostat | thermostat | setHeatingSetpoint, | temperature, heatingSetpoint + * | | setCoolingSetpoint(number) | coolingSetpoint, thermostatSetpoint + * | | off, heat, emergencyHeat | thermostatMode — ["emergency heat", "auto", "cool", "off", "heat"] + * | | cool, setThermostatMode | thermostatFanMode — ["auto", "on", "circulate"] + * | | fanOn, fanAuto, fanCirculate| thermostatOperatingState — ["cooling", "heating", "pending heat", + * | | setThermostatFanMode, auto | "fan only", "vent economizer", "pending cool", "idle"] * presenceSensors | presence | | present, 'not present' * temperatureSensors | temperature | | * accelerationSensors | acceleration | | active, inactive @@ -58,6 +64,7 @@ preferences(oauthPage: "deviceAuthorization") { input "switches", "capability.switch", title: "Which Switches?", multiple: true, required: false input "motionSensors", "capability.motionSensor", title: "Which Motion Sensors?", multiple: true, required: false input "contactSensors", "capability.contactSensor", title: "Which Contact Sensors?", multiple: true, required: false + input "thermostats", "capability.thermostat", title: "Which Thermostats?", multiple: true, required: false input "presenceSensors", "capability.presenceSensor", title: "Which Presence Sensors?", multiple: true, required: false input "temperatureSensors", "capability.temperatureMeasurement", title: "Which Temperature Sensors?", multiple: true, required: false input "accelerationSensors", "capability.accelerationSensor", title: "Which Vibration Sensors?", multiple: true, required: false @@ -936,7 +943,7 @@ def deleteHarmony() { } private getAllDevices() { - ([] + switches + motionSensors + contactSensors + presenceSensors + temperatureSensors + accelerationSensors + waterSensors + lightSensors + humiditySensors + alarms + locks)?.findAll()?.unique { it.id } + ([] + switches + motionSensors + contactSensors + thermostats + presenceSensors + temperatureSensors + accelerationSensors + waterSensors + lightSensors + humiditySensors + alarms + locks)?.findAll()?.unique { it.id } } private deviceItem(device) { From b6790729c6b6a6cbbf8cdee6be3123f089b41239 Mon Sep 17 00:00:00 2001 From: Parijat Das Date: Mon, 7 Nov 2016 18:37:46 +0530 Subject: [PATCH 07/17] Added fingerprint of Leviton Universal Dimmer with health check already implemented --- .../smartthings/zwave-dimmer-switch-generic.src/README.md | 8 +++++--- .../zwave-dimmer-switch-generic.groovy | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/devicetypes/smartthings/zwave-dimmer-switch-generic.src/README.md b/devicetypes/smartthings/zwave-dimmer-switch-generic.src/README.md index 5bbc091..f5f4fef 100644 --- a/devicetypes/smartthings/zwave-dimmer-switch-generic.src/README.md +++ b/devicetypes/smartthings/zwave-dimmer-switch-generic.src/README.md @@ -4,7 +4,8 @@ Works with: -* [Leviton Plug-in Lamp Dimmer Module (DZPD3-1LW)](http://www.leviton.com/OA_HTML/ProductDetail.jsp?partnumber=DZPD3-1LW) +* [Leviton Plug-in Lamp Dimmer Module (DZPD3-1LW)](https://www.smartthings.com/works-with-smartthings/outlets/leviton-plug-in-lamp-dimmer-module) +* [Leviton Universal Dimmer (DZMX1-LZ)](https://www.smartthings.com/works-with-smartthings/switches-and-dimmers/leviton-universal-dimmer) ## Table of contents @@ -24,7 +25,7 @@ Works with: ## Device Health -A Category C5 Leviton Plug-in Lamp Dimmer Module (DZPA1-1LW) (Z-Wave) polled by the hub. +Leviton Plug-in Lamp Dimmer Module (DZPA1-1LW) (Z-wave) and Leviton Universal Dimmer (DZMX1-LZ) (Z-Wave) are polled by the hub. As of hubCore version 0.14.38 the hub sends up reports every 15 minutes regardless of whether the state changed. Device-Watch allows 2 check-in misses from device plus some lag time. So Check-in interval = (2*15 + 2)mins = 32 mins. Not to mention after going OFFLINE when the device is plugged back in, it might take a considerable amount of time for @@ -36,4 +37,5 @@ it is not polled for 5 minutes by the hub. This can delay up the process of bein If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the device is out of range. Pairing needs to be tried again by placing the device closer to the hub. Instructions related to pairing, resetting and removing the device from SmartThings can be found in the following link: -* [Leviton Plug-in Lamp Dimmer Module (DZPD3-1LW) Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/206171053-How-to-connect-Leviton-Z-Wave-devices) \ No newline at end of file +* [Leviton Plug-in Lamp Dimmer Module (DZPD3-1LW) Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/206171053-How-to-connect-Leviton-Z-Wave-devices) +* [Leviton Universal Dimmer (DZMX1-LZ) Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/206171053-How-to-connect-Leviton-Z-Wave-devices) \ No newline at end of file diff --git a/devicetypes/smartthings/zwave-dimmer-switch-generic.src/zwave-dimmer-switch-generic.groovy b/devicetypes/smartthings/zwave-dimmer-switch-generic.src/zwave-dimmer-switch-generic.groovy index bd1668b..43a65b8 100644 --- a/devicetypes/smartthings/zwave-dimmer-switch-generic.src/zwave-dimmer-switch-generic.groovy +++ b/devicetypes/smartthings/zwave-dimmer-switch-generic.src/zwave-dimmer-switch-generic.groovy @@ -23,6 +23,7 @@ metadata { fingerprint inClusters: "0x26", deviceJoinName: "Z-Wave Dimmer" fingerprint mfr:"001D", prod:"1902", deviceJoinName: "Z-Wave Dimmer" + fingerprint mfr:"001D", prod:"1B03", model:"0334", deviceJoinName: "Leviton Universal Dimmer" } simulator { From c0bb0554d89b60384227bcc4ffbcbd6394410927 Mon Sep 17 00:00:00 2001 From: Parijat Das Date: Mon, 7 Nov 2016 19:02:25 +0530 Subject: [PATCH 08/17] Added fingerprint of Leviton Outlet and Leviton Switch with health check already implemented and modified readme file accordingly --- .../smartthings/zwave-switch-generic.src/README.md | 14 +++++++++----- .../zwave-switch-generic.groovy | 2 ++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/devicetypes/smartthings/zwave-switch-generic.src/README.md b/devicetypes/smartthings/zwave-switch-generic.src/README.md index 72ba38d..765bcd1 100644 --- a/devicetypes/smartthings/zwave-switch-generic.src/README.md +++ b/devicetypes/smartthings/zwave-switch-generic.src/README.md @@ -4,8 +4,10 @@ Works with: -* [Leviton Appliance Module (DZPA1-1LW)](https://support.smartthings.com/hc/en-us/articles/205881176-Leviton-Appliance-Module-DZPA1-1LW-) -* [GE Plug-In Outdoor Smart Switch (GE 12720) (Z-Wave)](https://support.smartthings.com/hc/en-us/articles/200903080-GE-Plug-In-Outdoor-Smart-Switch-GE-12720-Z-Wave-) +* [Leviton Appliance Module (DZPA1-1LW)](https://www.smartthings.com/works-with-smartthings/outlets/leviton-appliance-module) +* [GE Plug-In Outdoor Smart Switch (GE 12720) (Z-Wave)](https://www.smartthings.com/works-with-smartthings/outlets/ge-plug-in-outdoor-smart-switch) +* [Leviton Outlet (DZR15-1LZ)](https://www.smartthings.com/works-with-smartthings/outlets/leviton-outlet) +* [Leviton Switch (DZS15-1LZ)](https://www.smartthings.com/works-with-smartthings/switches-and-dimmers/leviton-switch) ## Table of contents @@ -23,7 +25,7 @@ Works with: ## Device Health -A Category C5 Leviton Appliance Module (DZPA1-1LW) and GE Plug-In Outdoor Smart Switch (GE 12720) (Z-Wave) polled by the hub. +Leviton Appliance Module (DZPA1-1LW), GE Plug-In Outdoor Smart Switch (GE 12720), Leviton Outlet (DZR15-1LZ) and Leviton Switch (DZS15-1LZ) (Z-Wave) are polled by the hub. As of hubCore version 0.14.38 the hub sends up reports every 15 minutes regardless of whether the state changed. Device-Watch allows 2 check-in misses from device plus some lag time. So Check-in interval = (2*15 + 2)mins = 32 mins. Not to mention after going OFFLINE when the device is plugged back in, it might take a considerable amount of time for @@ -35,5 +37,7 @@ it is not polled for 5 minutes by the hub. This can delay up the process of bein If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the device is out of range. Pairing needs to be tried again by placing the device closer to the hub. Instructions related to pairing, resetting and removing the device from SmartThings can be found in the following link: -* [Leviton Appliance Module (DZPA1-1LW) Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/205881176-Leviton-Appliance-Module-DZPA1-1LW-) -* [GE Plug-In Outdoor Smart Switch (GE 12720) (Z-Wave) Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/200903080-GE-Plug-In-Outdoor-Smart-Switch-GE-12720-Z-Wave-) \ No newline at end of file +* [Leviton Appliance Module (DZPA1-1LW) Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/206171053-How-to-connect-Leviton-Z-Wave-devices) +* [GE Plug-In Outdoor Smart Switch (GE 12720) (Z-Wave) Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/200903080-GE-Plug-In-Outdoor-Smart-Switch-GE-12720-Z-Wave-) +* [Leviton Outlet (DZR15-1LZ) Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/206171053-How-to-connect-Leviton-Z-Wave-devices) +* [Leviton Switch (DZS15-1LZ) Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/206171053-How-to-connect-Leviton-Z-Wave-devices) \ No newline at end of file diff --git a/devicetypes/smartthings/zwave-switch-generic.src/zwave-switch-generic.groovy b/devicetypes/smartthings/zwave-switch-generic.src/zwave-switch-generic.groovy index 411440f..01ce695 100644 --- a/devicetypes/smartthings/zwave-switch-generic.src/zwave-switch-generic.groovy +++ b/devicetypes/smartthings/zwave-switch-generic.src/zwave-switch-generic.groovy @@ -23,6 +23,8 @@ metadata { fingerprint inClusters: "0x25", deviceJoinName: "Z-Wave Switch" fingerprint mfr:"001D", prod:"1A02", model:"0334", deviceJoinName: "Leviton Appliance Module" fingerprint mfr:"0063", prod:"4F50", model:"3031", deviceJoinName: "GE Plug-in Outdoor Switch" + fingerprint mfr:"001D", prod:"1D04", model:"0334", deviceJoinName: "Leviton Outlet" + fingerprint mfr:"001D", prod:"1C02", model:"0334", deviceJoinName: "Leviton Switch" } // simulator metadata From c1d520a578365bd351f7e9d4158a1d00832e4706 Mon Sep 17 00:00:00 2001 From: "sushant.k1" Date: Mon, 7 Nov 2016 18:13:54 +0530 Subject: [PATCH 09/17] Added Health Check Implementation for following Osram RT5/6 Tunable White --- .../README.md | 13 ++++++++----- .../zigbee-white-color-temperature-bulb.groovy | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/README.md b/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/README.md index 3bd9229..779d119 100644 --- a/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/README.md +++ b/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/README.md @@ -1,10 +1,11 @@ -# OSRAM Lightify Tunable 60 White +# ZigBee White Color Temperature Bulb Works with: * [OSRAM Lightify Tunable 60 White](http://www.osram.com/osram_com/tools-and-services/tools/lightify---smart-connected-light/lightify-for-home---what-is-light-to-you/lightify-products/lightify-classic-a60-tunable-white/index.jsp) +* [OSRAM LIGHTIFY RT5/6 Tunable White](https://www.smartthings.com/works-with-smartthings/light-bulbs/osram-lightify-rt56-tunable-white) ## Table of contents @@ -24,14 +25,16 @@ Works with: ## Device Health -A Category C1 OSRAM Lightify Tunable 60 White with maxReportTime of 5 mins. -Check-in interval is double the value of maxReportTime. +Zigbee Bulb with maxReportTime of 5 mins. +Check-in interval is double the value of maxReportTime. This gives the device twice the amount of time to respond before it is marked as offline. -Check-in interval = 12 mins +Enrolls with default periodic reporting until newer 5 min interval is confirmed +It then enrolls the device with updated checkInterval i.e. 12 mins ## Troubleshooting If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the device is out of range. Pairing needs to be tried again by placing the device closer to the hub. Other troubleshooting tips are listed as follows: -* [Troubleshooting:](https://support.smartthings.com/hc/en-us/articles/204576454-OSRAM-LIGHTIFY-Tunable-White-60-Bulb) +* [OSRAM Lightify Tunable 60 White Troubleshooting](https://support.smartthings.com/hc/en-us/articles/204576454-OSRAM-LIGHTIFY-Tunable-White-60-Bulb) +* [OSRAM LIGHTIFY RT5/6 Tunable White Troubleshooting](https://support.smartthings.com/hc/en-us/articles/214191863-How-to-connect-OSRAM-LIGHTIFY-Bulbs) \ No newline at end of file diff --git a/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy b/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy index 15a83f6..fb06954 100644 --- a/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy +++ b/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy @@ -33,7 +33,7 @@ metadata { fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300", outClusters: "0019" fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 0B04", outClusters: "0019" fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 0B04, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "LIGHTIFY BR Tunable White", deviceJoinName: "OSRAM LIGHTIFY LED Flood BR30 Tunable White" - fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 0B04, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "LIGHTIFY RT Tunable White", deviceJoinName: "OSRAM LIGHTIFY LED Recessed Kit RT 5/6 Tunable White" + fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 0B04, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "LIGHTIFY RT Tunable White", deviceJoinName: "OSRAM LIGHTIFY RT5/6 Tunable White" fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 0B04, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "Classic A60 TW", deviceJoinName: "OSRAM LIGHTIFY LED Tunable White 60W" fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 0B04, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "LIGHTIFY A19 Tunable White", deviceJoinName: "OSRAM LIGHTIFY LED Tunable White 60W" fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 0B04, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "Classic B40 TW - LIGHTIFY", deviceJoinName: "OSRAM LIGHTIFY Classic B40 Tunable White" From 8ca20ce87e9dc5fb94a21392c70cef2ce305abf2 Mon Sep 17 00:00:00 2001 From: "sushant.k1" Date: Sun, 6 Nov 2016 20:18:03 +0530 Subject: [PATCH 10/17] Added Health Check Implementation for following WeMo LED Bulb --- devicetypes/smartthings/zigbee-dimmer.src/README.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/devicetypes/smartthings/zigbee-dimmer.src/README.md b/devicetypes/smartthings/zigbee-dimmer.src/README.md index 35997a5..61f3ed0 100644 --- a/devicetypes/smartthings/zigbee-dimmer.src/README.md +++ b/devicetypes/smartthings/zigbee-dimmer.src/README.md @@ -1,10 +1,11 @@ -# OSRAM Lightify LED On/Off/Dim +# Zigbee Dimmer Works with: * [OSRAM Lightify LED On/Off/Dim](https://shop.smartthings.com/#!/products/osram-led-smart-bulb-on-off-dim) +* [WeMo LED Bulb](https://support.smartthings.com/hc/en-us/articles/204259040-Belkin-WeMo-LED-Bulb-F7C033-) ## Table of contents @@ -23,14 +24,16 @@ Works with: ## Device Health -A Category C1 Zigbee dimmer with maxReportTime of 5 mins. -Check-in interval is double the value of maxReportTime. +A Zigbee dimmer with maxReportTime of 5 mins. +Check-in interval is double the value of maxReportTime. This gives the device twice the amount of time to respond before it is marked as offline. -Check-in interval = 12 mins +Enrolls with default periodic reporting until newer 5 min interval is confirmed +It then enrolls the device with updated checkInterval i.e. 12 mins ## Troubleshooting If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the device is out of range. Pairing needs to be tried again by placing the device closer to the hub. Other troubleshooting tips are listed as follows: -* [Troubleshooting:](https://support.smartthings.com/hc/en-us/articles/207191763-OSRAM-LIGHTIFY-LED-Smart-Connected-Light-A19-On-Off-Dim) +* [OSRAM Lightify LED On/Off/Dim Troubleshooting:](https://support.smartthings.com/hc/en-us/articles/207191763-OSRAM-LIGHTIFY-LED-Smart-Connected-Light-A19-On-Off-Dim) +* [WeMo LED Bulb Troubleshooting:](https://support.smartthings.com/hc/en-us/articles/204259040-Belkin-WeMo-LED-Bulb-F7C033-) From af8590ab01fc89f410a6694d388911df58ff41fa Mon Sep 17 00:00:00 2001 From: Tom Manley Date: Tue, 8 Nov 2016 14:48:42 -0600 Subject: [PATCH 11/17] GE Link: fixed problem creating level events The bug causing level events not to be created happens when the setLevel command runs in the cloud but the Device Type Handler is running locally in the hub. Since state is not synced from the cloud to the hub the `state.trigger` value was never set to `"setLevel"` on the hub which means no level events would be created. The change is to not be reliant on state. Instead we just don't create level events if the level is 0 since there is no legitimate way for the level to be 0. https://smartthings.atlassian.net/browse/DVCSMP-2219 --- devicetypes/smartthings/ge-link-bulb.src/ge-link-bulb.groovy | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/devicetypes/smartthings/ge-link-bulb.src/ge-link-bulb.groovy b/devicetypes/smartthings/ge-link-bulb.src/ge-link-bulb.groovy index 3e62197..d806b69 100644 --- a/devicetypes/smartthings/ge-link-bulb.src/ge-link-bulb.groovy +++ b/devicetypes/smartthings/ge-link-bulb.src/ge-link-bulb.groovy @@ -87,7 +87,7 @@ metadata { def parse(String description) { def resultMap = zigbee.getEvent(description) if (resultMap) { - if ((resultMap.name == "level" && state.trigger == "setLevel") || resultMap.name != "level") { //doing this to account for weird level reporting bug with GE Link Bulbs + if (resultMap.name != "level" || resultMap.value != 0) { // Ignore level reports of 0 sent when bulb turns off sendEvent(resultMap) } } @@ -188,12 +188,10 @@ def updated() { } def on() { - state.trigger = "on/off" zigbee.on() } def off() { - state.trigger = "on/off" zigbee.off() } @@ -206,7 +204,6 @@ def refresh() { } def setLevel(value) { - state.trigger = "setLevel" def cmd def delayForRefresh = 500 if (dimRate && (state?.rate != null)) { From bae79192c5d8cd82990c276b5052736ddf398371 Mon Sep 17 00:00:00 2001 From: jackchi Date: Wed, 9 Nov 2016 13:49:56 -0800 Subject: [PATCH 12/17] [CHF-459] Health documentation include DTH execution location and expected checkInterval; reduced checkInterval --- devicetypes/smartthings/cree-bulb.src/README.md | 8 +++++--- .../smartthings/cree-bulb.src/cree-bulb.groovy | 2 +- devicetypes/smartthings/dimmer-switch.src/README.md | 4 +++- .../nyce-open-closed-sensor.src/README.md | 8 ++++++-- .../smartthings/smartpower-outlet.src/README.md | 11 ++++++----- .../smartpower-outlet.src/smartpower-outlet.groovy | 4 ++-- .../smartsense-moisture-sensor.src/README.md | 11 ++++++----- .../smartsense-moisture-sensor.groovy | 4 ++-- .../smartsense-motion-sensor.src/README.md | 12 +++++++----- .../smartsense-motion-sensor.groovy | 4 ++-- .../smartsense-multi-sensor.src/README.md | 11 ++++++----- .../smartsense-multi-sensor.groovy | 4 ++-- .../smartsense-open-closed-sensor.src/README.md | 11 ++++++----- .../smartsense-open-closed-sensor.groovy | 4 ++-- .../smartsense-temp-humidity-sensor.src/README.md | 11 ++++++----- .../smartsense-temp-humidity-sensor.groovy | 4 ++-- .../tyco-door-window-sensor.src/README.md | 7 ++++--- .../smartthings/zigbee-dimmer-power.src/README.md | 12 ++++++------ .../zigbee-dimmer-power.groovy | 4 ++-- devicetypes/smartthings/zigbee-dimmer.src/README.md | 12 ++++++------ .../zigbee-dimmer.src/zigbee-dimmer.groovy | 4 ++-- .../smartthings/zigbee-rgbw-bulb.src/README.md | 9 ++++----- .../zigbee-rgbw-bulb.src/zigbee-rgbw-bulb.groovy | 4 ++-- .../README.md | 11 +++++------ .../zigbee-white-color-temperature-bulb.groovy | 4 ++-- .../zwave-dimmer-switch-generic.src/README.md | 6 ++++-- .../smartthings/zwave-switch-generic.src/README.md | 4 +++- devicetypes/smartthings/zwave-switch.src/README.md | 2 ++ 28 files changed, 106 insertions(+), 86 deletions(-) diff --git a/devicetypes/smartthings/cree-bulb.src/README.md b/devicetypes/smartthings/cree-bulb.src/README.md index 67f9699..2ceda3b 100644 --- a/devicetypes/smartthings/cree-bulb.src/README.md +++ b/devicetypes/smartthings/cree-bulb.src/README.md @@ -1,6 +1,6 @@ # Connected Cree LED Bulb - +Cloud Execution Works with: @@ -23,8 +23,10 @@ Works with: ## Device Health -A Category C6 Connected Cree LED Bulb with maxReportTime of 5 mins. -Check-in interval = 12 mins +Connected Cree LED Bulb with cloud polling it every __5min__ +SmartThings platform will ping the device after `checkInterval` seconds of inactivity in last attempt to reach the device before marking it `OFFLINE` + +* __12min__ checkInterval ## Troubleshooting diff --git a/devicetypes/smartthings/cree-bulb.src/cree-bulb.groovy b/devicetypes/smartthings/cree-bulb.src/cree-bulb.groovy index 69d26f7..26fa1b9 100644 --- a/devicetypes/smartthings/cree-bulb.src/cree-bulb.groovy +++ b/devicetypes/smartthings/cree-bulb.src/cree-bulb.groovy @@ -105,7 +105,7 @@ def healthPoll() { def configure() { unschedule() runEvery5Minutes("healthPoll") - // Device-Watch allows 2 check-in misses from device + // Device-Watch allows 2 check-in misses from device + ping sendEvent(name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) zigbee.onOffRefresh() + zigbee.levelRefresh() } diff --git a/devicetypes/smartthings/dimmer-switch.src/README.md b/devicetypes/smartthings/dimmer-switch.src/README.md index 3c2cdaf..71a27b6 100644 --- a/devicetypes/smartthings/dimmer-switch.src/README.md +++ b/devicetypes/smartthings/dimmer-switch.src/README.md @@ -1,6 +1,6 @@ # Z-wave Dimmer Switch - +Local Execution on V2 Hubs Works with: @@ -34,6 +34,8 @@ Not to mention after going OFFLINE when the device is plugged back in, it might the device to appear as ONLINE again. This is because if this listening device does not respond to two poll requests in a row, it is not polled for 5 minutes by the hub. This can delay up the process of being marked ONLINE by quite some time. +* __32min__ checkInterval + ## Troubleshooting If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the device is out of range. diff --git a/devicetypes/smartthings/nyce-open-closed-sensor.src/README.md b/devicetypes/smartthings/nyce-open-closed-sensor.src/README.md index 64624e3..257198f 100644 --- a/devicetypes/smartthings/nyce-open-closed-sensor.src/README.md +++ b/devicetypes/smartthings/nyce-open-closed-sensor.src/README.md @@ -1,6 +1,6 @@ # Nyce Door/Window Sensor (Open/Close Sensor) - +Cloud Execution Works with: @@ -23,7 +23,11 @@ Works with: ## Device Health -A Category C2 Nyce Door/Window sensor that has 12min check-in interval +Nyce Door/Window sensor with reporting interval of 5 min. +SmartThings platform will ping the device after `checkInterval` seconds of inactivity in last attempt to reach the device before marking it `OFFLINE` + +* __12min__ checkInterval + ## Battery Specification diff --git a/devicetypes/smartthings/smartpower-outlet.src/README.md b/devicetypes/smartthings/smartpower-outlet.src/README.md index 3a5fddb..8eed484 100644 --- a/devicetypes/smartthings/smartpower-outlet.src/README.md +++ b/devicetypes/smartthings/smartpower-outlet.src/README.md @@ -1,6 +1,6 @@ # SmartPower Outlet - +Local Execution on V2 Hubs Works with: @@ -23,10 +23,11 @@ Works with: ## Device Health -A Category C1 smart power outlet with maxReportTime of 5 mins. -Check-in interval is double the value of maxReportTime. -This gives the device twice the amount of time to respond before it is marked as offline. -Check-in interval = 12 mins +SmartPower outlet with reporting interval of 5 mins +SmartThings platform will ping the device after `checkInterval` seconds of inactivity in last attempt to reach the device before marking it `OFFLINE` + +* V1, TV, HubV2 AppEngine < 1.5.1 - __21min__ checkInterval +* HubV2 AppEngine 1.5.1 - __12min__ checkInterval ## Troubleshooting diff --git a/devicetypes/smartthings/smartpower-outlet.src/smartpower-outlet.groovy b/devicetypes/smartthings/smartpower-outlet.src/smartpower-outlet.groovy index 192f75a..03e475c 100644 --- a/devicetypes/smartthings/smartpower-outlet.src/smartpower-outlet.groovy +++ b/devicetypes/smartthings/smartpower-outlet.src/smartpower-outlet.groovy @@ -145,9 +145,9 @@ def refresh() { } def configure() { - // Device-Watch allows 3 check-in misses from device (plus 1 min lag time) + // Device-Watch allows 2 check-in misses from device + ping (plus 1 min lag time) // enrolls with default periodic reporting until newer 5 min interval is confirmed - sendEvent(name: "checkInterval", value: 3 * 10 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) + sendEvent(name: "checkInterval", value: 2 * 10 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) // OnOff minReportTime 0 seconds, maxReportTime 5 min. Reporting interval if no activity refresh() + zigbee.onOffConfig(0, 300) + powerConfig() diff --git a/devicetypes/smartthings/smartsense-moisture-sensor.src/README.md b/devicetypes/smartthings/smartsense-moisture-sensor.src/README.md index 401a7e5..9f5998e 100644 --- a/devicetypes/smartthings/smartsense-moisture-sensor.src/README.md +++ b/devicetypes/smartthings/smartsense-moisture-sensor.src/README.md @@ -1,6 +1,6 @@ # Smartsense Moisture Sensor - +Local Execution on V2 Hubs Works with: @@ -23,10 +23,11 @@ Works with: ## Device Health -A Category C2 moisture sensor with maxReportTime of 5 mins. -Check-in interval is double the value of maxReportTime. -This gives the device twice the amount of time to respond before it is marked as offline. -Check-in interval = 12 mins +SmartSense Moisture sensor with reporting interval of 5 mins. +SmartThings platform will ping the device after `checkInterval` seconds of inactivity in last attempt to reach the device before marking it `OFFLINE` + +* V1, TV, HubV2 AppEngine < 1.5.1 - __121min__ checkInterval +* HubV2 AppEngine 1.5.1 - __12min__ checkInterval ## Battery Specification diff --git a/devicetypes/smartthings/smartsense-moisture-sensor.src/smartsense-moisture-sensor.groovy b/devicetypes/smartthings/smartsense-moisture-sensor.src/smartsense-moisture-sensor.groovy index 61fefc3..535359a 100644 --- a/devicetypes/smartthings/smartsense-moisture-sensor.src/smartsense-moisture-sensor.groovy +++ b/devicetypes/smartthings/smartsense-moisture-sensor.src/smartsense-moisture-sensor.groovy @@ -293,9 +293,9 @@ def refresh() { } def configure() { - // Device-Watch allows 3 check-in misses from device (plus 1 min lag time) + // Device-Watch allows 2 check-in misses from device + ping (plus 1 min lag time) // enrolls with default periodic reporting until newer 5 min interval is confirmed - sendEvent(name: "checkInterval", value: 3 * 60 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) + sendEvent(name: "checkInterval", value: 2 * 60 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) // temperature minReportTime 30 seconds, maxReportTime 5 min. Reporting interval if no activity // battery minReport 30 seconds, maxReportTime 6 hrs by default diff --git a/devicetypes/smartthings/smartsense-motion-sensor.src/README.md b/devicetypes/smartthings/smartsense-motion-sensor.src/README.md index adcac31..f01d062 100644 --- a/devicetypes/smartthings/smartsense-motion-sensor.src/README.md +++ b/devicetypes/smartthings/smartsense-motion-sensor.src/README.md @@ -1,6 +1,6 @@ # Smartsense Motion Sensor - +Local Execution on V2 Hubs Works with: @@ -22,10 +22,12 @@ Works with: ## Device Health -A Category C2 motion sensor with maxReportTime of 5 mins. -Check-in interval is double the value of maxReportTime. -This gives the device twice the amount of time to respond before it is marked as offline. -Check-in interval = 12 mins +SmartSense Motion sensor with reporting interval of 5 mins. +SmartThings platform will ping the device after `checkInterval` seconds of inactivity in last attempt to reach the device before marking it `OFFLINE` + +* V1, TV, HubV2 AppEngine < 1.5.1 - __121min__ checkInterval +* HubV2 AppEngine 1.5.1 - __12min__ checkInterval + ## Battery Specification diff --git a/devicetypes/smartthings/smartsense-motion-sensor.src/smartsense-motion-sensor.groovy b/devicetypes/smartthings/smartsense-motion-sensor.src/smartsense-motion-sensor.groovy index 3244898..f2f653b 100644 --- a/devicetypes/smartthings/smartsense-motion-sensor.src/smartsense-motion-sensor.groovy +++ b/devicetypes/smartthings/smartsense-motion-sensor.src/smartsense-motion-sensor.groovy @@ -306,9 +306,9 @@ def refresh() { } def configure() { - // Device-Watch allows 3 check-in misses from device (plus 1 min lag time) + // Device-Watch allows 2 check-in misses from device + ping (plus 1 min lag time) // enrolls with default periodic reporting until newer 5 min interval is confirmed - sendEvent(name: "checkInterval", value: 3 * 60 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) + sendEvent(name: "checkInterval", value: 2 * 60 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) // temperature minReportTime 30 seconds, maxReportTime 5 min. Reporting interval if no activity // battery minReport 30 seconds, maxReportTime 6 hrs by default diff --git a/devicetypes/smartthings/smartsense-multi-sensor.src/README.md b/devicetypes/smartthings/smartsense-multi-sensor.src/README.md index 591475c..27523db 100644 --- a/devicetypes/smartthings/smartsense-multi-sensor.src/README.md +++ b/devicetypes/smartthings/smartsense-multi-sensor.src/README.md @@ -1,6 +1,6 @@ # Smartsense Multi Sensor - +Local Execution on V2 Hubs Works with: @@ -26,10 +26,11 @@ Works with: ## Device Health -A Category C2 multi sensor with maxReportTime of 5 mins. -Check-in interval is double the value of maxReportTime. -This gives the device twice the amount of time to respond before it is marked as offline. -Check-in interval = 12 mins +SmartSense Multi sensor with reporting interval of 5 mins. +SmartThings platform will ping the device after `checkInterval` seconds of inactivity in last attempt to reach the device before marking it `OFFLINE` + +* V1, TV, HubV2 AppEngine < 1.5.1 - __121min__ checkInterval +* HubV2 AppEngine 1.5.1 - __12min__ checkInterval ## Battery Specification diff --git a/devicetypes/smartthings/smartsense-multi-sensor.src/smartsense-multi-sensor.groovy b/devicetypes/smartthings/smartsense-multi-sensor.src/smartsense-multi-sensor.groovy index 2c1c2e3..1183fe2 100644 --- a/devicetypes/smartthings/smartsense-multi-sensor.src/smartsense-multi-sensor.groovy +++ b/devicetypes/smartthings/smartsense-multi-sensor.src/smartsense-multi-sensor.groovy @@ -400,9 +400,9 @@ def refresh() { } def configure() { - // Device-Watch allows 3 check-in misses from device (plus 1 min lag time) + // Device-Watch allows 2 check-in misses from device + ping (plus 1 min lag time) // enrolls with default periodic reporting until newer 5 min interval is confirmed - sendEvent(name: "checkInterval", value: 3 * 60 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) + sendEvent(name: "checkInterval", value: 2 * 60 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) log.debug "Configuring Reporting" diff --git a/devicetypes/smartthings/smartsense-open-closed-sensor.src/README.md b/devicetypes/smartthings/smartsense-open-closed-sensor.src/README.md index c9454c5..a8562d4 100644 --- a/devicetypes/smartthings/smartsense-open-closed-sensor.src/README.md +++ b/devicetypes/smartthings/smartsense-open-closed-sensor.src/README.md @@ -1,6 +1,6 @@ # Smartsense Open/Closed Sensor - +Local Execution on V2 Hubs Works with: @@ -24,10 +24,11 @@ Works with: ## Device Health -A Category C2 open/closed sensor with maxReportTime of 5 mins. -Check-in interval is double the value of maxReportTime. -This gives the device twice the amount of time to respond before it is marked as offline. -Check-in interval = 12 mins +SmartSense Open Closed sensor with reporting interval of 5 mins. +SmartThings platform will ping the device after `checkInterval` seconds of inactivity in last attempt to reach the device before marking it `OFFLINE` + +* V1, TV, HubV2 AppEngine < 1.5.1 - __121min__ checkInterval +* HubV2 AppEngine 1.5.1 - __12min__ checkInterval ## Battery Specification diff --git a/devicetypes/smartthings/smartsense-open-closed-sensor.src/smartsense-open-closed-sensor.groovy b/devicetypes/smartthings/smartsense-open-closed-sensor.src/smartsense-open-closed-sensor.groovy index 8c779d8..0d945cd 100644 --- a/devicetypes/smartthings/smartsense-open-closed-sensor.src/smartsense-open-closed-sensor.groovy +++ b/devicetypes/smartthings/smartsense-open-closed-sensor.src/smartsense-open-closed-sensor.groovy @@ -260,9 +260,9 @@ def refresh() { } def configure() { - // Device-Watch allows 3 check-in misses from device (plus 1 min lag time) + // Device-Watch allows 2 check-in misses from device + ping (plus 1 min lag time) // enrolls with default periodic reporting until newer 5 min interval is confirmed - sendEvent(name: "checkInterval", value: 3 * 60 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) + sendEvent(name: "checkInterval", value: 2 * 60 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) log.debug "Configuring Reporting, IAS CIE, and Bindings." diff --git a/devicetypes/smartthings/smartsense-temp-humidity-sensor.src/README.md b/devicetypes/smartthings/smartsense-temp-humidity-sensor.src/README.md index b24396a..9638b45 100644 --- a/devicetypes/smartthings/smartsense-temp-humidity-sensor.src/README.md +++ b/devicetypes/smartthings/smartsense-temp-humidity-sensor.src/README.md @@ -1,6 +1,6 @@ # SmartSense Temp/Humidity Sensor - +Local Execution on V2 Hubs Works with: @@ -24,10 +24,11 @@ Works with: ## Device Health -A Category C2 SmartSense Temp/Humidity Sensor with maxReportTime of 5 mins. -Check-in interval is double the value of maxReportTime. -This gives the device twice the amount of time to respond before it is marked as offline. -Check-in interval = 12 mins +SmartSense Temp/Humidity Sensor with reporting interval of 5 mins. +SmartThings platform will ping the device after `checkInterval` seconds of inactivity in last attempt to reach the device before marking it `OFFLINE` + +* V1, TV, HubV2 AppEngine < 1.5.1 - __121min__ checkInterval +* HubV2 AppEngine 1.5.1 - __12min__ checkIntervalr 5 min interval is confirmed ## Battery Specification diff --git a/devicetypes/smartthings/smartsense-temp-humidity-sensor.src/smartsense-temp-humidity-sensor.groovy b/devicetypes/smartthings/smartsense-temp-humidity-sensor.src/smartsense-temp-humidity-sensor.groovy index e0dc7e2..fe93ef3 100644 --- a/devicetypes/smartthings/smartsense-temp-humidity-sensor.src/smartsense-temp-humidity-sensor.groovy +++ b/devicetypes/smartthings/smartsense-temp-humidity-sensor.src/smartsense-temp-humidity-sensor.groovy @@ -264,9 +264,9 @@ def refresh() } def configure() { - // Device-Watch allows 3 check-in misses from device (plus 1 min lag time) + // Device-Watch allows 2 check-in misses from device + ping (plus 1 min lag time) // enrolls with default periodic reporting until newer 5 min interval is confirmed - sendEvent(name: "checkInterval", value: 3 * 60 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) + sendEvent(name: "checkInterval", value: 2 * 60 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) log.debug "Configuring Reporting and Bindings." def humidityConfigCmds = [ diff --git a/devicetypes/smartthings/tyco-door-window-sensor.src/README.md b/devicetypes/smartthings/tyco-door-window-sensor.src/README.md index 13d9ce1..079fbb0 100644 --- a/devicetypes/smartthings/tyco-door-window-sensor.src/README.md +++ b/devicetypes/smartthings/tyco-door-window-sensor.src/README.md @@ -1,6 +1,6 @@ # Tyco Door Window Sensor - +Cloud Execution Works with: @@ -23,10 +23,11 @@ Works with: ## Device Health -Contact sensor with maxReportTime of 5 mins. +Tyco Door Window Sensor with reporting interval of 5 mins. Check-in interval is double the value of maxReportTime for Zigbee device. This gives the device twice the amount of time to respond before it is marked as offline. -Check-in interval = 12 min + +* __12min__ checkInterval ## Battery Specification diff --git a/devicetypes/smartthings/zigbee-dimmer-power.src/README.md b/devicetypes/smartthings/zigbee-dimmer-power.src/README.md index 81ab641..130f20c 100644 --- a/devicetypes/smartthings/zigbee-dimmer-power.src/README.md +++ b/devicetypes/smartthings/zigbee-dimmer-power.src/README.md @@ -1,6 +1,6 @@ # GE Plug-In/In-Wall Smart Dimmer (ZigBee) - +Cloud Execution Works with: @@ -26,11 +26,11 @@ Works with: ## Device Health -A Zigbee dimmer with maxReportTime of 5 mins. -Check-in interval is double the value of maxReportTime. -This gives the device twice the amount of time to respond before it is marked as offline. -Enrolls with default periodic reporting until newer 5 min interval is confirmed -It then enrolls the device with updated checkInterval i.e. 12 mins +A Zigbee Power Dimmer with reporting interval of 5 mins. +SmartThings platform will ping the device after `checkInterval` seconds of inactivity in last attempt to reach the device before marking it `OFFLINE` + +* __12min__ checkInterval + ## Troubleshooting diff --git a/devicetypes/smartthings/zigbee-dimmer-power.src/zigbee-dimmer-power.groovy b/devicetypes/smartthings/zigbee-dimmer-power.src/zigbee-dimmer-power.groovy index c6f4e78..4bef6a9 100644 --- a/devicetypes/smartthings/zigbee-dimmer-power.src/zigbee-dimmer-power.groovy +++ b/devicetypes/smartthings/zigbee-dimmer-power.src/zigbee-dimmer-power.groovy @@ -114,8 +114,8 @@ def refresh() { def configure() { log.debug "Configuring Reporting and Bindings." - // Device-Watch allows 3 check-in misses from device (plus 1 min lag time) + // Device-Watch allows 2 check-in misses from device + ping (plus 1 min lag time) // enrolls with default periodic reporting until newer 5 min interval is confirmed - sendEvent(name: "checkInterval", value: 3 * 60 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) + sendEvent(name: "checkInterval", value: 2 * 60 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) refresh() } diff --git a/devicetypes/smartthings/zigbee-dimmer.src/README.md b/devicetypes/smartthings/zigbee-dimmer.src/README.md index 61f3ed0..05b3ba5 100644 --- a/devicetypes/smartthings/zigbee-dimmer.src/README.md +++ b/devicetypes/smartthings/zigbee-dimmer.src/README.md @@ -1,6 +1,6 @@ # Zigbee Dimmer - +Cloud Execution Works with: @@ -24,11 +24,11 @@ Works with: ## Device Health -A Zigbee dimmer with maxReportTime of 5 mins. -Check-in interval is double the value of maxReportTime. -This gives the device twice the amount of time to respond before it is marked as offline. -Enrolls with default periodic reporting until newer 5 min interval is confirmed -It then enrolls the device with updated checkInterval i.e. 12 mins +ZigBee Dimmer with reporting interval of 5 mins. +SmartThings platform will ping the device after `checkInterval` seconds of inactivity in last attempt to reach the device before marking it `OFFLINE` + +* __12min__ checkInterval + ## Troubleshooting diff --git a/devicetypes/smartthings/zigbee-dimmer.src/zigbee-dimmer.groovy b/devicetypes/smartthings/zigbee-dimmer.src/zigbee-dimmer.groovy index ef17d94..e28888e 100644 --- a/devicetypes/smartthings/zigbee-dimmer.src/zigbee-dimmer.groovy +++ b/devicetypes/smartthings/zigbee-dimmer.src/zigbee-dimmer.groovy @@ -102,9 +102,9 @@ def refresh() { def configure() { log.debug "Configuring Reporting and Bindings." - // Device-Watch allows 3 check-in misses from device (plus 1 min lag time) + // Device-Watch allows 2 check-in misses from device + ping (plus 1 min lag time) // enrolls with default periodic reporting until newer 5 min interval is confirmed - sendEvent(name: "checkInterval", value: 3 * 10 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) + sendEvent(name: "checkInterval", value: 2 * 10 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) // OnOff minReportTime 0 seconds, maxReportTime 5 min. Reporting interval if no activity zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.onOffConfig(0, 300) + zigbee.levelConfig() diff --git a/devicetypes/smartthings/zigbee-rgbw-bulb.src/README.md b/devicetypes/smartthings/zigbee-rgbw-bulb.src/README.md index abe51bb..0e413e5 100644 --- a/devicetypes/smartthings/zigbee-rgbw-bulb.src/README.md +++ b/devicetypes/smartthings/zigbee-rgbw-bulb.src/README.md @@ -1,6 +1,6 @@ # OSRAM LIGHTIFY LED RGBW Bulb - +Cloud Execution Works with: @@ -27,11 +27,10 @@ Works with: ## Device Health -A Category C6 OSRAM LIGHTIFY LED RGBW Bulb with maxReportTime of 5 mins. -Check-in interval is double the value of maxReportTime. -This gives the device twice the amount of time to respond before it is marked as offline. -Check-in interval = 12 mins +OSRAM LIGHTIFY LED RGBW Bulb with reporting interval of 5 mins. +SmartThings platform will ping the device after `checkInterval` seconds of inactivity in last attempt to reach the device before marking it `OFFLINE` +* __12min__ checkInterval ## Troubleshooting diff --git a/devicetypes/smartthings/zigbee-rgbw-bulb.src/zigbee-rgbw-bulb.groovy b/devicetypes/smartthings/zigbee-rgbw-bulb.src/zigbee-rgbw-bulb.groovy index aa4defb..97677b6 100644 --- a/devicetypes/smartthings/zigbee-rgbw-bulb.src/zigbee-rgbw-bulb.groovy +++ b/devicetypes/smartthings/zigbee-rgbw-bulb.src/zigbee-rgbw-bulb.groovy @@ -143,9 +143,9 @@ def refresh() { def configure() { log.debug "Configuring Reporting and Bindings." - // Device-Watch allows 3 check-in misses from device (plus 1 min lag time) + // Device-Watch allows 2 check-in misses from device + ping (plus 1 min lag time) // enrolls with default periodic reporting until newer 5 min interval is confirmed - sendEvent(name: "checkInterval", value: 3 * 10 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) + sendEvent(name: "checkInterval", value: 2 * 10 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) // OnOff minReportTime 0 seconds, maxReportTime 5 min. Reporting interval if no activity refresh() diff --git a/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/README.md b/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/README.md index 779d119..8102914 100644 --- a/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/README.md +++ b/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/README.md @@ -1,6 +1,6 @@ # ZigBee White Color Temperature Bulb - +Cloud Execution Works with: @@ -25,11 +25,10 @@ Works with: ## Device Health -Zigbee Bulb with maxReportTime of 5 mins. -Check-in interval is double the value of maxReportTime. -This gives the device twice the amount of time to respond before it is marked as offline. -Enrolls with default periodic reporting until newer 5 min interval is confirmed -It then enrolls the device with updated checkInterval i.e. 12 mins +Zigbee Bulb with reporting interval of 5 mins. +SmartThings platform will ping the device after `checkInterval` seconds of inactivity in last attempt to reach the device before marking it `OFFLINE` + +*__12min__ checkInterval ## Troubleshooting diff --git a/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy b/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy index ad28c8f..123a203 100644 --- a/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy +++ b/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy @@ -207,9 +207,9 @@ def refresh() { def configure() { log.debug "Configuring Reporting and Bindings." - // Device-Watch allows 3 check-in misses from device (plus 1 min lag time) + // Device-Watch allows 2 check-in misses from device + ping (plus 1 min lag time) // enrolls with default periodic reporting until newer 5 min interval is confirmed - sendEvent(name: "checkInterval", value: 3 * 10 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) + sendEvent(name: "checkInterval", value: 2 * 10 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) refresh() + requestBindingTable(0) + ["delay 2000"] } diff --git a/devicetypes/smartthings/zwave-dimmer-switch-generic.src/README.md b/devicetypes/smartthings/zwave-dimmer-switch-generic.src/README.md index f5f4fef..d959894 100644 --- a/devicetypes/smartthings/zwave-dimmer-switch-generic.src/README.md +++ b/devicetypes/smartthings/zwave-dimmer-switch-generic.src/README.md @@ -1,6 +1,6 @@ -# Z-wave Dimmer - +# Z-wave Dimmer Switch Generic +Cloud Execution Works with: @@ -32,6 +32,8 @@ Not to mention after going OFFLINE when the device is plugged back in, it might the device to appear as ONLINE again. This is because if this listening device does not respond to two poll requests in a row, it is not polled for 5 minutes by the hub. This can delay up the process of being marked ONLINE by quite some time. +* __32min__ checkInterval + ## Troubleshooting If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the device is out of range. diff --git a/devicetypes/smartthings/zwave-switch-generic.src/README.md b/devicetypes/smartthings/zwave-switch-generic.src/README.md index 765bcd1..baec4dd 100644 --- a/devicetypes/smartthings/zwave-switch-generic.src/README.md +++ b/devicetypes/smartthings/zwave-switch-generic.src/README.md @@ -1,6 +1,6 @@ # Z-wave Switch - +Cloud Execution Works with: @@ -32,6 +32,8 @@ Not to mention after going OFFLINE when the device is plugged back in, it might the device to appear as ONLINE again. This is because if this listening device does not respond to two poll requests in a row, it is not polled for 5 minutes by the hub. This can delay up the process of being marked ONLINE by quite some time. +* __32min__ checkInterval + ## Troubleshooting If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the device is out of range. diff --git a/devicetypes/smartthings/zwave-switch.src/README.md b/devicetypes/smartthings/zwave-switch.src/README.md index 7843a42..5d15675 100644 --- a/devicetypes/smartthings/zwave-switch.src/README.md +++ b/devicetypes/smartthings/zwave-switch.src/README.md @@ -1,5 +1,6 @@ # Z-Wave Switch +Local Execution on V2 Hubs Works with: @@ -34,6 +35,7 @@ Not to mention after going OFFLINE when the device is plugged back in, it might the device to appear as ONLINE again. This is because if this listening device does not respond to two poll requests in a row, it is not polled for 5 minutes by the hub. This can delay up the process of being marked ONLINE by quite some time. +* __32min__ checkInterval ## Troubleshooting From cf9d123aa0afda9375f3d640ac289d3d2a9907c8 Mon Sep 17 00:00:00 2001 From: Zach Varberg Date: Mon, 14 Nov 2016 11:06:09 -0600 Subject: [PATCH 13/17] Handle all messages in smartpower dimming outlet Previously the implementation of isKnownDescription didn't cover all possible messages that could be parsed and this caused null pointer exceptions with certain messages. This now handles all the possibilities. This resolves: https://smartthings.atlassian.net/browse/DVCSMP-2227 --- .../smartpower-dimming-outlet.groovy | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/devicetypes/smartthings/smartpower-dimming-outlet.src/smartpower-dimming-outlet.groovy b/devicetypes/smartthings/smartpower-dimming-outlet.src/smartpower-dimming-outlet.groovy index a4c240a..9539376 100644 --- a/devicetypes/smartthings/smartpower-dimming-outlet.src/smartpower-dimming-outlet.groovy +++ b/devicetypes/smartthings/smartpower-dimming-outlet.src/smartpower-dimming-outlet.groovy @@ -71,7 +71,7 @@ def parse(String description) { def event = [:] def finalResult = isKnownDescription(description) - if (finalResult != "false") { + if (finalResult) { log.info finalResult if (finalResult.type == "update") { log.info "$device updates: ${finalResult.value}" @@ -212,13 +212,16 @@ def isKnownDescription(description) { else if (descMap.cluster == "0B04" || descMap.clusterId == "0B04"){ isDescriptionPower(descMap) } + else { + return [:] + } } else if(description?.startsWith("on/off:")) { def switchValue = description?.endsWith("1") ? "on" : "off" return [type: "switch", value : switchValue] } else { - return "false" + return [:] } } @@ -252,7 +255,7 @@ def isDescriptionOnOff(descMap) { return [type: "switch", value : switchValue] } else { - return "false" + return [:] } } @@ -279,10 +282,9 @@ def isDescriptionLevel(descMap) { if (dimmerValue != -1){ return [type: "level", value : dimmerValue] - } else { - return "false" + return [:] } } @@ -304,7 +306,7 @@ def isDescriptionPower(descMap) { return [type: "power", value : powerValue] } else { - return "false" + return [:] } } From 3f93de247b3c0ea05ed97fcfffe15d440de1dea9 Mon Sep 17 00:00:00 2001 From: jackchi Date: Mon, 14 Nov 2016 12:05:10 -0800 Subject: [PATCH 14/17] [CHF-442][DVCSMP-2179] Hotfix for EcoBee thermostat & Osram RT5/6 Tunable White naming --- .../smartthings/ecobee-thermostat.src/ecobee-thermostat.groovy | 2 +- .../zigbee-white-color-temperature-bulb.groovy | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/devicetypes/smartthings/ecobee-thermostat.src/ecobee-thermostat.groovy b/devicetypes/smartthings/ecobee-thermostat.src/ecobee-thermostat.groovy index 198fc0a..0f281a2 100644 --- a/devicetypes/smartthings/ecobee-thermostat.src/ecobee-thermostat.groovy +++ b/devicetypes/smartthings/ecobee-thermostat.src/ecobee-thermostat.groovy @@ -125,7 +125,7 @@ metadata { void installed() { // The device refreshes every 5 minutes by default so if we miss 2 refreshes we can consider it offline // Using 12 minutes because in testing, device health team found that there could be "jitter" - sendEvent(name: "checkInterval", value: 60 * 12, data: [protocol: "cloud", hubHardwareId: device.hub.hardwareID], displayed: false) + sendEvent(name: "checkInterval", value: 60 * 12, data: [protocol: "cloud"], displayed: false) } // Device Watch will ping the device to proactively determine if the device has gone offline diff --git a/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy b/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy index 123a203..d35ec61 100644 --- a/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy +++ b/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy @@ -33,7 +33,7 @@ metadata { fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300", outClusters: "0019" fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 0B04", outClusters: "0019" fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 0B04, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "LIGHTIFY BR Tunable White", deviceJoinName: "OSRAM LIGHTIFY LED Flood BR30 Tunable White" - fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 0B04, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "LIGHTIFY RT Tunable White", deviceJoinName: "OSRAM LIGHTIFY RT5/6 Tunable White" + fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 0B04, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "LIGHTIFY RT Tunable White", deviceJoinName: "OSRAM LIGHTIFY LED Recessed Kit RT 5/6 Tunable White" fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 0B04, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "Classic A60 TW", deviceJoinName: "OSRAM LIGHTIFY LED Tunable White 60W" fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 0B04, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "LIGHTIFY A19 Tunable White", deviceJoinName: "OSRAM LIGHTIFY LED Tunable White 60W" fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 0B04, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "Classic B40 TW - LIGHTIFY", deviceJoinName: "OSRAM LIGHTIFY Classic B40 Tunable White" From 65bb10d6d6424660874707a61be8c1d9a05ff8f1 Mon Sep 17 00:00:00 2001 From: Zach Varberg Date: Mon, 14 Nov 2016 14:34:53 -0600 Subject: [PATCH 15/17] Do not delete all binding table entries There was a bug when comparing the destination address for binding table entries that would cause all binding table entries to be deleted. This fixes that. This is a fix for: https://smartthings.atlassian.net/browse/DVCSMP-2175 --- .../zigbee-white-color-temperature-bulb.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy b/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy index 123a203..e8310a1 100644 --- a/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy +++ b/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy @@ -88,7 +88,7 @@ def parse(String description) { List cmds = [] bindingTable.table_entries.inject(cmds) { acc, entry -> // The binding entry is not for our hub and should be deleted - if (entry["dstAddr"] != zigbeeEui) { + if (entry["dstAddr"] != zigbee.zigbeeEui) { acc.addAll(removeBinding(entry.clusterId, entry.srcAddr, entry.srcEndpoint, entry.dstAddr, entry.dstEndpoint)) } acc From 3034cc8bcb334aac0de6d97a9130c75a78a2d846 Mon Sep 17 00:00:00 2001 From: Zach Varberg Date: Tue, 15 Nov 2016 13:23:57 -0600 Subject: [PATCH 16/17] Revert "Do not delete all binding table entries" This reverts commit 65bb10d6d6424660874707a61be8c1d9a05ff8f1. --- .../zigbee-white-color-temperature-bulb.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy b/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy index 1a7afb9..d35ec61 100644 --- a/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy +++ b/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy @@ -88,7 +88,7 @@ def parse(String description) { List cmds = [] bindingTable.table_entries.inject(cmds) { acc, entry -> // The binding entry is not for our hub and should be deleted - if (entry["dstAddr"] != zigbee.zigbeeEui) { + if (entry["dstAddr"] != zigbeeEui) { acc.addAll(removeBinding(entry.clusterId, entry.srcAddr, entry.srcEndpoint, entry.dstAddr, entry.dstEndpoint)) } acc From a84ffdde918a95beeaf14b1f65d802a5a0860f97 Mon Sep 17 00:00:00 2001 From: Zach Varberg Date: Tue, 15 Nov 2016 13:24:23 -0600 Subject: [PATCH 17/17] Revert "ETI Clear binding table entries to other devices" This reverts commit 969852602c163f4064736c90ba2635ede50f5994. --- ...zigbee-white-color-temperature-bulb.groovy | 104 ++---------------- 1 file changed, 12 insertions(+), 92 deletions(-) diff --git a/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy b/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy index d35ec61..e6c6c7e 100644 --- a/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy +++ b/devicetypes/smartthings/zigbee-white-color-temperature-bulb.src/zigbee-white-color-temperature-bulb.groovy @@ -83,105 +83,24 @@ def parse(String description) { } } else { - Map bindingTable = parseBindingTableResponse(description) - if (bindingTable) { - List cmds = [] - bindingTable.table_entries.inject(cmds) { acc, entry -> - // The binding entry is not for our hub and should be deleted - if (entry["dstAddr"] != zigbeeEui) { - acc.addAll(removeBinding(entry.clusterId, entry.srcAddr, entry.srcEndpoint, entry.dstAddr, entry.dstEndpoint)) - } - acc - } - // There are more entries that we haven't examined yet - if (bindingTable.numTableEntries > bindingTable.startIndex + bindingTable.numEntriesReturned) { - def startPos - if (cmds) { - log.warn "Removing binding entries for other devices: $cmds" - // Since we are removing some entries, we should start in the same spot as we just read since values - // will fill in the newly vacated spots - startPos = bindingTable.startIndex - } else { - // Since we aren't removing anything we move forward to the next set of table entries - startPos = bindingTable.startIndex + bindingTable.numEntriesReturned - } - cmds.addAll(requestBindingTable(startPos)) - } - sendHubCommand(cmds.collect { it -> - new physicalgraph.device.HubAction(it) - }, 2000) - } else { - def cluster = zigbee.parse(description) + def cluster = zigbee.parse(description) - if (cluster && cluster.clusterId == 0x0006 && cluster.command == 0x07) { - if (cluster.data[0] == 0x00) { - log.debug "ON/OFF REPORTING CONFIG RESPONSE: " + cluster - sendEvent(name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) - } - else { - log.warn "ON/OFF REPORTING CONFIG FAILED- error code:${cluster.data[0]}" - } + if (cluster && cluster.clusterId == 0x0006 && cluster.command == 0x07) { + if (cluster.data[0] == 0x00) { + log.debug "ON/OFF REPORTING CONFIG RESPONSE: " + cluster + sendEvent(name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) } else { - log.warn "DID NOT PARSE MESSAGE for description : $description" - log.debug "${cluster}" + log.warn "ON/OFF REPORTING CONFIG FAILED- error code:${cluster.data[0]}" } } + else { + log.warn "DID NOT PARSE MESSAGE for description : $description" + log.debug "${cluster}" + } } } -def parseBindingTableResponse(description) { - Map descMap = zigbee.parseDescriptionAsMap(description) - if (descMap["clusterInt"] == 0x8033) { - def header_field_lengths = ["transactionSeqNo": 1, "status": 1, "numTableEntries": 1, "startIndex": 1, "numEntriesReturned": 1] - def field_values = [:] - def data = descMap["data"] - header_field_lengths.each { k, v -> - field_values[k] = Integer.parseInt(data.take(v).join(""), 16); - data = data.drop(v); - } - - List table = [] - if (field_values.numEntriesReturned) { - def table_entry_lengths = ["srcAddr": 8, "srcEndpoint": 1, "clusterId": 2, "dstAddrMode": 1] - for (def i : 0..(field_values.numEntriesReturned - 1)) { - def entryMap = [:] - table_entry_lengths.each { k, v -> - def val = data.take(v).reverse().join("") - entryMap[k] = val.length() < 8 ? Integer.parseInt(val, 16) : val - data = data.drop(v) - } - - switch (entryMap.dstAddrMode) { - case 0x01: - entryMap["dstAddr"] = data.take(2).reverse().join("") - data = data.drop(2) - break - case 0x03: - entryMap["dstAddr"] = data.take(8).reverse().join("") - data = data.drop(8) - entryMap["dstEndpoint"] = Integer.parseInt(data.take(1).join(""), 16) - data = data.drop(1) - break - } - table << entryMap - } - } - field_values["table_entries"] = table - return field_values - } - return [:] -} - -def requestBindingTable(startPos=0) { - return ["zdo mgmt-bind 0x${zigbee.deviceNetworkId} $startPos"] -} - -def removeBinding(cluster, srcAddr, srcEndpoint, destAddr, destEndpoint) { - return ["zdo unbind unicast 0x${zigbee.deviceNetworkId} {${srcAddr}} $srcEndpoint $cluster {${destAddr}} $destEndpoint"] -} - - def off() { zigbee.off() } @@ -211,7 +130,8 @@ def configure() { // enrolls with default periodic reporting until newer 5 min interval is confirmed sendEvent(name: "checkInterval", value: 2 * 10 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID]) - refresh() + requestBindingTable(0) + ["delay 2000"] + // OnOff minReportTime 0 seconds, maxReportTime 5 min. Reporting interval if no activity + refresh() } def setColorTemperature(value) {