diff --git a/devicetypes/smartthings/cree-bulb.src/cree-bulb.groovy b/devicetypes/smartthings/cree-bulb.src/cree-bulb.groovy index 0c76dc4..020272b 100644 --- a/devicetypes/smartthings/cree-bulb.src/cree-bulb.groovy +++ b/devicetypes/smartthings/cree-bulb.src/cree-bulb.groovy @@ -13,17 +13,19 @@ * for the specific language governing permissions and limitations under the License. * */ - + +//@Deprecated: Moved to ZLL Dimmer Bulb metadata { definition (name: "Cree Bulb", namespace: "smartthings", author: "SmartThings") { capability "Actuator" capability "Configuration" + capability "Polling" capability "Refresh" capability "Switch" capability "Switch Level" - fingerprint profileId: "C05E", inClusters: "0000,0003,0004,0005,0006,0008,1000", outClusters: "0000,0019" + //fingerprint profileId: "C05E", inClusters: "0000,0003,0004,0005,0006,0008,1000", outClusters: "0000,0019" } // simulator metadata @@ -88,6 +90,10 @@ def refresh() { zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.onOffConfig() + zigbee.levelConfig() } +def poll() { + zigbee.onOffRefresh() + zigbee.levelRefresh() +} + def configure() { log.debug "Configuring Reporting and Bindings." zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh() diff --git a/devicetypes/smartthings/zigbee-hue-bulb.src/zigbee-hue-bulb.groovy b/devicetypes/smartthings/zigbee-hue-bulb.src/zigbee-hue-bulb.groovy index 29a24fa..2b03635 100644 --- a/devicetypes/smartthings/zigbee-hue-bulb.src/zigbee-hue-bulb.groovy +++ b/devicetypes/smartthings/zigbee-hue-bulb.src/zigbee-hue-bulb.groovy @@ -11,6 +11,9 @@ * for the specific language governing permissions and limitations under the License. * */ + +//@Deprecated - Moved to zll-rgbw-bulb + /* Philips Hue (via Zigbee) Capabilities: @@ -22,10 +25,10 @@ Capabilities: Sensor Switch Switch Level - + Custom Commands: setAdjustedColor - + */ metadata { @@ -41,7 +44,7 @@ metadata { command "setAdjustedColor" - fingerprint profileId: "C05E", inClusters: "0000,0003,0004,0005,0006,0008,0300,1000", outClusters: "0019" + //fingerprint profileId: "C05E", inClusters: "0000,0003,0004,0005,0006,0008,0300,1000", outClusters: "0019" } // simulator metadata diff --git a/devicetypes/smartthings/zll-dimmer-bulb.src/zll-dimmer-bulb.groovy b/devicetypes/smartthings/zll-dimmer-bulb.src/zll-dimmer-bulb.groovy new file mode 100644 index 0000000..c610344 --- /dev/null +++ b/devicetypes/smartthings/zll-dimmer-bulb.src/zll-dimmer-bulb.groovy @@ -0,0 +1,99 @@ +/** + * Copyright 2016 SmartThings + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License + * for the specific language governing permissions and limitations under the License. + * + */ + +metadata { + definition (name: "ZLL Dimmer Bulb", namespace: "smartthings", author: "SmartThings") { + + capability "Actuator" + capability "Configuration" + capability "Polling" + capability "Refresh" + capability "Switch" + capability "Switch Level" + + fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000", outClusters: "0000,0019" + fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000", outClusters: "0000,0019", manufacturer: "CREE", model: "Connected A-19 60W Equivalent", deviceJoinName: "Cree Connected Bulb" + fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000, 0B04, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "Classic A60 W clear", deviceJoinName: "OSRAM LIGHTIFY LED Smart Connected Light" + } + + // simulator metadata + simulator { + // status messages + status "on": "on/off: 1" + status "off": "on/off: 0" + + // reply messages + reply "zcl on-off on": "on/off: 1" + reply "zcl on-off off": "on/off: 0" + } + + // UI tile definitions + tiles(scale: 2) { + multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){ + tileAttribute ("device.switch", key: "PRIMARY_CONTROL") { + attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff" + attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn" + attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff" + attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn" + } + tileAttribute ("device.level", key: "SLIDER_CONTROL") { + attributeState "level", action:"switch level.setLevel" + } + } + standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) { + state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh" + } + main "switch" + details(["switch", "refresh"]) + } +} + +// Parse incoming device messages to generate events +def parse(String description) { + log.debug "description is $description" + + def resultMap = zigbee.getEvent(description) + if (resultMap) { + sendEvent(resultMap) + } + else { + log.debug "DID NOT PARSE MESSAGE for description : $description" + log.debug zigbee.parseDescriptionAsMap(description) + } +} + +def off() { + zigbee.off() + ["delay 1500"] + zigbee.onOffRefresh() +} + +def on() { + zigbee.on() + ["delay 1500"] + zigbee.onOffRefresh() +} + +def setLevel(value) { + zigbee.setLevel(value) + ["delay 1500"] + zigbee.levelRefresh() //adding refresh because of ZLL bulb not conforming to send-me-a-report +} + +def refresh() { + zigbee.onOffRefresh() + zigbee.levelRefresh() +} + +def poll() { + refresh() +} + +def configure() { + log.debug "Configuring Reporting and Bindings." + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh() +} diff --git a/devicetypes/smartthings/zll-rgbw-bulb.src/zll-rgbw-bulb.groovy b/devicetypes/smartthings/zll-rgbw-bulb.src/zll-rgbw-bulb.groovy new file mode 100644 index 0000000..9d9be84 --- /dev/null +++ b/devicetypes/smartthings/zll-rgbw-bulb.src/zll-rgbw-bulb.groovy @@ -0,0 +1,150 @@ +/** + * Copyright 2016 SmartThings + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License + * for the specific language governing permissions and limitations under the License. + * + */ + +metadata { + definition (name: "ZLL RGBW Bulb", namespace: "smartthings", author: "SmartThings") { + + capability "Actuator" + capability "Color Control" + capability "Color Temperature" + capability "Configuration" + capability "Polling" + capability "Refresh" + capability "Switch" + capability "Switch Level" + + fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300", outClusters: "0019" + fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 1000", outClusters: "0019" + fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 1000", outClusters: "0019", "manufacturer":"OSRAM", "model":"Classic A60 RGBW", deviceJoinName: "OSRAM LIGHTIFY LED Classic A60 RGBW" + } + + // UI tile definitions + tiles(scale: 2) { + multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){ + tileAttribute ("device.switch", key: "PRIMARY_CONTROL") { + attributeState "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff" + attributeState "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn" + attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff" + attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn" + } + tileAttribute ("device.level", key: "SLIDER_CONTROL") { + attributeState "level", action:"switch level.setLevel" + } + tileAttribute ("device.color", key: "COLOR_CONTROL") { + attributeState "color", action:"color control.setColor" + } + } + controlTile("colorTempSliderControl", "device.colorTemperature", "slider", width: 4, height: 2, inactiveLabel: false, range:"(2700..6500)") { + state "colorTemperature", action:"color temperature.setColorTemperature" + } + valueTile("colorTemp", "device.colorTemperature", inactiveLabel: false, decoration: "flat", width: 2, height: 2) { + state "colorTemperature", label: '${currentValue} K' + } + standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) { + state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh" + } + + main(["switch"]) + details(["switch", "colorTempSliderControl", "colorTemp", "refresh"]) + } +} + +//Globals +private getATTRIBUTE_HUE() { 0x0000 } +private getATTRIBUTE_SATURATION() { 0x0001 } +private getHUE_COMMAND() { 0x00 } +private getSATURATION_COMMAND() { 0x03 } +private getCOLOR_CONTROL_CLUSTER() { 0x0300 } +private getATTRIBUTE_COLOR_TEMPERATURE() { 0x0007 } + +// Parse incoming device messages to generate events +def parse(String description) { + log.debug "description is $description" + + def finalResult = zigbee.getEvent(description) + if (finalResult) { + log.debug finalResult + sendEvent(finalResult) + } + else { + def zigbeeMap = zigbee.parseDescriptionAsMap(description) + log.trace "zigbeeMap : $zigbeeMap" + + if (zigbeeMap?.clusterInt == COLOR_CONTROL_CLUSTER) { + if(zigbeeMap.attrInt == ATTRIBUTE_HUE){ //Hue Attribute + def hueValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 255 * 360) + sendEvent(name: "hue", value: hueValue, displayed:false) + } + else if(zigbeeMap.attrInt == ATTRIBUTE_SATURATION){ //Saturation Attribute + def saturationValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 255 * 100) + sendEvent(name: "saturation", value: saturationValue, displayed:false) + } + } + else { + log.info "DID NOT PARSE MESSAGE for description : $description" + } + } +} + +def on() { + zigbee.on() + ["delay 1500"] + zigbee.onOffRefresh() +} + +def off() { + zigbee.off() + ["delay 1500"] + zigbee.onOffRefresh() +} + +def refresh() { + refreshAttributes() + configureAttributes() +} + +def poll() { + refreshAttributes() +} + +def configure() { + log.debug "Configuring Reporting and Bindings." + configureAttributes() + refreshAttributes() +} + +def configureAttributes() { + 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 refreshAttributes() { + zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh() + zigbee.readAttribute(0x0300, 0x00) + zigbee.readAttribute(0x0300, ATTRIBUTE_HUE) + zigbee.readAttribute(0x0300, ATTRIBUTE_SATURATION) +} + +def setColorTemperature(value) { + zigbee.setColorTemperature(value) + ["delay 1500"] + zigbee.colorTemperatureRefresh() +} + +def setLevel(value) { + zigbee.setLevel(value) + ["delay 1500"] + zigbee.levelRefresh() //adding refresh because of ZLL bulb not conforming to send-me-a-report +} + +def setColor(value){ + log.trace "setColor($value)" + zigbee.on() + setHue(value.hue) + ["delay 300"] + setSaturation(value.saturation) + ["delay 2000"] + refreshAttributes() +} + +def setHue(value) { + def scaledHueValue = zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2) + zigbee.command(COLOR_CONTROL_CLUSTER, HUE_COMMAND, scaledHueValue, "00", "0500") //payload-> hue value, direction (00-> shortest distance), transition time (1/10th second) (0500 in U16 reads 5) +} + +def setSaturation(value) { + def scaledSatValue = zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2) + zigbee.command(COLOR_CONTROL_CLUSTER, SATURATION_COMMAND, scaledSatValue, "0500") //payload-> sat value, transition time +} diff --git a/devicetypes/smartthings/zll-white-color-temperature-bulb.src/zll-white-color-temperature-bulb.groovy b/devicetypes/smartthings/zll-white-color-temperature-bulb.src/zll-white-color-temperature-bulb.groovy new file mode 100644 index 0000000..bbdc73b --- /dev/null +++ b/devicetypes/smartthings/zll-white-color-temperature-bulb.src/zll-white-color-temperature-bulb.groovy @@ -0,0 +1,124 @@ +/** + * Copyright 2016 SmartThings + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License + * for the specific language governing permissions and limitations under the License. + * + */ + +metadata { + definition (name: "ZLL White Color Temperature Bulb", namespace: "smartthings", author: "SmartThings") { + + capability "Actuator" + capability "Color Temperature" + capability "Configuration" + capability "Polling" + capability "Refresh" + capability "Switch" + capability "Switch Level" + + attribute "colorName", "string" + command "setGenericName" + + fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 1000, 0B04, FC0F", outClusters: "0019", "manufacturer":"OSRAM", "model":"Classic A60 TW", deviceJoinName: "OSRAM LIGHTIFY LED Classic A60 Tunable White" + fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 1000, FC0F", outClusters: "0019", "manufacturer":"OSRAM", "model":"PAR16 50 TW", deviceJoinName: "OSRAM LIGHTIFY LED PAR16 50 Tunable White" + } + + // UI tile definitions + tiles(scale: 2) { + multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){ + tileAttribute ("device.switch", key: "PRIMARY_CONTROL") { + attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff" + attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn" + attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff" + attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn" + } + tileAttribute ("device.level", key: "SLIDER_CONTROL") { + attributeState "level", action:"switch level.setLevel" + } + tileAttribute ("colorName", key: "SECONDARY_CONTROL") { + attributeState "colorName", label:'${currentValue}' + } + } + + standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) { + state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh" + } + + controlTile("colorTempSliderControl", "device.colorTemperature", "slider", width: 4, height: 2, inactiveLabel: false, range:"(2700..6500)") { + state "colorTemperature", action:"color temperature.setColorTemperature" + } + valueTile("colorTemp", "device.colorTemperature", inactiveLabel: false, decoration: "flat", width: 2, height: 2) { + state "colorTemperature", label: '${currentValue} K' + } + + main(["switch"]) + details(["switch", "colorTempSliderControl", "colorTemp", "refresh"]) + } +} + +// Parse incoming device messages to generate events +def parse(String description) { + log.debug "description is $description" + def event = zigbee.getEvent(description) + if (event) { + sendEvent(event) + } + else { + log.warn "DID NOT PARSE MESSAGE for description : $description" + log.debug zigbee.parseDescriptionAsMap(description) + } +} + +def off() { + zigbee.off() + ["delay 1500"] + zigbee.onOffRefresh() +} + +def on() { + zigbee.on() + ["delay 1500"] + zigbee.onOffRefresh() +} + +def setLevel(value) { + zigbee.setLevel(value) + ["delay 1500"] + zigbee.levelRefresh() +} + +def refresh() { + zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh() + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig() +} + +def poll() { + zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh() +} + +def configure() { + log.debug "Configuring Reporting and Bindings." + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh() +} + +def setColorTemperature(value) { + setGenericName(value) + zigbee.setColorTemperature(value) + ["delay 1500"] + zigbee.colorTemperatureRefresh() +} + +//Naming based on the wiki article here: http://en.wikipedia.org/wiki/Color_temperature +def setGenericName(value){ + if (value != null) { + def genericName = "" + if (value < 3300) { + genericName = "Soft White" + } else if (value < 4150) { + genericName = "Moonlight" + } else if (value <= 5000) { + genericName = "Cool White" + } else { + genericName = "Daylight" + } + sendEvent(name: "colorName", value: genericName) + } +}