diff --git a/devicetypes/smartthings/aeon-home-energy-meter-c3.src/aeon-home-energy-meter-c3.groovy b/devicetypes/smartthings/aeon-home-energy-meter-c3.src/aeon-home-energy-meter-c3.groovy index 90291d5..f214597 100644 --- a/devicetypes/smartthings/aeon-home-energy-meter-c3.src/aeon-home-energy-meter-c3.groovy +++ b/devicetypes/smartthings/aeon-home-energy-meter-c3.src/aeon-home-energy-meter-c3.groovy @@ -94,11 +94,11 @@ def parse(String description) { def cmd = zwave.parse(description, [0x31: 1, 0x32: 1, 0x60: 3]) if (cmd) { result = createEvent(zwaveEvent(cmd)) + log.debug "Parse returned ${result?.descriptionText}" + storeGraphData(result.name, result.value) + } else { + log.debug "zwave.parse returned null command. Cannot create event" } - log.debug "Parse returned ${result?.descriptionText}" - - storeGraphData(result.name, result.value) - return result } diff --git a/devicetypes/smartthings/arrival-sensor-ha.src/arrival-sensor-ha.groovy b/devicetypes/smartthings/arrival-sensor-ha.src/arrival-sensor-ha.groovy index bda1d20..3175764 100644 --- a/devicetypes/smartthings/arrival-sensor-ha.src/arrival-sensor-ha.groovy +++ b/devicetypes/smartthings/arrival-sensor-ha.src/arrival-sensor-ha.groovy @@ -12,16 +12,6 @@ * */ - /* - * Purpose: Arrival Sensor HA DTH File - * - * Filename: Arrival-Sensor-HA.src/Arrival-Sensor-HA.groovy - * - * Change History: - * 1. 20160115 TW - Update/Edit to support i18n translations - * 2. 20160121 TW - Update to V4 battery calcs, added pref's page title translations - */ - metadata { definition (name: "Arrival Sensor HA", namespace: "smartthings", author: "SmartThings") { capability "Tone" diff --git a/devicetypes/smartthings/arrival-sensor-ha.src/i18n/messages.properties b/devicetypes/smartthings/arrival-sensor-ha.src/i18n/messages.properties index 12d7d2f..c5fd0c7 100644 --- a/devicetypes/smartthings/arrival-sensor-ha.src/i18n/messages.properties +++ b/devicetypes/smartthings/arrival-sensor-ha.src/i18n/messages.properties @@ -1,4 +1,3 @@ -#============================================================================== # Copyright 2016 SmartThings # # Licensed under the Apache License, Version 2.0 (the "License"); you may not @@ -12,15 +11,6 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -#============================================================================== -# Purpose: Arrival Sensor HA i18n Translation File -# -# Filename: Arrival-Sensor-HA.src/i18n/messages.properties -# -# Change History: -# 1. 20160115 TW Initial release with informal Korean translation. -# 2. 20160121 TW Added def preference section titles. -#============================================================================== # Korean (ko) # Device Preferences '''Give your device a name'''.ko=기기 이름 설정 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/ge-link-bulb.src/ge-link-bulb.groovy b/devicetypes/smartthings/ge-link-bulb.src/ge-link-bulb.groovy index c8a3c01..3e62197 100644 --- a/devicetypes/smartthings/ge-link-bulb.src/ge-link-bulb.groovy +++ b/devicetypes/smartthings/ge-link-bulb.src/ge-link-bulb.groovy @@ -1,7 +1,7 @@ /** * GE Link Bulb * - * Copyright 2014 SmartThings + * 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: @@ -53,6 +53,8 @@ metadata { capability "Polling" fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0008,1000", outClusters: "0019", manufacturer: "GE_Appliances", model: "ZLL Light", deviceJoinName: "GE Link Bulb" + fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0008,1000", outClusters: "0019", manufacturer: "GE", model: "SoftWhite", deviceJoinName: "GE Link Soft White Bulb" + fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0008,1000", outClusters: "0019", manufacturer: "GE", model: "Daylight", deviceJoinName: "GE Link Daylight Bulb" } // UI tile definitions diff --git a/devicetypes/smartthings/mobile-presence.src/i18n/messages.properties b/devicetypes/smartthings/mobile-presence.src/i18n/messages.properties index 63bec4d..bf543c7 100644 --- a/devicetypes/smartthings/mobile-presence.src/i18n/messages.properties +++ b/devicetypes/smartthings/mobile-presence.src/i18n/messages.properties @@ -1,4 +1,3 @@ -#============================================================================== # Copyright 2016 SmartThings # # Licensed under the Apache License, Version 2.0 (the "License"); you may not @@ -12,15 +11,6 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -#============================================================================== -# Purpose: Mobile Presence i18n Translation File -# -# Filename: mobile-presence.src/i18n/messages.properties -# -# Change History: -# 1. 20160205 TW Initial release with informal Korean translation. -# 2. 20160224 TW Updated with formal Korean translation. -#============================================================================== # Korean (ko) # Device Preferences '''Give your device a name'''.ko=기기 이름 설정 diff --git a/devicetypes/smartthings/mobile-presence.src/mobile-presence.groovy b/devicetypes/smartthings/mobile-presence.src/mobile-presence.groovy index b0fa346..8ed14ab 100644 --- a/devicetypes/smartthings/mobile-presence.src/mobile-presence.groovy +++ b/devicetypes/smartthings/mobile-presence.src/mobile-presence.groovy @@ -1,5 +1,4 @@ /* -=============================================================================== * Copyright 2016 SmartThings * * Licensed under the Apache License, Version 2.0 (the "License"); you may not @@ -13,14 +12,6 @@ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. -=============================================================================== - * Purpose: Mobile Presence DTH File - * - * Filename: mobile-presence.src/mobile-presence.groovy - * - * Change History: - * 1. 20160205 TW - Update/Edit to support i18n translations -=============================================================================== */ metadata { diff --git a/devicetypes/smartthings/smartpower-outlet.src/i18n/messages.properties b/devicetypes/smartthings/smartpower-outlet.src/i18n/messages.properties index 0dfd7ca..51d9d39 100644 --- a/devicetypes/smartthings/smartpower-outlet.src/i18n/messages.properties +++ b/devicetypes/smartthings/smartpower-outlet.src/i18n/messages.properties @@ -1,4 +1,3 @@ -#============================================================================== # Copyright 2016 SmartThings # # Licensed under the Apache License, Version 2.0 (the "License"); you may not @@ -12,14 +11,6 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -#============================================================================== -# Purpose: SmartPower Outlet i18n Translation File -# -# Filename: SmartPower-Outlet.src/i18n/messages.properties -# -# Change History: -# 1. 20160116 TW Initial release with informal Korean translation. -#============================================================================== # Korean (ko) # Device Preferences '''Give your device a name'''.ko=기기 이름 설정 diff --git a/devicetypes/smartthings/smartpower-outlet.src/smartpower-outlet.groovy b/devicetypes/smartthings/smartpower-outlet.src/smartpower-outlet.groovy index ec46979..1b47c3e 100644 --- a/devicetypes/smartthings/smartpower-outlet.src/smartpower-outlet.groovy +++ b/devicetypes/smartthings/smartpower-outlet.src/smartpower-outlet.groovy @@ -1,5 +1,4 @@ /* -=============================================================================== * Copyright 2016 SmartThings * * Licensed under the Apache License, Version 2.0 (the "License"); you may not @@ -13,15 +12,8 @@ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. -=============================================================================== - * Purpose: SmartPower Outlet DTH File - * - * Filename: SmartPower-Outlet.src/SmartPower-Outlet.groovy - * - * Change History: - * 1. 20160117 TW - Update/Edit to support i18n translations -=============================================================================== */ + metadata { // Automatically generated. Make future change here. definition (name: "SmartPower Outlet", namespace: "smartthings", author: "SmartThings") { @@ -137,6 +129,7 @@ def refresh() { } def configure() { + sendEvent(name: "checkInterval", value: 1200, displayed: false) zigbee.onOffConfig() + powerConfig() + refresh() } diff --git a/devicetypes/smartthings/smartsense-moisture-sensor.src/i18n/messages.properties b/devicetypes/smartthings/smartsense-moisture-sensor.src/i18n/messages.properties index 3082071..d0e1ade 100644 --- a/devicetypes/smartthings/smartsense-moisture-sensor.src/i18n/messages.properties +++ b/devicetypes/smartthings/smartsense-moisture-sensor.src/i18n/messages.properties @@ -1,4 +1,3 @@ -#============================================================================== # Copyright 2016 SmartThings # # Licensed under the Apache License, Version 2.0 (the "License"); you may not @@ -12,14 +11,6 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -#============================================================================== -# Purpose: SmartSense Moisture Sensor i18n Translation File -# -# Filename: SmartSense-Moisture-Sensor.src/i18n/messages.properties -# -# Change History: -# 1. 20160116 TW Initial release with formal Korean translation. -#============================================================================== # Korean (ko) # Device Preferences '''Dry'''.ko=건조 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 1dd3f72..de0526b 100644 --- a/devicetypes/smartthings/smartsense-moisture-sensor.src/smartsense-moisture-sensor.groovy +++ b/devicetypes/smartthings/smartsense-moisture-sensor.src/smartsense-moisture-sensor.groovy @@ -1,5 +1,4 @@ /* -=============================================================================== * Copyright 2016 SmartThings * * Licensed under the Apache License, Version 2.0 (the "License"); you may not @@ -13,15 +12,6 @@ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. -=============================================================================== - * Purpose: SmartSense Moisture Sensor DTH File - * - * Filename: SmartSense-Moisture-Sensor.src/SmartSense-Moisture-Sensor.groovy - * - * Change History: - * 1. 20160116 TW - Update/Edit to support i18n translations - * 2. 20160125 TW = Incorporated new battery mapping from TM -=============================================================================== */ metadata { @@ -321,6 +311,8 @@ def refresh() { } def configure() { + sendEvent(name: "checkInterval", value: 7200, displayed: false) + String zigbeeEui = swapEndianHex(device.hub.zigbeeEui) log.debug "Configuring Reporting, IAS CIE, and Bindings." def configCmds = [ diff --git a/devicetypes/smartthings/smartsense-motion-sensor.src/i18n/messages.properties b/devicetypes/smartthings/smartsense-motion-sensor.src/i18n/messages.properties index fa17848..fad06e0 100644 --- a/devicetypes/smartthings/smartsense-motion-sensor.src/i18n/messages.properties +++ b/devicetypes/smartthings/smartsense-motion-sensor.src/i18n/messages.properties @@ -1,4 +1,3 @@ -#============================================================================== # Copyright 2016 SmartThings # # Licensed under the Apache License, Version 2.0 (the "License"); you may not @@ -12,15 +11,6 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -#============================================================================== -# Purpose: SmartSense Motion Sensor i18n Translation File -# -# Filename: SmartSense-Motion-Sensor.src/i18n/messages.properties -# -# Change History: -# 1. 20160116 TW Initial release with formal Korean translation. -# 2. 20160224 TW Updated formal Korean translations from Mike Stoller. -#============================================================================== # Korean (ko) # Device Preferences '''battery'''.ko=배터리 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 78dd31f..29d9dd0 100644 --- a/devicetypes/smartthings/smartsense-motion-sensor.src/smartsense-motion-sensor.groovy +++ b/devicetypes/smartthings/smartsense-motion-sensor.src/smartsense-motion-sensor.groovy @@ -1,5 +1,4 @@ /* -=============================================================================== * Copyright 2016 SmartThings * * Licensed under the Apache License, Version 2.0 (the "License"); you may not @@ -13,15 +12,6 @@ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. -=============================================================================== - * Purpose: SmartSense Motion Sensor DTH File - * - * Filename: SmartSense-Motion-Sensor.src/SmartSense-Motion-Sensor.groovy - * - * Change History: - * 1. 20160116 TW - Update/Edit to support i18n translations - * 2. 20160125 TW = Incorporated new battery mapping from TM -=============================================================================== */ metadata { @@ -333,6 +323,8 @@ def refresh() { } def configure() { + sendEvent(name: "checkInterval", value: 7200, displayed: false) + String zigbeeEui = swapEndianHex(device.hub.zigbeeEui) log.debug "Configuring Reporting, IAS CIE, and Bindings." diff --git a/devicetypes/smartthings/smartsense-multi-sensor.src/i18n/messages.properties b/devicetypes/smartthings/smartsense-multi-sensor.src/i18n/messages.properties index 822300a..efcbb8e 100644 --- a/devicetypes/smartthings/smartsense-multi-sensor.src/i18n/messages.properties +++ b/devicetypes/smartthings/smartsense-multi-sensor.src/i18n/messages.properties @@ -1,4 +1,3 @@ -#============================================================================== # Copyright 2016 SmartThings # # Licensed under the Apache License, Version 2.0 (the "License"); you may not @@ -12,14 +11,6 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -#============================================================================== -# Purpose: SmartSense Multi Sensor i18n Translation File -# -# Filename: SmartSense-Multi-Sensor.src/i18n/messages.properties -# -# Change History: -# 1. 20160117 TW Initial release with informal Korean translation. -#============================================================================== # Korean (ko) # Device Preferences '''Yes'''.ko=예 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 234ce9d..892e5ad 100644 --- a/devicetypes/smartthings/smartsense-multi-sensor.src/smartsense-multi-sensor.groovy +++ b/devicetypes/smartthings/smartsense-multi-sensor.src/smartsense-multi-sensor.groovy @@ -1,5 +1,4 @@ /* -=============================================================================== * Copyright 2016 SmartThings * * Licensed under the Apache License, Version 2.0 (the "License"); you may not @@ -13,15 +12,6 @@ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. -=============================================================================== - * Purpose: SmartSense Multi Sensor DTH File - * - * Filename: SmartSense-Multi-Sensor.src/SmartSense-Multi-Sensor.groovy - * - * Change History: - * 1. 20160117 TW - Update/Edit to support i18n translations - * 2. 20160125 TW = Incorporated new battery mapping from TM -=============================================================================== */ metadata { @@ -451,6 +441,8 @@ def refresh() { } def configure() { + sendEvent(name: "checkInterval", value: 7200, displayed: false) + String zigbeeEui = swapEndianHex(device.hub.zigbeeEui) log.debug "Configuring Reporting" diff --git a/devicetypes/smartthings/smartsense-open-closed-accelerometer-sensor.src/smartsense-open-closed-accelerometer-sensor.groovy b/devicetypes/smartthings/smartsense-open-closed-accelerometer-sensor.src/smartsense-open-closed-accelerometer-sensor.groovy index 9467bdc..eb2bfdd 100644 --- a/devicetypes/smartthings/smartsense-open-closed-accelerometer-sensor.src/smartsense-open-closed-accelerometer-sensor.groovy +++ b/devicetypes/smartthings/smartsense-open-closed-accelerometer-sensor.src/smartsense-open-closed-accelerometer-sensor.groovy @@ -300,6 +300,7 @@ def getTemperature(value) { } def configure() { + sendEvent(name: "checkInterval", value: 7200, displayed: false) String zigbeeEui = swapEndianHex(device.hub.zigbeeEui) log.debug "Configuring Reporting, IAS CIE, and Bindings." 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 304dd78..a938cb9 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 @@ -252,6 +252,7 @@ def refresh() } def configure() { + sendEvent(name: "checkInterval", value: 7200, displayed: false) log.debug "Configuring Reporting and Bindings." def configCmds = [ diff --git a/devicetypes/smartthings/tile-ux/tile-multiattribute-generic.src/tile-multiattribute-generic.groovy b/devicetypes/smartthings/tile-ux/tile-multiattribute-generic.src/tile-multiattribute-generic.groovy index bb131cf..61f09d9 100644 --- a/devicetypes/smartthings/tile-ux/tile-multiattribute-generic.src/tile-multiattribute-generic.groovy +++ b/devicetypes/smartthings/tile-ux/tile-multiattribute-generic.src/tile-multiattribute-generic.groovy @@ -110,7 +110,7 @@ def installed() { sendEvent(name: "multilineText", value: "Line 1 YES\nLine 2 YES\nLine 3 NO") } -def parse() { +def parse(String description) { // This is a simulated device. No incoming data to parse. } 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..6ba2cfc --- /dev/null +++ b/devicetypes/smartthings/zll-dimmer-bulb.src/zll-dimmer-bulb.groovy @@ -0,0 +1,101 @@ +/** + * 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" + fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000, 0B04, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "Classic A60 W clear - LIGHTIFY", deviceJoinName: "OSRAM LIGHTIFY LED Smart Connected Light" + fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000", outClusters: "0019", manufacturer: "Philips", model: "LWB006", deviceJoinName: "Philips Hue White" + } + + // 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) + } +} diff --git a/smartapps/smartthings/ifttt.src/ifttt.groovy b/smartapps/smartthings/ifttt.src/ifttt.groovy index cad83d2..74dd2b2 100644 --- a/smartapps/smartthings/ifttt.src/ifttt.groovy +++ b/smartapps/smartthings/ifttt.src/ifttt.groovy @@ -131,19 +131,69 @@ def update() { def type = params.deviceType def data = request.JSON def devices = settings[type] + def device = settings[type]?.find { it.id == params.id } def command = data.command log.debug "[PROD] update, params: ${params}, request: ${data}, devices: ${devices*.id}" - if (command) { - def device = devices?.find { it.id == params.id } - if (!device) { - httpError(404, "Device not found") - } else { - device."$command"() - } + + if (!device) { + httpError(404, "Device not found") + } + + if (validateCommand(device, type, command)) { + device."$command"() + } else { + httpError(403, "Access denied. This command is not supported by current capability.") } } +/** + * Validating the command passed by the user based on capability. + * @return boolean + */ +def validateCommand(device, deviceType, command) { + def capabilityCommands = getDeviceCapabilityCommands(device.capabilities) + def currentDeviceCapability = getCapabilityName(deviceType) + if (capabilityCommands[currentDeviceCapability]) { + return command in capabilityCommands[currentDeviceCapability] ? true : false + } else { + // Handling other device types here, which don't accept commands + httpError(400, "Bad request.") + } +} + +/** + * Need to get the attribute name to do the lookup. Only + * doing it for the device types which accept commands + * @return attribute name of the device type + */ +def getCapabilityName(type) { + switch(type) { + case "switches": + return "Switch" + case "alarms": + return "Alarm" + case "locks": + return "Lock" + default: + return type + } +} + +/** + * Constructing the map over here of + * supported commands by device capability + * @return a map of device capability -> supported commands + */ +def getDeviceCapabilityCommands(deviceCapabilities) { + def map = [:] + deviceCapabilities.collect { + map[it.name] = it.commands.collect{ it.name.toString() } + } + return map +} + + def show() { def type = params.deviceType def devices = settings[type]