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 ae18c1c..4cdece9 100644 --- a/devicetypes/smartthings/smartsense-multi-sensor.src/smartsense-multi-sensor.groovy +++ b/devicetypes/smartthings/smartsense-multi-sensor.src/smartsense-multi-sensor.groovy @@ -371,21 +371,50 @@ def getTemperature(value) { def refresh() { log.debug "Refreshing Values " - def refreshCmds = [ - /* sensitivity - default value (8) */ + def refreshCmds = [] - "zcl mfg-code ${manufacturerCode}", "delay 200", - "zcl global write 0xFC02 0 0x20 {02}", "delay 200", - "send 0x${device.deviceNetworkId} 1 1", "delay 400", + if (device.getDataValue("manufacturer") == "SmartThings") { + + log.debug "Refreshing Values for manufacturer: SmartThings " + refreshCmds = refreshCmds + [ - "st rattr 0x${device.deviceNetworkId} 1 0x402 0", "delay 200", - "st rattr 0x${device.deviceNetworkId} 1 1 0x20", "delay 200", + /* These values of Motion Threshold Multiplier(01) and Motion Threshold (D200) + seem to be giving pretty accurate results for the XYZ co-ordinates for this manufacturer. + Separating these out in a separate if-else because I do not want to touch Centralite part + as of now. + */ - "zcl mfg-code ${manufacturerCode}", "delay 200", - "zcl global read 0xFC02 0x0010", - "send 0x${device.deviceNetworkId} 1 1","delay 400" - ] + "zcl mfg-code ${manufacturerCode}", "delay 200", + "zcl global write 0xFC02 0 0x20 {01}", "delay 200", + "send 0x${device.deviceNetworkId} 1 1", "delay 400", + + "zcl mfg-code ${manufacturerCode}", "delay 200", + "zcl global write 0xFC02 2 0x21 {D200}", "delay 200", + "send 0x${device.deviceNetworkId} 1 1", "delay 400", + + ] + + + } else { + refreshCmds = refreshCmds + [ + + /* sensitivity - default value (8) */ + "zcl mfg-code ${manufacturerCode}", "delay 200", + "zcl global write 0xFC02 0 0x20 {02}", "delay 200", + "send 0x${device.deviceNetworkId} 1 1", "delay 400", + ] + } + + //Common refresh commands + refreshCmds = refreshCmds + [ + "st rattr 0x${device.deviceNetworkId} 1 0x402 0", "delay 200", + "st rattr 0x${device.deviceNetworkId} 1 1 0x20", "delay 200", + + "zcl mfg-code ${manufacturerCode}", "delay 200", + "zcl global read 0xFC02 0x0010", + "send 0x${device.deviceNetworkId} 1 1","delay 400" + ] return refreshCmds + enrollResponse() } @@ -461,19 +490,34 @@ private Map parseAxis(String description) { xyzResults.x = signedX log.debug "X Part: ${signedX}" } + // Y and the Z axes are interchanged between SmartThings's implementation and Centralite's implementation else if (part.startsWith("13")) { def unsignedY = hexToInt(part.split("13")[1].trim()) def signedY = unsignedY > 32767 ? unsignedY - 65536 : unsignedY - xyzResults.y = signedY - log.debug "Y Part: ${signedY}" + if (device.getDataValue("manufacturer") == "SmartThings") { + xyzResults.z = -signedY + log.debug "Z Part: ${xyzResults.z}" + if (garageSensor == "Yes") + garageEvent(xyzResults.z) + } + else { + xyzResults.y = signedY + log.debug "Y Part: ${signedY}" + } } else if (part.startsWith("14")) { def unsignedZ = hexToInt(part.split("14")[1].trim()) def signedZ = unsignedZ > 32767 ? unsignedZ - 65536 : unsignedZ - xyzResults.z = signedZ - log.debug "Z Part: ${signedZ}" - if (garageSensor == "Yes") - garageEvent(signedZ) + if (device.getDataValue("manufacturer") == "SmartThings") { + xyzResults.y = signedZ + log.debug "Y Part: ${signedZ}" + } else { + xyzResults.z = signedZ + log.debug "Z Part: ${signedZ}" + if (garageSensor == "Yes") + garageEvent(signedZ) + + } } } @@ -553,3 +597,4 @@ private byte[] reverseArray(byte[] array) { return array } + diff --git a/smartapps/com-vinli-smartthings/vinli-home-connect.src/vinli-home-connect.groovy b/smartapps/com-vinli-smartthings/vinli-home-connect.src/vinli-home-connect.groovy new file mode 100644 index 0000000..525ce6e --- /dev/null +++ b/smartapps/com-vinli-smartthings/vinli-home-connect.src/vinli-home-connect.groovy @@ -0,0 +1,189 @@ +/** + * Vinli Home Beta + * + * Copyright 2015 Daniel + * + */ +definition( + name: "Vinli Home Connect", + namespace: "com.vinli.smartthings", + author: "Daniel", + description: "Allows Vinli users to connect their car to SmartThings", + category: "SmartThings Labs", + iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png", + iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png", + iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png", + oauth: true) + +preferences { + section ("Allow external service to control these things...") { + input "switches", "capability.switch", multiple: true, required: true + input "locks", "capability.lock", multiple: true, required: true + } +} + +mappings { + + path("/devices") { + action: [ + GET: "listAllDevices" + ] + } + + path("/switches") { + action: [ + GET: "listSwitches" + ] + } + path("/switches/:command") { + action: [ + PUT: "updateSwitches" + ] + } + path("/switches/:id/:command") { + action: [ + PUT: "updateSwitch" + ] + } + path("/locks/:command") { + action: [ + PUT: "updateLocks" + ] + } + path("/locks/:id/:command") { + action: [ + PUT: "updateLock" + ] + } + + path("/devices/:id/:command") { + action: [ + PUT: "commandDevice" + ] + } +} + +// returns a list of all devices +def listAllDevices() { + def resp = [] + switches.each { + resp << [name: it.name, label: it.label, value: it.currentValue("switch"), type: "switch", id: it.id, hub: it.hub.name] + } + + locks.each { + resp << [name: it.name, label: it.label, value: it.currentValue("lock"), type: "lock", id: it.id, hub: it.hub.name] + } + return resp +} + +// returns a list like +// [[name: "kitchen lamp", value: "off"], [name: "bathroom", value: "on"]] +def listSwitches() { + def resp = [] + switches.each { + resp << [name: it.displayName, value: it.currentValue("switch"), type: "switch", id: it.id] + } + return resp +} + +void updateLocks() { + // use the built-in request object to get the command parameter + def command = params.command + + if (command) { + + // check that the switch supports the specified command + // If not, return an error using httpError, providing a HTTP status code. + locks.each { + if (!it.hasCommand(command)) { + httpError(501, "$command is not a valid command for all switches specified") + } + } + + // all switches have the comand + // execute the command on all switches + // (note we can do this on the array - the command will be invoked on every element + locks."$command"() + } +} + +void updateLock() { + def command = params.command + + locks.each { + if (!it.hasCommand(command)) { + httpError(400, "$command is not a valid command for all lock specified") + } + + if (it.id == params.id) { + it."$command"() + } + } +} + +void updateSwitch() { + def command = params.command + + switches.each { + if (!it.hasCommand(command)) { + httpError(400, "$command is not a valid command for all switches specified") + } + + if (it.id == params.id) { + it."$command"() + } + } +} + +void commandDevice() { + def command = params.command + def devices = [] + + switches.each { + devices << it + } + + locks.each { + devices << it + } + + devices.each { + if (it.id == params.id) { + if (!it.hasCommand(command)) { + httpError(400, "$command is not a valid command for specified device") + } + it."$command"() + } + } +} + +void updateSwitches() { + // use the built-in request object to get the command parameter + def command = params.command + + if (command) { + + // check that the switch supports the specified command + // If not, return an error using httpError, providing a HTTP status code. + switches.each { + if (!it.hasCommand(command)) { + httpError(400, "$command is not a valid command for all switches specified") + } + } + + // all switches have the comand + // execute the command on all switches + // (note we can do this on the array - the command will be invoked on every element + switches."$command"() + } +} + + def installed() { + log.debug "Installed with settings: ${settings}" +} + +def updated() { + log.debug "Updated with settings: ${settings}" + + unsubscribe() +}