diff --git a/devicetypes/smartthings/zigbee-dimmer-power.src/zigbee-dimmer-power.groovy b/devicetypes/smartthings/zigbee-dimmer-power.src/zigbee-dimmer-power.groovy new file mode 100644 index 0000000..0382e0c --- /dev/null +++ b/devicetypes/smartthings/zigbee-dimmer-power.src/zigbee-dimmer-power.groovy @@ -0,0 +1,98 @@ +/** + * Copyright 2015 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: "ZigBee Dimmer Power", namespace: "smartthings", author: "SmartThings") { + capability "Actuator" + capability "Configuration" + capability "Refresh" + capability "Power Meter" + capability "Sensor" + capability "Switch" + capability "Switch Level" + + fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0B04" + fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0702" + } + + 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.switch.on", backgroundColor:"#79b821", nextState:"turningOff" + attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn" + attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff" + attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn" + } + tileAttribute ("device.level", key: "SLIDER_CONTROL") { + attributeState "level", action:"switch level.setLevel" + } + tileAttribute ("power", key: "SECONDARY_CONTROL") { + attributeState "power", label:'${currentValue} W' + } + } + 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.getKnownDescription(description) + if (resultMap) { + log.info resultMap + if (resultMap.type == "update") { + log.info "$device updates: ${resultMap.value}" + } + else if (resultMap.type == "power") { + def powerValue + if (device.getDataValue("manufacturer") != "OSRAM") { //OSRAM devices do not reliably update power + powerValue = (resultMap.value as Integer)/10 //TODO: The divisor value needs to be set as part of configuration + sendEvent(name: "power", value: powerValue) + } + } + else { + sendEvent(name: resultMap.type, value: resultMap.value) + } + } + else { + log.warn "DID NOT PARSE MESSAGE for description : $description" + log.debug zigbee.parseDescriptionAsMap(description) + } +} + +def off() { + zigbee.off() +} + +def on() { + zigbee.on() +} + +def setLevel(value) { + zigbee.setLevel(value) +} + +def refresh() { + zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.simpleMeteringPowerRefresh() + zigbee.electricMeasurementPowerRefresh() + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.simpleMeteringPowerConfig() + zigbee.electricMeasurementPowerConfig() +} + +def configure() { + log.debug "Configuring Reporting and Bindings." + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.simpleMeteringPowerConfig() + zigbee.electricMeasurementPowerConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.simpleMeteringPowerRefresh() + zigbee.electricMeasurementPowerRefresh() +} diff --git a/devicetypes/smartthings/zigbee-dimmer.src/zigbee-dimmer.groovy b/devicetypes/smartthings/zigbee-dimmer.src/zigbee-dimmer.groovy index 07dbc37..588a177 100644 --- a/devicetypes/smartthings/zigbee-dimmer.src/zigbee-dimmer.groovy +++ b/devicetypes/smartthings/zigbee-dimmer.src/zigbee-dimmer.groovy @@ -11,133 +11,77 @@ * for the specific language governing permissions and limitations under the License. * */ + metadata { - definition (name: "ZigBee Dimmer", namespace: "smartthings", author: "SmartThings") { - capability "Switch Level" - capability "Actuator" - capability "Switch" - capability "Configuration" - capability "Sensor" - capability "Refresh" + definition (name: "ZigBee Dimmer", namespace: "smartthings", author: "SmartThings") { + capability "Actuator" + capability "Configuration" + capability "Refresh" + capability "Sensor" + capability "Switch" + capability "Switch Level" - fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0008,0B05", outClusters: "0019" - } - // simulator metadata - simulator { - // status messages - status "on": "on/off: 1" - status "off": "on/off: 0" + fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008" + } - // reply messages - reply "zcl on-off on": "on/off: 1" - reply "zcl on-off off": "on/off: 0" - } - - 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.switch.on", backgroundColor:"#79b821", nextState:"turningOff" - attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn" - attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff" - attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.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" - } - valueTile("level", "device.level", inactiveLabel: false, decoration: "flat", width: 2, height: 2) { - state "level", label:'${currentValue} %', unit:"%", backgroundColor:"#ffffff" - } - main "switch" - details(["switch", "refresh", "level", "levelSliderControl"]) - } + 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.info description - if (description?.startsWith("catchall:")) { - def msg = zigbee.parse(description) - log.trace msg - log.trace "data: $msg.data" - } - else { - def name = description?.startsWith("on/off: ") ? "switch" : null - def value = name == "switch" ? (description?.endsWith(" 1") ? "on" : "off") : null - def result = createEvent(name: name, value: value) - log.debug "Parse returned ${result?.descriptionText}" - return result - } -} + log.debug "description is $description" -// Commands to device -def on() { - log.debug "on()" - sendEvent(name: "switch", value: "on") - "st cmd 0x${device.deviceNetworkId} ${endpointId} 6 1 {}" + def resultMap = zigbee.getKnownDescription(description) + if (resultMap) { + log.info resultMap + if (resultMap.type == "update") { + log.info "$device updates: ${resultMap.value}" + } + else { + sendEvent(name: resultMap.type, value: resultMap.value) + } + } + else { + log.warn "DID NOT PARSE MESSAGE for description : $description" + log.debug zigbee.parseDescriptionAsMap(description) + } } def off() { - log.debug "off()" - sendEvent(name: "switch", value: "off") - "st cmd 0x${device.deviceNetworkId} ${endpointId} 6 0 {}" + zigbee.off() } + +def on() { + zigbee.on() +} + def setLevel(value) { - log.trace "setLevel($value)" - def cmds = [] - - if (value == 0) { - sendEvent(name: "switch", value: "off") - cmds << "st cmd 0x${device.deviceNetworkId} ${endpointId} 6 0 {}" - } - else if (device.latestValue("switch") == "off") { - sendEvent(name: "switch", value: "on") - cmds << "st cmd 0x${device.deviceNetworkId} ${endpointId} 6 1 {}" - - } - - sendEvent(name: "level", value: value) - def level = hexString(Math.round(value * 255/100)) - cmds << "st cmd 0x${device.deviceNetworkId} ${endpointId} 8 4 {${level} 0000}" - - //log.debug cmds - cmds + zigbee.setLevel(value) } def refresh() { - [ - "st wattr 0x${device.deviceNetworkId} 1 6 0", "delay 200", - "st wattr 0x${device.deviceNetworkId} 1 8 0" - ] + zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.onOffConfig() + zigbee.levelConfig() } def configure() { - - /*log.debug "binding to switch and level control cluster" - [ - "zdo bind 0x${device.deviceNetworkId} 1 1 6 {${device.zigbeeId}} {}", "delay 200", - "zdo bind 0x${device.deviceNetworkId} 1 1 8 {${device.zigbeeId}} {}" - ] - */ - - //set transition time to 2 seconds. Not currently working. - "st wattr 0x${device.deviceNetworkId} 1 8 0x10 0x21 {1400}" -} - - - -private hex(value, width=2) { - def s = new BigInteger(Math.round(value).toString()).toString(16) - while (s.size() < width) { - s = "0" + s - } - s -} - -private getEndpointId() { - new BigInteger(device.endpointId, 16).toString() + log.debug "Configuring Reporting and Bindings." + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh() }