From 7bfa0304afccb6b39e967eb7be80219b19f448f2 Mon Sep 17 00:00:00 2001 From: Zach Varberg Date: Wed, 8 Jun 2016 09:50:05 -0500 Subject: [PATCH 1/6] Update DTHs to use ZigBee library ZoneStatus This makes use of a new class exposed from the ZigBee library to automatically parse the ZoneStatus attribute bit map and expose the individual values in a simple way. This fixes a lot of unhandled cases in the previous copy-pasted switch statements, as well as allowing for a simpler interface with less copy/pasted code. --- .../nyce-motion-sensor.groovy | 50 +++---------------- .../nyce-open-closed-sensor.groovy | 33 +++++------- .../smartsense-moisture-sensor.groovy | 39 ++------------- .../smartsense-motion-sensor.groovy | 42 ++-------------- .../smartsense-motion-temp-sensor.groovy | 41 ++------------- .../smartsense-multi-sensor.groovy | 43 ++-------------- ...se-open-closed-accelerometer-sensor.groovy | 36 ++----------- .../smartsense-open-closed-sensor.groovy | 37 ++------------ .../tyco-door-window-sensor.groovy | 36 ++----------- 9 files changed, 46 insertions(+), 311 deletions(-) diff --git a/devicetypes/smartthings/nyce-motion-sensor.src/nyce-motion-sensor.groovy b/devicetypes/smartthings/nyce-motion-sensor.src/nyce-motion-sensor.groovy index c89bc03..d372c38 100644 --- a/devicetypes/smartthings/nyce-motion-sensor.src/nyce-motion-sensor.groovy +++ b/devicetypes/smartthings/nyce-motion-sensor.src/nyce-motion-sensor.groovy @@ -13,6 +13,7 @@ * for the specific language governing permissions and limitations under the License. * */ +import physicalgraph.zigbee.clusters.iaszone.ZoneStatus metadata { definition (name: "NYCE Motion Sensor", namespace: "smartthings", author: "SmartThings") { @@ -143,51 +144,14 @@ private Map parseReportAttributeMessage(String description) { private Map parseIasMessage(String description) { - List parsedMsg = description.split(' ') - String msgCode = parsedMsg[2] - - Map resultMap = [:] - switch(msgCode) { - case '0x0030': // Closed/No Motion/Dry - log.debug 'no motion' - resultMap.name = 'motion' - resultMap.value = 'inactive' - break + ZoneStatus zs = zigbee.parseZoneStatus(description) + Map resultMap = [:] - case '0x0032': // Open/Motion/Wet - log.debug 'motion' - resultMap.name = 'motion' - resultMap.value = 'active' - break + result.name = 'motion' + result.value = zs.isAlarm2Set() ? 'active' : 'inactive' + log.debug(zs.isAlarm2Set() ? 'motion' : 'no motion') - case '0x0032': // Tamper Alarm - log.debug 'motion with tamper alarm' - resultMap.name = 'motion' - resultMap.value = 'active' - break - - case '0x0033': // Battery Alarm - break - - case '0x0034': // Supervision Report - log.debug 'no motion with tamper alarm' - resultMap.name = 'motion' - resultMap.value = 'inactive' - break - - case '0x0035': // Restore Report - break - - case '0x0036': // Trouble/Failure - log.debug 'motion with failure alarm' - resultMap.name = 'motion' - resultMap.value = 'active' - break - - case '0x0038': // Test Mode - break - } - return resultMap + return resultMap } def refresh() diff --git a/devicetypes/smartthings/nyce-open-closed-sensor.src/nyce-open-closed-sensor.groovy b/devicetypes/smartthings/nyce-open-closed-sensor.src/nyce-open-closed-sensor.groovy index eef9273..506ca89 100644 --- a/devicetypes/smartthings/nyce-open-closed-sensor.src/nyce-open-closed-sensor.groovy +++ b/devicetypes/smartthings/nyce-open-closed-sensor.src/nyce-open-closed-sensor.groovy @@ -13,7 +13,10 @@ * for the specific language governing permissions and limitations under the License. * */ - + +import physicalgraph.zigbee.clusters.iaszone.ZoneStatus + + metadata { definition (name: "NYCE Open/Closed Sensor", namespace: "smartthings", author: "NYCE") { capability "Battery" @@ -219,40 +222,33 @@ private Map parseReportAttributeMessage(String description) { } private List parseIasMessage(String description) { - List parsedMsg = description.split(" ") - String msgCode = parsedMsg[2] + ZoneStatus zs = zigbee.parseZoneStatus(description) + log.debug "parseIasMessage: $description" List resultListMap = [] Map resultMap_battery = [:] Map resultMap_battery_state = [:] Map resultMap_sensor = [:] - // Relevant bit field definitions from ZigBee spec - def BATTERY_BIT = ( 1 << 3 ) - def TROUBLE_BIT = ( 1 << 6 ) - def SENSOR_BIT = ( 1 << 0 ) // it's ALARM1 bit from the ZCL spec - - // Convert hex string to integer - def zoneStatus = Integer.parseInt(msgCode[-4..-1],16) - - log.debug "parseIasMessage: zoneStatus: ${zoneStatus}" + resultMap_sensor.name = "contact" + resultMap_sensor.value = zs.isAlarm1Set() ? "open" : "closed" // Check each relevant bit, create map for it, and add to list - log.debug "parseIasMessage: Battery Status ${zoneStatus & BATTERY_BIT}" - log.debug "parseIasMessage: Trouble Status ${zoneStatus & TROUBLE_BIT}" - log.debug "parseIasMessage: Sensor Status ${zoneStatus & SENSOR_BIT}" + log.debug "parseIasMessage: Battery Status ${zs.battery}" + log.debug "parseIasMessage: Trouble Status ${zs.trouble}" + log.debug "parseIasMessage: Sensor Status ${zs.alarm1}" /* Comment out this path to check the battery state to avoid overwriting the battery value (Change log #2), but keep these conditions for later use resultMap_battery_state.name = "battery_state" - if (zoneStatus & TROUBLE_BIT) { + if (zs.isTroubleSet()) { resultMap_battery_state.value = "failed" resultMap_battery.name = "battery" resultMap_battery.value = 0 } else { - if (zoneStatus & BATTERY_BIT) { + if (zs.isBatterySet()) { resultMap_battery_state.value = "low" // to generate low battery notification by the platform @@ -270,9 +266,6 @@ private List parseIasMessage(String description) { } */ - resultMap_sensor.name = "contact" - resultMap_sensor.value = (zoneStatus & SENSOR_BIT) ? "open" : "closed" - resultListMap << resultMap_battery_state resultListMap << resultMap_battery resultListMap << resultMap_sensor 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 4e9a32c..4dafa5a 100644 --- a/devicetypes/smartthings/smartsense-moisture-sensor.src/smartsense-moisture-sensor.groovy +++ b/devicetypes/smartthings/smartsense-moisture-sensor.src/smartsense-moisture-sensor.groovy @@ -13,6 +13,8 @@ * License for the specific language governing permissions and limitations * under the License. */ +import physicalgraph.zigbee.clusters.iaszone.ZoneStatus + metadata { definition (name: "SmartSense Moisture Sensor",namespace: "smartthings", author: "SmartThings", category: "C2") { @@ -169,42 +171,9 @@ private Map parseCustomMessage(String description) { } private Map parseIasMessage(String description) { - List parsedMsg = description.split(' ') - String msgCode = parsedMsg[2] + ZoneStatus zs = zigbee.parseZoneStatus(description) - Map resultMap = [:] - switch(msgCode) { - case '0x0020': // Closed/No Motion/Dry - resultMap = getMoistureResult('dry') - break - - case '0x0021': // Open/Motion/Wet - resultMap = getMoistureResult('wet') - break - - case '0x0022': // Tamper Alarm - break - - case '0x0023': // Battery Alarm - break - - case '0x0024': // Supervision Report - log.debug 'dry with tamper alarm' - resultMap = getMoistureResult('dry') - break - - case '0x0025': // Restore Report - log.debug 'water with tamper alarm' - resultMap = getMoistureResult('wet') - break - - case '0x0026': // Trouble/Failure - break - - case '0x0028': // Test Mode - break - } - return resultMap + return zs.isAlarm1Set() ? getMoistureResult('wet') : getMoistureResult('dry') } def getTemperature(value) { 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 5d80f07..0a6f8b0 100644 --- a/devicetypes/smartthings/smartsense-motion-sensor.src/smartsense-motion-sensor.groovy +++ b/devicetypes/smartthings/smartsense-motion-sensor.src/smartsense-motion-sensor.groovy @@ -13,6 +13,8 @@ * License for the specific language governing permissions and limitations * under the License. */ +import physicalgraph.zigbee.clusters.iaszone.ZoneStatus + metadata { definition (name: "SmartSense Motion Sensor", namespace: "smartthings", author: "SmartThings", category: "C2") { @@ -182,44 +184,10 @@ private Map parseCustomMessage(String description) { } private Map parseIasMessage(String description) { - List parsedMsg = description.split(' ') - String msgCode = parsedMsg[2] + ZoneStatus zs = zigbee.parseZoneStatus(description) - Map resultMap = [:] - switch(msgCode) { - case '0x0020': // Closed/No Motion/Dry - resultMap = getMotionResult('inactive') - break - - case '0x0021': // Open/Motion/Wet - resultMap = getMotionResult('active') - break - - case '0x0022': // Tamper Alarm - log.debug 'motion with tamper alarm' - resultMap = getMotionResult('active') - break - - case '0x0023': // Battery Alarm - break - - case '0x0024': // Supervision Report - log.debug 'no motion with tamper alarm' - resultMap = getMotionResult('inactive') - break - - case '0x0025': // Restore Report - break - - case '0x0026': // Trouble/Failure - log.debug 'motion with failure alarm' - resultMap = getMotionResult('active') - break - - case '0x0028': // Test Mode - break - } - return resultMap + // Some sensor models that use this DTH use alarm1 and some use alarm2 to signify motion + return (zs.isAlarm1Set() || zs.isAlarm2Set()) ? getMotionResult('active') : getMotionResult('inactive') } def getTemperature(value) { 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 446ec70..f5ebc5f 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 @@ -15,6 +15,7 @@ */ //DEPRECATED - Using the smartsense-motion-sensor.groovy DTH for this device. Users need to be moved before deleting this DTH +import physicalgraph.zigbee.clusters.iaszone.ZoneStatus metadata { definition (name: "SmartSense Motion/Temp Sensor", namespace: "smartthings", author: "SmartThings") { @@ -168,44 +169,8 @@ private Map parseCustomMessage(String description) { } private Map parseIasMessage(String description) { - List parsedMsg = description.split(' ') - String msgCode = parsedMsg[2] - - Map resultMap = [:] - switch(msgCode) { - case '0x0020': // Closed/No Motion/Dry - resultMap = getMotionResult('inactive') - break - - case '0x0021': // Open/Motion/Wet - resultMap = getMotionResult('active') - break - - case '0x0022': // Tamper Alarm - log.debug 'motion with tamper alarm' - resultMap = getMotionResult('active') - break - - case '0x0023': // Battery Alarm - break - - case '0x0024': // Supervision Report - log.debug 'no motion with tamper alarm' - resultMap = getMotionResult('inactive') - break - - case '0x0025': // Restore Report - break - - case '0x0026': // Trouble/Failure - log.debug 'motion with failure alarm' - resultMap = getMotionResult('active') - break - - case '0x0028': // Test Mode - break - } - return resultMap + ZoneStatus zs = zigbee.parseZoneStatus(description) + return zs.isAlarm1Set() ? getMotionResult('active') : getMotionResult('inactive') } def getTemperature(value) { 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 02861cc..9bb6d2b 100644 --- a/devicetypes/smartthings/smartsense-multi-sensor.src/smartsense-multi-sensor.groovy +++ b/devicetypes/smartthings/smartsense-multi-sensor.src/smartsense-multi-sensor.groovy @@ -13,6 +13,7 @@ * License for the specific language governing permissions and limitations * under the License. */ +import physicalgraph.zigbee.clusters.iaszone.ZoneStatus metadata { definition (name: "SmartSense Multi Sensor", namespace: "smartthings", author: "SmartThings", category: "C2") { @@ -224,47 +225,13 @@ private Map parseCustomMessage(String description) { } private Map parseIasMessage(String description) { - List parsedMsg = description.split(' ') - String msgCode = parsedMsg[2] - + ZoneStatus zs = zigbee.parseZoneStatus(description) Map resultMap = [:] - switch(msgCode) { - case '0x0020': // Closed/No Motion/Dry - if (garageSensor != "Yes"){ - resultMap = getContactResult('closed') - } - break - case '0x0021': // Open/Motion/Wet - if (garageSensor != "Yes"){ - resultMap = getContactResult('open') - } - break - - case '0x0022': // Tamper Alarm - break - - case '0x0023': // Battery Alarm - break - - case '0x0024': // Supervision Report - if (garageSensor != "Yes"){ - resultMap = getContactResult('closed') - } - break - - case '0x0025': // Restore Report - if (garageSensor != "Yes"){ - resultMap = getContactResult('open') - } - break - - case '0x0026': // Trouble/Failure - break - - case '0x0028': // Test Mode - break + if(garageSensor != "Yes") { + resultMap = zs.isAlarm1Set() ? getContactResult('open') : getContactResult('closed') } + return resultMap } 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 d12124a..d398285 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 @@ -14,6 +14,7 @@ * */ //DEPRECATED - Using the smartsense-multi-sensor.groovy DTH for this device. Users need to be moved before deleting this DTH +import physicalgraph.zigbee.clusters.iaszone.ZoneStatus metadata { definition (name: "SmartSense Open/Closed Accelerometer Sensor", namespace: "smartthings", author: "SmartThings", category: "C2") { @@ -171,40 +172,9 @@ private Map parseCustomMessage(String description) { } private Map parseIasMessage(String description) { - List parsedMsg = description.split(' ') - String msgCode = parsedMsg[2] + ZoneStatus zs = zigbee.parseZoneStatus(description) - Map resultMap = [:] - switch(msgCode) { - case '0x0020': // Closed/No Motion/Dry - resultMap = getContactResult('closed') - break - - case '0x0021': // Open/Motion/Wet - resultMap = getContactResult('open') - break - - case '0x0022': // Tamper Alarm - break - - case '0x0023': // Battery Alarm - break - - case '0x0024': // Supervision Report - resultMap = getContactResult('closed') - break - - case '0x0025': // Restore Report - resultMap = getContactResult('open') - break - - case '0x0026': // Trouble/Failure - break - - case '0x0028': // Test Mode - break - } - return resultMap + return zs.isAlarm1Set() ? getContactResult('open') : getContactResult('closed') } def getTemperature(value) { 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 7ff7cb8..8133463 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 @@ -13,6 +13,7 @@ * for the specific language governing permissions and limitations under the License. * */ +import physicalgraph.zigbee.clusters.iaszone.ZoneStatus metadata { definition (name: "SmartSense Open/Closed Sensor", namespace: "smartthings", author: "SmartThings", category: "C2") { @@ -167,40 +168,8 @@ private Map parseCustomMessage(String description) { } private Map parseIasMessage(String description) { - List parsedMsg = description.split(' ') - String msgCode = parsedMsg[2] - - Map resultMap = [:] - switch(msgCode) { - case '0x0020': // Closed/No Motion/Dry - resultMap = getContactResult('closed') - break - - case '0x0021': // Open/Motion/Wet - resultMap = getContactResult('open') - break - - case '0x0022': // Tamper Alarm - break - - case '0x0023': // Battery Alarm - break - - case '0x0024': // Supervision Report - resultMap = getContactResult('closed') - break - - case '0x0025': // Restore Report - resultMap = getContactResult('open') - break - - case '0x0026': // Trouble/Failure - break - - case '0x0028': // Test Mode - break - } - return resultMap + ZoneStatus zs = zigbee.parseZoneStatus(description) + return zs.isAlarm1Set() ? getContactResult('open') : getContactResult('closed') } def getTemperature(value) { diff --git a/devicetypes/smartthings/tyco-door-window-sensor.src/tyco-door-window-sensor.groovy b/devicetypes/smartthings/tyco-door-window-sensor.src/tyco-door-window-sensor.groovy index 627ab1d..4121630 100644 --- a/devicetypes/smartthings/tyco-door-window-sensor.src/tyco-door-window-sensor.groovy +++ b/devicetypes/smartthings/tyco-door-window-sensor.src/tyco-door-window-sensor.groovy @@ -13,6 +13,7 @@ * for the specific language governing permissions and limitations under the License. * */ +import physicalgraph.zigbee.clusters.iaszone.ZoneStatus metadata { definition (name: "Tyco Door/Window Sensor", namespace: "smartthings", author: "SmartThings") { @@ -161,40 +162,9 @@ private Map parseCustomMessage(String description) { } private Map parseIasMessage(String description) { - List parsedMsg = description.split(' ') - String msgCode = parsedMsg[2] + ZoneStatus zs = zigbee.parseZoneStatus(description) - Map resultMap = [:] - switch(msgCode) { - case '0x0020': // Closed/No Motion/Dry - resultMap = getContactResult('closed') - break - - case '0x0021': // Open/Motion/Wet - resultMap = getContactResult('open') - break - - case '0x0022': // Tamper Alarm - break - - case '0x0023': // Battery Alarm - break - - case '0x0024': // Supervision Report - resultMap = getContactResult('closed') - break - - case '0x0025': // Restore Report - resultMap = getContactResult('open') - break - - case '0x0026': // Trouble/Failure - break - - case '0x0028': // Test Mode - break - } - return resultMap + return zs.isAlarm1Set() ? getContactResult('open') : getContactResult('closed') } def getTemperature(value) { From 7beb2e390520609dc4f8088b6d6507499017a8fe Mon Sep 17 00:00:00 2001 From: CosmicPuppy Date: Fri, 5 Aug 2016 01:09:32 -0700 Subject: [PATCH 2/6] Added Capability "Sensor" and/or "Actuator" per http://docs.smartthings.com/en/latest/device-type-developers-guide/overview.html?highlight=sensor%20actuator#actuator-and-sensor. There are some integrations out there using the "Actuator" and "Sensor" Capabilities and this doesn't show up for them (e.g., SmartTiles V6). --- .../smartsense-moisture-sensor.groovy | 1 + .../smartsense-motion-sensor.groovy | 1 + .../smartsense-open-closed-accelerometer-sensor.groovy | 1 + .../smartsense-temp-humidity-sensor.groovy | 1 + .../testing/simulated-alarm.src/simulated-alarm.groovy | 2 ++ .../simulated-color-control.src/simulated-color-control.groovy | 2 ++ .../simulated-contact-sensor.groovy | 1 + .../testing/simulated-lock.src/simulated-lock.groovy | 2 ++ .../simulated-motion-sensor.src/simulated-motion-sensor.groovy | 1 + .../simulated-presence-sensor.groovy | 1 + .../testing/simulated-switch.src/simulated-switch.groovy | 2 ++ .../simulated-temperature-sensor.groovy | 1 + .../simulated-thermostat.src/simulated-thermostat.groovy | 2 ++ .../simulated-water-sensor.src/simulated-water-sensor.groovy | 1 + 14 files changed, 19 insertions(+) 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 4e9a32c..c1be409 100644 --- a/devicetypes/smartthings/smartsense-moisture-sensor.src/smartsense-moisture-sensor.groovy +++ b/devicetypes/smartthings/smartsense-moisture-sensor.src/smartsense-moisture-sensor.groovy @@ -22,6 +22,7 @@ metadata { capability "Temperature Measurement" capability "Water Sensor" capability "Health Check" + capability "Sensor" command "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 5d80f07..342bd2e 100644 --- a/devicetypes/smartthings/smartsense-motion-sensor.src/smartsense-motion-sensor.groovy +++ b/devicetypes/smartthings/smartsense-motion-sensor.src/smartsense-motion-sensor.groovy @@ -22,6 +22,7 @@ metadata { capability "Temperature Measurement" capability "Refresh" capability "Health Check" + capability "Sensor" command "enrollResponse" 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 d12124a..7668ff2 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 @@ -24,6 +24,7 @@ capability "Refresh" capability "Temperature Measurement" capability "Health Check" + capability "Sensor" command "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 0476f72..e06dc78 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 @@ -21,6 +21,7 @@ metadata { capability "Temperature Measurement" capability "Relative Humidity Measurement" capability "Health Check" + capability "Sensor" fingerprint endpointId: "01", inClusters: "0001,0003,0020,0402,0B05,FC45", outClusters: "0019,0003" } diff --git a/devicetypes/smartthings/testing/simulated-alarm.src/simulated-alarm.groovy b/devicetypes/smartthings/testing/simulated-alarm.src/simulated-alarm.groovy index edb6f14..2eaab37 100644 --- a/devicetypes/smartthings/testing/simulated-alarm.src/simulated-alarm.groovy +++ b/devicetypes/smartthings/testing/simulated-alarm.src/simulated-alarm.groovy @@ -16,6 +16,8 @@ metadata { definition (name: "Simulated Alarm", namespace: "smartthings/testing", author: "SmartThings") { capability "Alarm" + capability "Sensor" + capability "Actuator" } simulator { diff --git a/devicetypes/smartthings/testing/simulated-color-control.src/simulated-color-control.groovy b/devicetypes/smartthings/testing/simulated-color-control.src/simulated-color-control.groovy index f32fa5c..487da0d 100644 --- a/devicetypes/smartthings/testing/simulated-color-control.src/simulated-color-control.groovy +++ b/devicetypes/smartthings/testing/simulated-color-control.src/simulated-color-control.groovy @@ -1,6 +1,8 @@ metadata { definition (name: "Simulated Color Control", namespace: "smartthings/testing", author: "SmartThings") { capability "Color Control" + capability "Sensor" + capability "Actuator" } simulator { diff --git a/devicetypes/smartthings/testing/simulated-contact-sensor.src/simulated-contact-sensor.groovy b/devicetypes/smartthings/testing/simulated-contact-sensor.src/simulated-contact-sensor.groovy index 46d52f8..0c520e8 100644 --- a/devicetypes/smartthings/testing/simulated-contact-sensor.src/simulated-contact-sensor.groovy +++ b/devicetypes/smartthings/testing/simulated-contact-sensor.src/simulated-contact-sensor.groovy @@ -15,6 +15,7 @@ metadata { // Automatically generated. Make future change here. definition (name: "Simulated Contact Sensor", namespace: "smartthings/testing", author: "bob") { capability "Contact Sensor" + capability "Sensor" command "open" command "close" diff --git a/devicetypes/smartthings/testing/simulated-lock.src/simulated-lock.groovy b/devicetypes/smartthings/testing/simulated-lock.src/simulated-lock.groovy index e94bec6..59e6e0d 100644 --- a/devicetypes/smartthings/testing/simulated-lock.src/simulated-lock.groovy +++ b/devicetypes/smartthings/testing/simulated-lock.src/simulated-lock.groovy @@ -15,6 +15,8 @@ metadata { // Automatically generated. Make future change here. definition (name: "Simulated Lock", namespace: "smartthings/testing", author: "bob") { capability "Lock" + capability "Sensor" + capability "Actuator" } // Simulated lock diff --git a/devicetypes/smartthings/testing/simulated-motion-sensor.src/simulated-motion-sensor.groovy b/devicetypes/smartthings/testing/simulated-motion-sensor.src/simulated-motion-sensor.groovy index 73ca0a9..cf5a773 100644 --- a/devicetypes/smartthings/testing/simulated-motion-sensor.src/simulated-motion-sensor.groovy +++ b/devicetypes/smartthings/testing/simulated-motion-sensor.src/simulated-motion-sensor.groovy @@ -15,6 +15,7 @@ metadata { // Automatically generated. Make future change here. definition (name: "Simulated Motion Sensor", namespace: "smartthings/testing", author: "bob") { capability "Motion Sensor" + capability "Sensor" command "active" command "inactive" diff --git a/devicetypes/smartthings/testing/simulated-presence-sensor.src/simulated-presence-sensor.groovy b/devicetypes/smartthings/testing/simulated-presence-sensor.src/simulated-presence-sensor.groovy index 8b075da..389122a 100644 --- a/devicetypes/smartthings/testing/simulated-presence-sensor.src/simulated-presence-sensor.groovy +++ b/devicetypes/smartthings/testing/simulated-presence-sensor.src/simulated-presence-sensor.groovy @@ -15,6 +15,7 @@ metadata { // Automatically generated. Make future change here. definition (name: "Simulated Presence Sensor", namespace: "smartthings/testing", author: "bob") { capability "Presence Sensor" + capability "Sensor" command "arrived" command "departed" diff --git a/devicetypes/smartthings/testing/simulated-switch.src/simulated-switch.groovy b/devicetypes/smartthings/testing/simulated-switch.src/simulated-switch.groovy index e4256cc..e15cf0d 100644 --- a/devicetypes/smartthings/testing/simulated-switch.src/simulated-switch.groovy +++ b/devicetypes/smartthings/testing/simulated-switch.src/simulated-switch.groovy @@ -16,6 +16,8 @@ metadata { definition (name: "Simulated Switch", namespace: "smartthings/testing", author: "bob") { capability "Switch" capability "Relay Switch" + capability "Sensor" + capability "Actuator" command "onPhysical" command "offPhysical" diff --git a/devicetypes/smartthings/testing/simulated-temperature-sensor.src/simulated-temperature-sensor.groovy b/devicetypes/smartthings/testing/simulated-temperature-sensor.src/simulated-temperature-sensor.groovy index 6d32824..bb038e3 100644 --- a/devicetypes/smartthings/testing/simulated-temperature-sensor.src/simulated-temperature-sensor.groovy +++ b/devicetypes/smartthings/testing/simulated-temperature-sensor.src/simulated-temperature-sensor.groovy @@ -16,6 +16,7 @@ metadata { definition (name: "Simulated Temperature Sensor", namespace: "smartthings/testing", author: "SmartThings") { capability "Temperature Measurement" capability "Switch Level" + capability "Sensor" command "up" command "down" diff --git a/devicetypes/smartthings/testing/simulated-thermostat.src/simulated-thermostat.groovy b/devicetypes/smartthings/testing/simulated-thermostat.src/simulated-thermostat.groovy index 229c90c..63d08f8 100644 --- a/devicetypes/smartthings/testing/simulated-thermostat.src/simulated-thermostat.groovy +++ b/devicetypes/smartthings/testing/simulated-thermostat.src/simulated-thermostat.groovy @@ -16,6 +16,8 @@ metadata { definition (name: "Simulated Thermostat", namespace: "smartthings/testing", author: "SmartThings") { capability "Thermostat" capability "Relative Humidity Measurement" + capability "Sensor" + capability "Actuator" command "tempUp" command "tempDown" diff --git a/devicetypes/smartthings/testing/simulated-water-sensor.src/simulated-water-sensor.groovy b/devicetypes/smartthings/testing/simulated-water-sensor.src/simulated-water-sensor.groovy index 74377fb..4998447 100644 --- a/devicetypes/smartthings/testing/simulated-water-sensor.src/simulated-water-sensor.groovy +++ b/devicetypes/smartthings/testing/simulated-water-sensor.src/simulated-water-sensor.groovy @@ -15,6 +15,7 @@ metadata { // Automatically generated. Make future change here. definition (name: "Simulated Water Sensor", namespace: "smartthings/testing", author: "SmartThings") { capability "Water Sensor" + capability "Sensor" command "wet" command "dry" From d68f70b3dd7362b93b2298d50bb617b7f43aee39 Mon Sep 17 00:00:00 2001 From: jackchi Date: Fri, 12 Aug 2016 14:33:42 -0700 Subject: [PATCH 3/6] [CHF-204] Implementation of PING in SmartPower Outlet --- .../smartpower-outlet.groovy | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/devicetypes/smartthings/smartpower-outlet.src/smartpower-outlet.groovy b/devicetypes/smartthings/smartpower-outlet.src/smartpower-outlet.groovy index 11febf1..4a71834 100644 --- a/devicetypes/smartthings/smartpower-outlet.src/smartpower-outlet.groovy +++ b/devicetypes/smartthings/smartpower-outlet.src/smartpower-outlet.groovy @@ -101,6 +101,12 @@ 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) + // Temporary fix for the case when Device is OFFLINE and is connected again + if (state.lastOnOff == null){ + state.lastOnOff = now() + sendEvent(name: "deviceWatch-lastActivity", value: state.lastOnOff, description: "Last Activity is on ${new Date(state.lastOnOff)}", displayed: false, isStateChange: true) + } + state.lastOnOff = now() } } else { @@ -116,9 +122,24 @@ def off() { def on() { zigbee.on() } +/** + * PING is used by Device-Watch in attempt to reach the Outlet + * */ +def ping() { + + // send read attribute onOFF if the last time we heard from the outlet is outside of the checkInterval + if (state.lastOnOff < (now() - (1000 * device.currentValue("checkInterval"))) ){ + log.info "ping, alive=no, lastOnOff=${new Date(state.lastOnOff)}" + state.lastOnOff = null + return zigbee.onOffRefresh() + } else { // if the last onOff activity is within the checkInterval we artificially create a Device-Watch event + log.info "ping, alive=yes, lastOnOff=${new Date(state.lastOnOff)}" + sendEvent(name: "deviceWatch-lastActivity", value: state.lastOnOff, description: "Last Activity is on ${new Date(state.lastOnOff)}", displayed: false, isStateChange: true) + } +} def refresh() { - zigbee.onOffRefresh() + zigbee.refreshData("0x0B04", "0x050B") + zigbee.onOffRefresh() + zigbee.electricMeasurementPowerRefresh() } def configure() { From 90384d0852bf6c05b0314224989fce5d7b7f4a2c Mon Sep 17 00:00:00 2001 From: David Sainte-Claire Date: Tue, 16 Aug 2016 11:35:04 -0700 Subject: [PATCH 4/6] DVCSMP-1959 fixed issue with logging personal information and unused subscription from SmartApps --- .../docwisdom/humidity-alert.src/humidity-alert.groovy | 4 ++-- .../dooglave/let-there-be-dark.src/let-there-be-dark.groovy | 6 +----- .../smart-humidifier.src/smart-humidifier.groovy | 6 +++--- smartapps/smartthings/its-too-cold.src/its-too-cold.groovy | 4 ++-- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/smartapps/docwisdom/humidity-alert.src/humidity-alert.groovy b/smartapps/docwisdom/humidity-alert.src/humidity-alert.groovy index 26ffeca..d194906 100644 --- a/smartapps/docwisdom/humidity-alert.src/humidity-alert.groovy +++ b/smartapps/docwisdom/humidity-alert.src/humidity-alert.groovy @@ -78,7 +78,7 @@ def humidityHandler(evt) { log.debug "Notification already sent within the last ${deltaMinutes} minutes" } else { - log.debug "Humidity Rose Above ${tooHumid}: sending SMS to $phone1 and activating ${mySwitch}" + log.debug "Humidity Rose Above ${tooHumid}: sending SMS and activating ${mySwitch}" send("${humiditySensor1.label} sensed high humidity level of ${evt.value}") switch1?.on() } @@ -91,7 +91,7 @@ def humidityHandler(evt) { log.debug "Notification already sent within the last ${deltaMinutes} minutes" } else { - log.debug "Humidity Fell Below ${notHumidEnough}: sending SMS to $phone1 and activating ${mySwitch}" + log.debug "Humidity Fell Below ${notHumidEnough}: sending SMS and activating ${mySwitch}" send("${humiditySensor1.label} sensed high humidity level of ${evt.value}") switch1?.off() } diff --git a/smartapps/dooglave/let-there-be-dark.src/let-there-be-dark.groovy b/smartapps/dooglave/let-there-be-dark.src/let-there-be-dark.groovy index 73d5d46..11a986c 100644 --- a/smartapps/dooglave/let-there-be-dark.src/let-there-be-dark.groovy +++ b/smartapps/dooglave/let-there-be-dark.src/let-there-be-dark.groovy @@ -25,14 +25,10 @@ preferences { def installed() { subscribe(contact1, "contact", contactHandler) - subscribe(switch1, "switch.on", switchOnHandler) - subscribe(switch1, "switch.off", switchOffHandler) } def updated() { unsubscribe() - subscribe(contact1, "contact", contactHandler) - subscribe(switch1, "switch.on", switchOnHandler) subscribe(switch1, "switch.off", switchOffHandler) } @@ -46,4 +42,4 @@ def contactHandler(evt) { if (evt.value == "closed") { if(state.wasOn)switch1.on() } -} \ No newline at end of file +} diff --git a/smartapps/sheikhsphere/smart-humidifier.src/smart-humidifier.groovy b/smartapps/sheikhsphere/smart-humidifier.src/smart-humidifier.groovy index c489a22..eaf30ba 100644 --- a/smartapps/sheikhsphere/smart-humidifier.src/smart-humidifier.groovy +++ b/smartapps/sheikhsphere/smart-humidifier.src/smart-humidifier.groovy @@ -77,7 +77,7 @@ def humidityHandler(evt) { } else { if (state.lastStatus != "off") { - log.debug "Humidity Rose Above $humidityHigh1: sending SMS to $phone1 and deactivating $mySwitch" + log.debug "Humidity Rose Above $humidityHigh1: sending SMS and deactivating $mySwitch" send("${humiditySensor1.label} sensed high humidity level of ${evt.value}, turning off ${switch1.label}") switch1?.off() state.lastStatus = "off" @@ -99,7 +99,7 @@ def humidityHandler(evt) { } else { if (state.lastStatus != "on") { - log.debug "Humidity Dropped Below $humidityLow1: sending SMS to $phone1 and activating $mySwitch" + log.debug "Humidity Dropped Below $humidityLow1: sending SMS and activating $mySwitch" send("${humiditySensor1.label} sensed low humidity level of ${evt.value}, turning on ${switch1.label}") switch1?.on() state.lastStatus = "on" @@ -125,4 +125,4 @@ private send(msg) { } log.debug msg -} \ No newline at end of file +} diff --git a/smartapps/smartthings/its-too-cold.src/its-too-cold.groovy b/smartapps/smartthings/its-too-cold.src/its-too-cold.groovy index 8364c20..e06f8a2 100644 --- a/smartapps/smartthings/its-too-cold.src/its-too-cold.groovy +++ b/smartapps/smartthings/its-too-cold.src/its-too-cold.groovy @@ -69,10 +69,10 @@ def temperatureHandler(evt) { def alreadySentSms = recentEvents.count { it.doubleValue <= tooCold } > 1 if (alreadySentSms) { - log.debug "SMS already sent to $phone1 within the last $deltaMinutes minutes" + log.debug "SMS already sent within the last $deltaMinutes minutes" // TODO: Send "Temperature back to normal" SMS, turn switch off } else { - log.debug "Temperature dropped below $tooCold: sending SMS to $phone1 and activating $mySwitch" + log.debug "Temperature dropped below $tooCold: sending SMS and activating $mySwitch" def tempScale = location.temperatureScale ?: "F" send("${temperatureSensor1.displayName} is too cold, reporting a temperature of ${evt.value}${evt.unit?:tempScale}") switch1?.on() From 0d4a00ae2b83fef95ae4d87c2f922f4d2dc2f88e Mon Sep 17 00:00:00 2001 From: David Sainte-Claire Date: Tue, 16 Aug 2016 11:46:47 -0700 Subject: [PATCH 5/6] fixed wrong subscription based on code review comment --- .../dooglave/let-there-be-dark.src/let-there-be-dark.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smartapps/dooglave/let-there-be-dark.src/let-there-be-dark.groovy b/smartapps/dooglave/let-there-be-dark.src/let-there-be-dark.groovy index 11a986c..3e9d99d 100644 --- a/smartapps/dooglave/let-there-be-dark.src/let-there-be-dark.groovy +++ b/smartapps/dooglave/let-there-be-dark.src/let-there-be-dark.groovy @@ -29,7 +29,7 @@ def installed() { def updated() { unsubscribe() - subscribe(switch1, "switch.off", switchOffHandler) + subscribe(contact1, "contact", contactHandler) } def contactHandler(evt) { From 4866ecd2043900e8bec4c1bc8e1c5fbf467e88ce Mon Sep 17 00:00:00 2001 From: Matthew Moore Date: Tue, 16 Aug 2016 13:52:53 -0700 Subject: [PATCH 6/6] DVCSMP-1959: remove logging of phone number in barkley been fed --- .../has-barkley-been-fed.src/has-barkley-been-fed.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smartapps/smartthings/has-barkley-been-fed.src/has-barkley-been-fed.groovy b/smartapps/smartthings/has-barkley-been-fed.src/has-barkley-been-fed.groovy index 31faa2d..28cca95 100644 --- a/smartapps/smartthings/has-barkley-been-fed.src/has-barkley-been-fed.groovy +++ b/smartapps/smartthings/has-barkley-been-fed.src/has-barkley-been-fed.groovy @@ -68,7 +68,7 @@ def scheduleCheck() sendNotificationToContacts("No one has fed the dog", recipients) } else { - log.debug "Feeder was not opened since $midnight, texting $phone1" + log.debug "Feeder was not opened since $midnight, texting one phone number" sendSms(phone1, "No one has fed the dog") } }