diff --git a/devicetypes/smartthings/zigbee-dimmer.src/zigbee-dimmer.groovy b/devicetypes/smartthings/zigbee-dimmer.src/zigbee-dimmer.groovy index 72809f5..f23c78c 100644 --- a/devicetypes/smartthings/zigbee-dimmer.src/zigbee-dimmer.groovy +++ b/devicetypes/smartthings/zigbee-dimmer.src/zigbee-dimmer.groovy @@ -19,6 +19,7 @@ metadata { capability "Refresh" capability "Switch" capability "Switch Level" + capability "Health Check" fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008" @@ -54,6 +55,12 @@ def parse(String description) { def event = zigbee.getEvent(description) if (event) { sendEvent(event) + // Temporary fix for the case when Device is OFFLINE and is connected again + if (state.lastActivity == null){ + state.lastActivity = now() + sendEvent(name: "deviceWatch-lastActivity", value: state.lastActivity, description: "Last Activity is on ${new Date((long)state.lastActivity)}", displayed: false, isStateChange: true) + } + state.lastActivity = now() } else { log.warn "DID NOT PARSE MESSAGE for description : $description" @@ -72,6 +79,20 @@ def on() { def setLevel(value) { zigbee.setLevel(value) } +/** + * PING is used by Device-Watch in attempt to reach the Device + * */ +def ping() { + + if (state.lastActivity < (now() - (1000 * device.currentValue("checkInterval"))) ){ + log.info "ping, alive=no, lastActivity=${state.lastActivity}" + state.lastActivity = null + return zigbee.onOffRefresh() + } else { + log.info "ping, alive=yes, lastActivity=${state.lastActivity}" + sendEvent(name: "deviceWatch-lastActivity", value: state.lastActivity, description: "Last Activity is on ${new Date((long)state.lastActivity)}", displayed: false, isStateChange: true) + } +} def refresh() { zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.onOffConfig() + zigbee.levelConfig() @@ -79,5 +100,7 @@ def refresh() { def configure() { log.debug "Configuring Reporting and Bindings." + // Enrolls device to Device-Watch with 3 x Reporting interval 30min + sendEvent(name: "checkInterval", value: 1800, displayed: false, data: [protocol: "zigbee"]) zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh() } 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 ade4987..31fc7b0 100644 --- a/devicetypes/smartthings/zigbee-rgbw-bulb.src/zigbee-rgbw-bulb.groovy +++ b/devicetypes/smartthings/zigbee-rgbw-bulb.src/zigbee-rgbw-bulb.groovy @@ -27,6 +27,7 @@ metadata { capability "Refresh" capability "Switch" capability "Switch Level" + capability "Health Check" fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0008,0300,0B04,FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "LIGHTIFY Flex RGBW", deviceJoinName: "OSRAM LIGHTIFY LED FLEXIBLE STRIP RGBW" fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0008,0300,0B04,FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "Flex RGBW", deviceJoinName: "OSRAM LIGHTIFY LED FLEXIBLE STRIP RGBW" @@ -82,6 +83,12 @@ def parse(String description) { if (finalResult) { log.debug finalResult sendEvent(finalResult) + // Temporary fix for the case when Device is OFFLINE and is connected again + if (state.lastActivity == null){ + state.lastActivity = now() + sendEvent(name: "deviceWatch-lastActivity", value: state.lastActivity, description: "Last Activity is on ${new Date((long)state.lastActivity)}", displayed: false, isStateChange: true) + } + state.lastActivity = now() } else { def zigbeeMap = zigbee.parseDescriptionAsMap(description) @@ -110,13 +117,29 @@ def on() { def off() { zigbee.off() } +/** + * PING is used by Device-Watch in attempt to reach the Device + * */ +def ping() { + + if (state.lastActivity < (now() - (1000 * device.currentValue("checkInterval"))) ){ + log.info "ping, alive=no, lastActivity=${state.lastActivity}" + state.lastActivity = null + return zigbee.onOffRefresh() + } else { + log.info "ping, alive=yes, lastActivity=${state.lastActivity}" + sendEvent(name: "deviceWatch-lastActivity", value: state.lastActivity, description: "Last Activity is on ${new Date((long)state.lastActivity)}", displayed: false, isStateChange: true) + } +} def refresh() { - zigbee.readAttribute(0x0006, 0x00) + zigbee.readAttribute(0x0008, 0x00) + zigbee.readAttribute(0x0300, 0x00) + zigbee.readAttribute(0x0300, ATTRIBUTE_COLOR_TEMPERATURE) + zigbee.readAttribute(0x0300, ATTRIBUTE_HUE) + zigbee.readAttribute(0x0300, ATTRIBUTE_SATURATION) + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig() + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE, 0x20, 1, 3600, 0x01) + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION, 0x20, 1, 3600, 0x01) + zigbee.onOffRefresh() + zigbee.readAttribute(0x0008, 0x00) + zigbee.readAttribute(0x0300, 0x00) + zigbee.readAttribute(0x0300, ATTRIBUTE_COLOR_TEMPERATURE) + zigbee.readAttribute(0x0300, ATTRIBUTE_HUE) + zigbee.readAttribute(0x0300, ATTRIBUTE_SATURATION) + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig() + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE, 0x20, 1, 3600, 0x01) + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION, 0x20, 1, 3600, 0x01) } def configure() { log.debug "Configuring Reporting and Bindings." + // Enrolls device to Device-Watch with 3 x Reporting interval 30min + sendEvent(name: "checkInterval", value: 1800, displayed: false, data: [protocol: "zigbee"]) zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig() + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE, 0x20, 1, 3600, 0x01) + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION, 0x20, 1, 3600, 0x01) + zigbee.readAttribute(0x0006, 0x00) + zigbee.readAttribute(0x0008, 0x00) + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, 0x00) + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_COLOR_TEMPERATURE) + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION) }