From 139c44a85e2ad834c72001b21c5dd6c1d4c08236 Mon Sep 17 00:00:00 2001 From: Vinay Rao Date: Mon, 31 Aug 2015 07:08:43 -0700 Subject: [PATCH] Garage door preference based DTH with icon support --- .../smartsense-multi-sensor.groovy | 94 ++++++++++++++----- 1 file changed, 72 insertions(+), 22 deletions(-) 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 df9dc8a..8f19701 100644 --- a/devicetypes/smartthings/smartsense-multi-sensor.src/smartsense-multi-sensor.groovy +++ b/devicetypes/smartthings/smartsense-multi-sensor.src/smartsense-multi-sensor.groovy @@ -30,7 +30,8 @@ fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05,FC02", outClusters: "0019", manufacturer: "CentraLite", model: "3320" fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05,FC02", outClusters: "0019", manufacturer: "CentraLite", model: "3321" fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05,FC02", outClusters: "0019", manufacturer: "CentraLite", model: "3321-S" - + + attribute "status", "string" } simulator { @@ -53,16 +54,22 @@ preferences { input description: "This feature allows you to correct any temperature variations by selecting an offset. Ex: If your sensor consistently reports a temp that's 5 degrees too warm, you'd enter \"-5\". If 3 degrees too cold, enter \"+3\".", displayDuringSetup: false, type: "paragraph", element: "paragraph" input "tempOffset", "number", title: "Temperature Offset", description: "Adjust temperature by this many degrees", range: "*..*", displayDuringSetup: false + input("garageSensor", "enum", title: "Do you want to use this sensor as tilt/garage sensor?", options: ["Yes", "No"], defaultValue: "No", required: false, displayDuringSetup: false) } tiles(scale: 2) { - multiAttributeTile(name:"contact", type: "generic", width: 6, height: 4){ - tileAttribute ("device.contact", key: "PRIMARY_CONTROL") { + multiAttributeTile(name:"status", type: "generic", width: 6, height: 4){ + tileAttribute ("device.status", key: "PRIMARY_CONTROL") { attributeState "open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e" attributeState "closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821" + attributeState "garage-open", label:'${name}', icon:"st.doors.garage.garage-open", backgroundColor:"#ffa81e" + attributeState "garage-closed", label:'${name}', icon:"st.doors.garage.garage-closed", backgroundColor:"#79b821" } } - + standardTile("contact", "device.contact", width: 2, height: 2) { + state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e") + state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821") + } standardTile("acceleration", "device.acceleration", width: 2, height: 2) { state("active", label:'${name}', icon:"st.motion.acceleration.active", backgroundColor:"#53a7c0") state("inactive", label:'${name}', icon:"st.motion.acceleration.inactive", backgroundColor:"#ffffff") @@ -91,13 +98,15 @@ } //This tile is a temporary fix so users can select main tiles again - standardTile("CONVERTED-MULTI-device.contact", "device.contact", width: 4, height: 4) { + standardTile("CONVERTED-MULTI-device.status", "device.status", width: 4, height: 4) { state "open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e" state "closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821" + state "garage-open", label:'${name}', icon:"st.doors.garage.garage-open", backgroundColor:"#ffa81e" + state "garage-closed", label:'${name}', icon:"st.doors.garage.garage-closed", backgroundColor:"#79b821" } - main(["contact", "acceleration", "temperature"]) - details(["contact", "acceleration", "temperature", "3axis", "battery", "refresh"]) + main(["status", "acceleration", "temperature"]) + details(["status", "acceleration", "temperature", "3axis", "battery", "refresh"]) } } @@ -164,11 +173,6 @@ private boolean shouldProcessMessage(cluster) { return !ignoredMessage } -//TODO: Not sure why this is here. Clean up if not required during refactor -private int getHumidity(value) { - return Math.round(Double.parseDouble(value)) -} - private Map parseReportAttributeMessage(String description) { Map descMap = (description - "read attr - ").split(",").inject([:]) { map, param -> def nameAndValue = param.split(":") @@ -209,11 +213,15 @@ private Map parseIasMessage(String description) { Map resultMap = [:] switch(msgCode) { case '0x0020': // Closed/No Motion/Dry - resultMap = getContactResult('closed') + if (garageSensor != "Yes"){ + resultMap = getContactResult('closed') + } break case '0x0021': // Open/Motion/Wet - resultMap = getContactResult('open') + if (garageSensor != "Yes"){ + resultMap = getContactResult('open') + } break case '0x0022': // Tamper Alarm @@ -223,11 +231,15 @@ private Map parseIasMessage(String description) { break case '0x0024': // Supervision Report - resultMap = getContactResult('closed') + if (garageSensor != "Yes"){ + resultMap = getContactResult('closed') + } break case '0x0025': // Restore Report - resultMap = getContactResult('open') + if (garageSensor != "Yes"){ + resultMap = getContactResult('open') + } break case '0x0026': // Trouble/Failure @@ -239,6 +251,29 @@ private Map parseIasMessage(String description) { return resultMap } +def updated() { + log.debug "updated called" + log.info "garage value : $garageSensor" + if (garageSensor == "Yes") { + def descriptionText = "Updating device to garage sensor" + if (device.latestValue("status") == "open") { + sendEvent(name: 'status', value: 'garage-open', descriptionText: descriptionText) + } + else if (device.latestValue("status") == "closed") { + sendEvent(name: 'status', value: 'garage-closed', descriptionText: descriptionText) + } + } + else { + def descriptionText = "Updating device to open/close sensor" + if (device.latestValue("status") == "garage-open") { + sendEvent(name: 'status', value: 'open', descriptionText: descriptionText) + } + else if (device.latestValue("status") == "garage-closed") { + sendEvent(name: 'status', value: 'closed', descriptionText: descriptionText) + } + } +} + def getTemperature(value) { def celsius = Integer.parseInt(value, 16).shortValue() / 100 if(getTemperatureScale() == "C"){ @@ -298,11 +333,8 @@ def getTemperature(value) { log.debug "Contact" def linkText = getLinkText(device) def descriptionText = "${linkText} was ${value == 'open' ? 'opened' : 'closed'}" - return [ - name: 'contact', - value: value, - descriptionText: descriptionText - ] + sendEvent(name: 'contact', value: value, descriptionText: descriptionText) + sendEvent(name: 'status', value: value, descriptionText: descriptionText) } private getAccelerationResult(numValue) { @@ -436,13 +468,31 @@ private Map parseAxis(String description) { def signedZ = unsignedZ > 32767 ? unsignedZ - 65536 : unsignedZ xyzResults.z = signedZ log.debug "Z Part: ${signedZ}" + if (garageSensor == "Yes") + garageEvent(signedZ) } } getXyzResult(xyzResults, description) } - +def garageEvent(zValue) { + def absValue = zValue.abs() + def contactValue = null + def garageValue = null + if (absValue>900) { + contactValue = 'closed' + garageValue = 'garage-closed' + } + else if (absValue < 100) { + contactValue = 'open' + garageValue = 'garage-open' + } + if (contactValue != null){ + sendEvent(name: 'contact', value: contactValue, descriptionText: descriptionText) + sendEvent(name: 'status', value: garageValue, descriptionText: descriptionText) + } +} private Map getXyzResult(results, description) { def name = "threeAxis"