Compare commits

..

25 Commits

Author SHA1 Message Date
Eugen Valeriu
d18774081a MSA-1839: SmartThings in any respect whatsoever. 2017-03-14 13:13:02 -07:00
Tyler Lange
2ae163b10b Merge pull request #1764 from CosmicPuppy/ActionTiles-Fibaro-CapabilitySensorPatch
To Fibaro Flood Sensor DTHs, added Capability "Sensor" per http://doc…
2017-03-13 10:27:41 -07:00
CosmicPuppy
e3168793bd To Fibaro Flood Sensor DTHs, added Capability "Sensor" per http://docs.smartthings.com/en/latest/device-type-developers-guide/overview.html?highlight=sensor%20actuator#actuator-and-sensor.
There are some SmartApps out there using the "Actuator" and "Sensor" Capabilities and this Device doesn't show up for them (e.g., ActionTiles).
2017-03-11 00:47:36 -08:00
Tyler Lange
0baa986c61 Merge pull request #1762 from CosmicPuppy/ActionTiles-Nyce-CapabilitySensorPatch
To Nyce sensor DTHs, added Capability "Sensor" per http://docs.smartt…
2017-03-09 12:53:49 -08:00
CosmicPuppy
8484f18a0e To Nyce sensor DTHs, added Capability "Sensor" per http://docs.smartthings.com/en/latest/device-type-developers-guide/overview.html?highlight=sensor%20actuator#actuator-and-sensor.
There are some SmartApps out there using the "Actuator" and "Sensor" Capabilities and this Device doesn't show up for them (e.g., ActionTiles).
2017-03-09 00:05:14 -08:00
Vinay Rao
cb6377886d Merge pull request #1755 from SmartThingsCommunity/staging
Rolling down staging to master
2017-03-07 13:54:54 -08:00
Vinay Rao
90fb9251a6 Merge pull request #1753 from SmartThingsCommunity/production
Rolling down production to staging
2017-03-07 13:27:02 -08:00
Vinay Rao
195e0babb2 Merge pull request #1752 from larsfinander/DVCSMP-2497_OpenT2T_Update_3_5_submission_staging
DVCSMP-2497 OpenT2T: Update to 3/5 submission
2017-03-06 20:52:51 -08:00
Lars Finander
065715f296 DVCSMP-2497 OpenT2T: Update to 3/5 submission 2017-03-06 21:43:42 -07:00
tslagle13
a544e2f019 Merge pull request #1712 from SmartThingsCommunity/MSA-1803-1
MSA-1803: Gideon Smart home smartapp
2017-03-06 12:07:11 -08:00
Vinay Rao
10acb76b34 Merge pull request #1747 from workingmonk/feature/zwave_chf_prod
[CHF-532] [CHF-533] Health Check Z-Wave Sleepy Fibaro Sensors
2017-03-05 13:29:49 -08:00
Jack Chi
4fc046f57f [CHF-532] [CHF-533] Health Check Z-Wave Sleepy Fibaro Sensors (#1741) 2017-03-05 13:26:30 -08:00
Vinay Rao
ff2e70b011 Merge pull request #1744 from workingmonk/feature/na04_deploy_tag
TECHOPS-1788 update deploy script
2017-03-03 16:37:42 -08:00
Vinay Rao
79e2789f68 TECHOPS-1788 update deploy script 2017-03-03 16:32:32 -08:00
Vinay Rao
a777c298ca Merge pull request #1743 from dbradmit/shabbat-zipcode-fix
Update shabbat-and-holiday-modes.groovy
2017-03-03 04:04:00 -08:00
Jack Chi
94a87e5c7f [CHF-532] [CHF-533] Health Check Z-Wave Sleepy Fibaro Sensors (#1741) 2017-03-02 17:53:17 -08:00
Vinay Rao
22be8ef2e8 Merge pull request #1739 from larsfinander/DVCSMP-2487_OpenT2T_Update_to_3_2_submission_staging
DVCSMP-2487 OpenT2T: Update to 3/2 submission
2017-03-02 11:26:42 -08:00
Lars Finander
2f20a339c3 DVCSMP-2487 OpenT2T: Update to 3/2 submission 2017-03-02 12:16:03 -07:00
Vinay Rao
ab79ceb857 Merge pull request #1728 from SmartThingsCommunity/staging
Rolling up staging to production
2017-02-28 14:01:19 -08:00
Nicola Russo
a583a25ef3 MSA-1803: A simple web service smartapp that allows the users to control their devices through Gideon Smart home app. 2017-02-23 15:31:44 -08:00
Vinay Rao
2151e2dd3e Merge pull request #1706 from SmartThingsCommunity/staging
Rolling up staging to production for deploy
2017-02-22 13:44:57 -08:00
Vinay Rao
bfd2b6c0fa Merge pull request #1674 from SmartThingsCommunity/staging
Rolling up staging to production
2017-02-14 12:09:12 -08:00
Vinay Rao
fc312286a2 Merge pull request #1653 from SmartThingsCommunity/staging
Rolling up staging to production for deploy
2017-02-07 14:21:49 -08:00
Vinay Rao
0846b6f34c Merge pull request #1629 from SmartThingsCommunity/staging
Rolling up staging to production
2017-01-31 13:25:26 -08:00
dbradmit
a15ca97988 Update shabbat-and-holiday-modes.groovy 2017-01-24 19:16:10 -07:00
13 changed files with 1425 additions and 156 deletions

View File

@@ -9,7 +9,7 @@ apply plugin: 'smartthings-slack'
buildscript {
dependencies {
classpath "com.smartthings.deployment:executable-deployment-scripts:1.0.8"
classpath "com.smartthings.deployment:executable-deployment-scripts:1.0.11"
}
repositories {
mavenLocal()

View File

@@ -21,6 +21,7 @@ metadata {
capability "Tamper Alert"
capability "Temperature Measurement"
capability "Water Sensor"
capability "Health Check"
fingerprint deviceId: "0x0701", inClusters: "0x5E, 0x22, 0x85, 0x59, 0x20, 0x80, 0x70, 0x56, 0x5A, 0x7A, 0x72, 0x8E, 0x71, 0x73, 0x98, 0x9C, 0x31, 0x86", outClusters: ""
}
@@ -228,7 +229,9 @@ def zwaveEvent(physicalgraph.zwave.commands.deviceresetlocallyv1.DeviceResetLoca
def configure() {
log.debug "Executing 'configure'"
// Device-Watch simply pings if no device events received for 8 hrs & 2 minutes
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
def cmds = []
cmds += zwave.wakeUpV2.wakeUpIntervalSet(seconds:21600, nodeid: zwaveHubNodeId)//FGFS' default wake up interval

View File

@@ -22,6 +22,7 @@ metadata {
capability "Sensor"
capability "Tamper Alert"
capability "Temperature Measurement"
capability "Health Check"
fingerprint deviceId: "0x0701", inClusters: "0x5E, 0x20, 0x86, 0x72, 0x5A, 0x59, 0x85, 0x73, 0x84, 0x80, 0x71, 0x56, 0x70, 0x31, 0x8E, 0x22, 0x30, 0x9C, 0x98, 0x7A", outClusters: ""
}
@@ -240,7 +241,9 @@ def zwaveEvent(physicalgraph.zwave.commands.deviceresetlocallyv1.DeviceResetLoca
def configure() {
log.debug "Executing 'configure'"
// Device-Watch simply pings if no device events received for 8 hrs & 2 minutes
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
def cmds = []
cmds += zwave.wakeUpV2.wakeUpIntervalSet(seconds: 7200, nodeid: zwaveHubNodeId)//FGMS' default wake up interval

View File

@@ -0,0 +1,250 @@
/**
* Raspberry Pi
*
* Copyright 2014 Nicholas Wilde
*
* Monitor your Raspberry Pi using SmartThings and WebIOPi <https://code.google.com/p/webiopi/>
*
* Companion WebIOPi python script can be found here:
* <https://github.com/nicholaswilde/smartthings/blob/master/device-types/raspberry-pi/raspberrypi.py>
*
* 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.
*
*/
import groovy.json.JsonSlurper
preferences {
input("ip", "string", title:"IP Address", description: "192.168.1.150", required: true, displayDuringSetup: true)
input("port", "string", title:"Port", description: "8000", defaultValue: 8000 , required: true, displayDuringSetup: true)
input("username", "string", title:"Username", description: "webiopi", required: true, displayDuringSetup: true)
input("password", "password", title:"Password", description: "Password", required: true, displayDuringSetup: true)
}
metadata {
definition (name: "Raspberry Pi", namespace: "nicholaswilde/smartthings", author: "Nicholas Wilde") {
capability "Polling"
capability "Refresh"
capability "Temperature Measurement"
capability "Switch"
capability "Sensor"
capability "Actuator"
attribute "cpuPercentage", "string"
attribute "memory", "string"
attribute "diskUsage", "string"
command "restart"
}
simulator {
// TODO: define status and reply messages here
}
tiles {
valueTile("temperature", "device.temperature", width: 1, height: 1) {
state "temperature", label:'${currentValue}° CPU', unit: "F",
backgroundColors:[
[value: 25, color: "#153591"],
[value: 35, color: "#1e9cbb"],
[value: 47, color: "#90d2a7"],
[value: 59, color: "#44b621"],
[value: 67, color: "#f1d801"],
[value: 76, color: "#d04e00"],
[value: 77, color: "#bc2323"]
]
}
standardTile("button", "device.switch", width: 1, height: 1, canChangeIcon: true) {
state "off", label: 'Off', icon: "st.Electronics.electronics18", backgroundColor: "#ffffff", nextState: "on"
state "on", label: 'On', icon: "st.Electronics.electronics18", backgroundColor: "#79b821", nextState: "off"
}
valueTile("cpuPercentage", "device.cpuPercentage", inactiveLabel: false) {
state "default", label:'${currentValue}% CPU', unit:"Percentage",
backgroundColors:[
[value: 31, color: "#153591"],
[value: 44, color: "#1e9cbb"],
[value: 59, color: "#90d2a7"],
[value: 74, color: "#44b621"],
[value: 84, color: "#f1d801"],
[value: 95, color: "#d04e00"],
[value: 96, color: "#bc2323"]
]
}
valueTile("memory", "device.memory", width: 1, height: 1) {
state "default", label:'${currentValue} MB', unit:"MB",
backgroundColors:[
[value: 353, color: "#153591"],
[value: 287, color: "#1e9cbb"],
[value: 210, color: "#90d2a7"],
[value: 133, color: "#44b621"],
[value: 82, color: "#f1d801"],
[value: 26, color: "#d04e00"],
[value: 20, color: "#bc2323"]
]
}
valueTile("diskUsage", "device.diskUsage", width: 1, height: 1) {
state "default", label:'${currentValue}% Disk', unit:"Percent",
backgroundColors:[
[value: 31, color: "#153591"],
[value: 44, color: "#1e9cbb"],
[value: 59, color: "#90d2a7"],
[value: 74, color: "#44b621"],
[value: 84, color: "#f1d801"],
[value: 95, color: "#d04e00"],
[value: 96, color: "#bc2323"]
]
}
standardTile("restart", "device.restart", inactiveLabel: false, decoration: "flat") {
state "default", action:"restart", label: "Restart", displayName: "Restart"
}
standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat") {
state "default", action:"refresh.refresh", icon: "st.secondary.refresh"
}
main "button"
details(["button", "temperature", "cpuPercentage", "memory" , "diskUsage", "restart", "refresh"])
}
}
// ------------------------------------------------------------------
// parse events into attributes
def parse(String description) {
def map = [:]
def descMap = parseDescriptionAsMap(description)
//log.debug descMap
def body = new String(descMap["body"].decodeBase64())
//log.debug "body: ${body}"
def slurper = new JsonSlurper()
def result = slurper.parseText(body)
log.debug "result: ${result}"
if (result){
log.debug "Computer is up"
sendEvent(name: "switch", value: "on")
}
if (result.containsKey("cpu_temp")) {
sendEvent(name: "temperature", value: result.cpu_temp)
}
if (result.containsKey("cpu_perc")) {
sendEvent(name: "cpuPercentage", value: result.cpu_perc)
}
if (result.containsKey("mem_avail")) {
log.debug "mem_avail: ${result.mem_avail}"
sendEvent(name: "memory", value: result.mem_avail)
}
if (result.containsKey("disk_usage")) {
log.debug "disk_usage: ${result.disk_usage}"
sendEvent(name: "diskUsage", value: result.disk_usage)
}
}
// handle commands
def poll() {
log.debug "Executing 'poll'"
sendEvent(name: "switch", value: "off")
getRPiData()
}
def refresh() {
sendEvent(name: "switch", value: "off")
log.debug "Executing 'refresh'"
getRPiData()
}
def restart(){
log.debug "Restart was pressed"
sendEvent(name: "switch", value: "off")
def uri = "/macros/reboot"
postAction(uri)
}
// Get CPU percentage reading
private getRPiData() {
def uri = "/macros/getData"
postAction(uri)
}
// ------------------------------------------------------------------
private postAction(uri){
setDeviceNetworkId(ip,port)
def userpass = encodeCredentials(username, password)
def headers = getHeader(userpass)
def hubAction = new physicalgraph.device.HubAction(
method: "POST",
path: uri,
headers: headers
)//,delayAction(1000), refresh()]
log.debug("Executing hubAction on " + getHostAddress())
//log.debug hubAction
hubAction
}
// ------------------------------------------------------------------
// Helper methods
// ------------------------------------------------------------------
def parseDescriptionAsMap(description) {
description.split(",").inject([:]) { map, param ->
def nameAndValue = param.split(":")
map += [(nameAndValue[0].trim()):nameAndValue[1].trim()]
}
}
private encodeCredentials(username, password){
log.debug "Encoding credentials"
def userpassascii = "${username}:${password}"
def userpass = "Basic " + userpassascii.encodeAsBase64().toString()
//log.debug "ASCII credentials are ${userpassascii}"
//log.debug "Credentials are ${userpass}"
return userpass
}
private getHeader(userpass){
log.debug "Getting headers"
def headers = [:]
headers.put("HOST", getHostAddress())
headers.put("Authorization", userpass)
//log.debug "Headers are ${headers}"
return headers
}
private delayAction(long time) {
new physicalgraph.device.HubAction("delay $time")
}
private setDeviceNetworkId(ip,port){
def iphex = convertIPtoHex(ip)
def porthex = convertPortToHex(port)
device.deviceNetworkId = "$iphex:$porthex"
log.debug "Device Network Id set to ${iphex}:${porthex}"
}
private getHostAddress() {
return "${ip}:${port}"
}
private String convertIPtoHex(ipAddress) {
String hex = ipAddress.tokenize( '.' ).collect { String.format( '%02x', it.toInteger() ) }.join()
return hex
}
private String convertPortToHex(port) {
String hexport = port.toString().format( '%04x', port.toInteger() )
return hexport
}

View File

@@ -0,0 +1,277 @@
/**
* Live Code Friday Virtual Device Manager
*
* Copyright 2015 Patrick Stuart
*
* 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.
*
* Tasks
Create a dynamic pages interface
Pick a device type
add/delete that child
*/
definition(
name: "Live Code Friday Virtual Device Manager",
namespace: "pstuart",
author: "Patrick Stuart",
description: "Live Code Friday Virtual Device Manager",
category: "My Apps",
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",
singleInstance: true)
preferences {
page(name: "firstPage")
page(name: "inputPage")
page(name: "devicePage")
page(name: "addDevicePage")
page(name: "viewDevicePage")
page(name: "deletePage")
}
def firstPage() {
dynamicPage(name: "firstPage", title: "Where to first?", install: true, uninstall: true) {
section("Main Menu") {
paragraph "Version 1.2"
href(page: "inputPage", title: "Let's Add Devices!")
}
/*
section("Later") {
paragraph "More to come..."
}
*/
}
}
def inputPage() {
dynamicPage(name: "inputPage", title: "Choose What Device Type You Want To Add", nextPage:"firstPage") {
section("Device Types") {
href(page: "devicePage", title: "Switches", params: [device: "Generic Switch"])
href(page: "devicePage", title: "Dimmers", params: [device: "Generic Dimmer"])
href(page: "devicePage", title: "Contact Sensor", params: [device: "Generic Contact"])
}
section("Later") {
paragraph "more devices coming soon"
}
section("Navigation") {
href(page: "firstPage", title: "Main Menu")
}
}
}
def devicePage(params) {
dynamicPage(name: "devicePage", title: "Devices", nextPage:"inputPage") {
// Loop childDevices based on type
// match up types
def device = params.device
log.debug "Hit Device Page with the selector device type $device"
def deviceTitle = device + "s"
if (device?.endsWith('ch') || device?.endsWith('s') || device?.endsWith('x')) {
deviceTitle = device + "es"
}
log.debug "Device Title is $deviceTitle"
section("Installed ${deviceTitle}") {
def childDevices = getChildDevices()
log.debug "The Child Devices are $childDevices"
if (childDevices) {
def devices = "Switches Installed:\r\nThis is a second line\r\n"
log.debug "Inside childDevices if statement"
childDevices.findAll { it.typeName == device }
.each {
log.debug "The child device id is $it.deviceNetworkId and the type is $it"
def test = it.typeName
log.debug "Testing $test"
//def tempDevice = getChildDevice(it)
//log.debug tempDevice
//devices = devices + "test\r\n"
switch(it.typeName) {
case "Generic Switch" :
href(page: "viewDevicePage", title: it.name, params: [dni: it.deviceNetworkId])
break
case "Generic Dimmer" :
href(page: "viewDevicePage", title: it.name, params: [dni: it.deviceNetworkId])
break
case "Generic Contact" :
href(page: "viewDevicePage", title: it.name, params: [dni: it.deviceNetworkId])
break
default : break
}
}
} else {
paragraph "No Virtual Generic Devices are Installed"
}
}
section("Add A ${params.device}") { //${params.device}
// List Switches getChildDevices()
// Add A Switch addChildDevice()
// View A Switch / Delete that switch go to switch view
input("DeviceName", "text")
href(page: "addDevicePage", title: "New $device", params: [type: device])
}
section("Navigation") {
href(page: "firstPage", title: "Main Menu")
}
}
}
def addDevicePage(params) {
dynamicPage(name: "addDevicePage", title: "New $params.type", nextPage:"devicePage") {
section("New $params.type Add Result") {
//add new virtual switch
log.debug "Add Device Page hit with params $params and $settings.DeviceName"
def newDeviceName = params.type
if (settings.DeviceName) {
newDeviceName = settings.DeviceName
}
def result = addChildDevice(params.type, newDeviceName)
paragraph "$params.type Added ${result}"
href(page: "devicePage", title: "Devices")
}
section("Navigation") {
href(page: "firstPage", title: "Main Menu")
}
}
}
def viewDevicePage(params) {
dynamicPage(name: "viewDevicePage", title: "Switch", nextPage:"devicePage") {
def viewSwitch = getChildDevice(params.dni)
section("$viewSwitch.name") {
paragraph "Switch Details \r\nName: $viewSwitch.name\r\nType: $viewSwitch.typeName\r\nNetwork ID: $viewSwitch.deviceNetworkId\r\nStates\r\nSwitch: ${viewSwitch.currentState('switch').value}\r\n" // Create info about switch / child device
log.debug viewSwitch.currentState('switch').value
href(page: "deletePage", title: "Delete", params: [dni: params.dni])
}
section("Navigation") {
href(page: "firstPage", title: "Main Menu")
}
}
}
def deletePage(params) {
dynamicPage(name: "deletePage", title: "Delete", nextPage:"devicePage") {
section("switch") {
paragraph "Deleted Switch with DNI of $params.dni"
log.debug "Deleting $params.dni"
//def delete = getChildDevices().findAll { it?.contains(params.dni) }
//log.debug delete
def delete = getChildDevice(params.dni)
//removeChildDevices(delete)
deleteChildDevice(delete.deviceNetworkId)
href(page: "switchPage", title: "Switches")
}
section("Navigation") {
href(page: "firstPage", title: "Main Menu")
}
}
}
def installed() {
log.debug "Installed with settings: ${settings}"
initialize()
}
def updated() {
log.debug "Updated with settings: ${settings}"
unsubscribe()
initialize()
}
def initialize() {
// TODO: subscribe to attributes, devices, locations, etc.
def switches = getChildDevices()
switches.each {
if (!it.currentValue('switch') ) {
it.off()
}
}
}
def addChildDevice(params, deviceName) {
//Get all devices installed as children
def childDevices = getChildDevices() //.findAll{ it -> it.type == params } //Find device of type params.type
//def collectDevices = childDevices.collect{ getChildDevice(it).type ?: 0}
//log.debug "The result of collectDevices is $collectDevices"
def gTypes = genericTypes()
log.debug gTypes
def subChildDevices = childDevices?.findAll { it -> it.typeName == params }
log.debug "The subset of child devices is $subChildDevices based on type $params"
def counter = subChildDevices?.size() + 1
log.debug "$subChildDevices and counter is $counter"
/*
def counters = [:]
childDevices.each {
def childDevice = getChildDevice(it)
log.debug "Child Device type is $childDevice.type"
gTypes.each {
if (it == childDevice.type) {
def counter = ["name" : params.type, "counter" : counter++ ]
}
}
} */
//def counter = childDevices.size() + 1 //TODO Fix counter for each type
def dni = "pstuartDevice_$counter" // TODO create random string /guid
def newDeviceName = "$params $counter"
if (deviceName != params) {
newDeviceName = deviceName
}
log.debug newDeviceName
log.debug dni
log.debug params
log.trace "just about to add childe device"
def childDevice = addChildDevice("pstuart", params, dni, null, [name:newDeviceName])
log.debug childDevice
childDevice.off()
return childDevice
//return dni
}
def genericTypes() {
def gTypes = [
"Generic Switch",
"Generic Contact",
"Generic Dimmer",
]
return gTypes
}

View File

@@ -39,6 +39,8 @@ metadata {
capability "Temperature Measurement"
capability "Configuration"
capability "Battery"
capability "Health Check"
capability "Sensor"
command "resetParams2StDefaults"
command "listCurrentParams"
@@ -304,6 +306,9 @@ def lateConfigure(setConf = False) {
*/
def configure() {
log.debug "Configuring Device..."
// Device-Watch simply pings if no device events received for 8 hrs & 2 minutes
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
def cmds = []
// send associate to group 2 to get alarm data

View File

@@ -46,6 +46,7 @@
capability "Illuminance Measurement"
capability "Sensor"
capability "Battery"
capability "Health Check"
command "resetParams2StDefaults"
command "listCurrentParams"
@@ -125,6 +126,9 @@
*/
def configure() {
log.debug "Configuring Device For SmartThings Use"
// Device-Watch simply pings if no device events received for 8 hrs & 2 minutes
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
def cmds = []
// send associate to group 3 to get sensor data reported only to hub

View File

@@ -21,6 +21,7 @@ metadata {
capability "Configuration"
capability "Battery"
capability "Refresh"
capability "Sensor"
command "enrollResponse"

View File

@@ -24,6 +24,7 @@ metadata {
capability "Contact Sensor"
capability "Refresh"
capability "Health Check"
capability "Sensor"
command "enrollResponse"

View File

@@ -0,0 +1,794 @@
/**
* Gideon
*
* Copyright 2016 Nicola Russo
*
* 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.
*
*/
definition(
name: "Gideon Smart Home",
namespace: "gideon.api",
author: "Braindrain Solutions ltd",
description: "Gideon Smart Home SmartApp allows you to connect and control all of your SmartThings devices through the Gideon app, making your SmartThings devices even smarter.",
category: "Family",
iconUrl: "http://s33.postimg.org/t77u7y7v3/logo.png",
iconX2Url: "http://s33.postimg.org/t77u7y7v3/logo.png",
iconX3Url: "http://s33.postimg.org/t77u7y7v3/logo.png",
oauth: [displayName: "Gideon Smart Home API app", displayLink: "gideon.ai"])
preferences {
section("Control these contact sensors...") {
input "contact", "capability.contactSensor", multiple:true, required:false
}
section("Control these switch levels...") {
input "switchlevels", "capability.switchLevel", multiple:true, required:false
}
/* section("Control these thermostats...") {
input "thermostats", "capability.thermostat", multiple:true, required:false
}*/
section("Control the color for these devices...") {
input "colors", "capability.colorControl", multiple:true, required:false
}
section("Control the color temperature for these devices...") {
input "kelvin", "capability.colorTemperature", multiple:true, required:false
}
section("Control these switches...") {
input "switches", "capability.switch", multiple:true, required:false
}
section("Control these smoke alarms...") {
input "smoke_alarms", "capability.smokeDetector", multiple:true, required:false
}
section("Control these window shades...") {
input "shades", "capability.windowShade", multiple:true, required:false
}
section("Control these garage doors...") {
input "garage", "capability.garageDoorControl", multiple:true, required:false
}
section("Control these water sensors...") {
input "water_sensors", "capability.waterSensor", multiple:true, required:false
}
section("Control these motion sensors...") {
input "motions", "capability.motionSensor", multiple:true, required:false
}
section("Control these presence sensors...") {
input "presence_sensors", "capability.presenceSensor", multiple:true, required:false
}
section("Control these outlets...") {
input "outlets", "capability.outlet", multiple:true, required:false
}
section("Control these power meters...") {
input "meters", "capability.powerMeter", multiple:true, required:false
}
section("Control these locks...") {
input "locks", "capability.lock", multiple:true, required:false
}
section("Control these temperature sensors...") {
input "temperature_sensors", "capability.temperatureMeasurement", multiple:true, required:false
}
section("Control these batteries...") {
input "batteries", "capability.battery", multiple:true, required:false
}
}
def installed() {
log.debug "Installed with settings: ${settings}"
initialize()
}
def updated() {
log.debug "Updated with settings: ${settings}"
unsubscribe()
initialize()
}
def initialize() {
}
private device(it, type) {
it ? [id: it.id, label: it.label, type: type] : null
}
//API Mapping
mappings {
path("/getalldevices") {
action: [
GET: "getAllDevices"
]
}
/*
path("/thermostat/setcool/:id/:temp") {
action: [
GET: "setCoolTemp"
]
}
path("/thermostat/setheat/:id/:temp") {
action: [
GET: "setHeatTemp"
]
}
path("/thermostat/setfanmode/:id/:mode") {
action: [
GET: "setFanMode"
]
}
path("/thermostat/setmode/:id/:mode") {
action: [
GET: "setThermostatMode"
]
}
path("/thermostat/:id") {
action: [
GET: "getThermostatStatus"
]
}
*/
path("/light/dim/:id/:dim") {
action: [
GET: "setLevelStatus"
]
}
path("/light/kelvin/:id/:kelvin") {
action: [
GET: "setKelvin"
]
}
path("/colorlight/:id/:hue/:sat") {
action: [
GET: "setColor"
]
}
path("/light/status/:id") {
action: [
GET: "getLightStatus"
]
}
path("/light/on/:id") {
action: [
GET: "turnOnLight"
]
}
path("/light/off/:id") {
action: [
GET: "turnOffLight"
]
}
path("/doorlocks/lock/:id") {
action: [
GET: "lockDoorLock"
]
}
path("/doorlocks/unlock/:id") {
action: [
GET: "unlockDoorLock"
]
}
path("/doorlocks/:id") {
action: [
GET: "getDoorLockStatus"
]
}
path("/contacts/:id") {
action: [
GET: "getContactStatus"
]
}
path("/smoke/:id") {
action: [
GET: "getSmokeStatus"
]
}
path("/shades/open/:id") {
action: [
GET: "openShade"
]
}
path("/shades/preset/:id") {
action: [
GET: "presetShade"
]
}
path("/shades/close/:id") {
action: [
GET: "closeShade"
]
}
path("/shades/:id") {
action: [
GET: "getShadeStatus"
]
}
path("/garage/open/:id") {
action: [
GET: "openGarage"
]
}
path("/garage/close/:id") {
action: [
GET: "closeGarage"
]
}
path("/garage/:id") {
action: [
GET: "getGarageStatus"
]
}
path("/watersensors/:id") {
action: [
GET: "getWaterSensorStatus"
]
}
path("/tempsensors/:id") {
action: [
GET: "getTempSensorsStatus"
]
}
path("/meters/:id") {
action: [
GET: "getMeterStatus"
]
}
path("/batteries/:id") {
action: [
GET: "getBatteryStatus"
]
}
path("/presences/:id") {
action: [
GET: "getPresenceStatus"
]
}
path("/motions/:id") {
action: [
GET: "getMotionStatus"
]
}
path("/outlets/:id") {
action: [
GET: "getOutletStatus"
]
}
path("/outlets/turnon/:id") {
action: [
GET: "turnOnOutlet"
]
}
path("/outlets/turnoff/:id") {
action: [
GET: "turnOffOutlet"
]
}
path("/switches/turnon/:id") {
action: [
GET: "turnOnSwitch"
]
}
path("/switches/turnoff/:id") {
action: [
GET: "turnOffSwitch"
]
}
path("/switches/:id") {
action: [
GET: "getSwitchStatus"
]
}
}
//API Methods
def getAllDevices() {
def locks_list = locks.collect{device(it,"Lock")}
/*def thermo_list = thermostats.collect{device(it,"Thermostat")}*/
def colors_list = colors.collect{device(it,"Color")}
def kelvin_list = kelvin.collect{device(it,"Kelvin")}
def contact_list = contact.collect{device(it,"Contact Sensor")}
def smokes_list = smoke_alarms.collect{device(it,"Smoke Alarm")}
def shades_list = shades.collect{device(it,"Window Shade")}
def garage_list = garage.collect{device(it,"Garage Door")}
def water_sensors_list = water_sensors.collect{device(it,"Water Sensor")}
def presences_list = presence_sensors.collect{device(it,"Presence")}
def motions_list = motions.collect{device(it,"Motion")}
def outlets_list = outlets.collect{device(it,"Outlet")}
def switches_list = switches.collect{device(it,"Switch")}
def switchlevels_list = switchlevels.collect{device(it,"Switch Level")}
def temp_list = temperature_sensors.collect{device(it,"Temperature")}
def meters_list = meters.collect{device(it,"Power Meters")}
def battery_list = batteries.collect{device(it,"Batteries")}
return outlets_list + kelvin_list + colors_list + switchlevels_list + smokes_list + contact_list + water_sensors_list + shades_list + garage_list + locks_list + presences_list + motions_list + switches_list + temp_list + meters_list + battery_list
}
//thermostat
/*
def setCoolTemp() {
def device = thermostats.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
if(device.hasCommand("setCoolingSetpoint")) {
device.setCoolingSetpoint(params.temp.toInteger());
return [result_action: "200"]
}
else {
httpError(510, "Not supported!")
}
}
}
def setHeatTemp() {
def device = thermostats.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
if(device.hasCommand("setHeatingSetpoint")) {
device.setHeatingSetpoint(params.temp.toInteger());
return [result_action: "200"]
}
else {
httpError(510, "Not supported!")
}
}
}
def setFanMode() {
def device = thermostats.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
if(device.hasCommand("setThermostatFanMode")) {
device.setThermostatFanMode(params.mode);
return [result_action: "200"]
}
else {
httpError(510, "Not supported!")
}
}
}
def setThermostatMode() {
def device = thermostats.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
if(device.hasCommand("setThermostatMode")) {
device.setThermostatMode(params.mode);
return [result_action: "200"]
}
else {
httpError(510, "Not supported!")
}
}
}
def getThermostatStatus() {
def device = thermostats.find{ it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
return [ThermostatOperatingState: device.currentValue('thermostatOperatingState'), ThermostatSetpoint: device.currentValue('thermostatSetpoint'),
ThermostatFanMode: device.currentValue('thermostatFanMode'), ThermostatMode: device.currentValue('thermostatMode')]
}
}
*/
//light
def turnOnLight() {
def device = switches.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device.on();
return [Device_id: params.id, result_action: "200"]
}
}
def turnOffLight() {
def device = switches.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device.off();
return [Device_id: params.id, result_action: "200"]
}
}
def getLightStatus() {
def device = switches.find{ it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
return [Status: device.currentValue('switch'), Dim: getLevelStatus(params.id), Color: getColorStatus(params.id), Kelvin: getKelvinStatus(params.id)]
}
}
//color control
def setColor() {
def device = colors.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
def map = [hue:params.hue.toInteger(), saturation:params.sat.toInteger()]
device.setColor(map);
return [Device_id: params.id, result_action: "200"]
}
}
def getColorStatus(id) {
def device = colors.find { it.id == id }
if (!device) {
return [Color: "none"]
} else {
return [hue: device.currentValue('hue'), saturation: device.currentValue('saturation')]
}
}
//kelvin control
def setKelvin() {
def device = kelvin.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device.setColorTemperature(params.kelvin.toInteger());
return [Device_id: params.id, result_action: "200"]
}
}
def getKelvinStatus(id) {
def device = kelvin.find { it.id == id }
if (!device) {
return [kelvin: "none"]
} else {
return [kelvin: device.currentValue('colorTemperature')]
}
}
//switch level
def getLevelStatus() {
def device = switchlevels.find { it.id == params.id }
if (!device) {
[Level: "No dimmer"]
} else {
return [Level: device.currentValue('level')]
}
}
def getLevelStatus(id) {
def device = switchlevels.find { it.id == id }
if (!device) {
[Level: "No dimmer"]
} else {
return [Level: device.currentValue('level')]
}
}
def setLevelStatus() {
def device = switchlevels.find { it.id == params.id }
def level = params.dim
if (!device) {
httpError(404, "Device not found")
} else {
device.setLevel(level.toInteger())
return [result_action: "200", Level: device.currentValue('level')]
}
}
//contact sensors
def getContactStatus() {
def device = contact.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
def args = getTempSensorsStatus(device.id)
return [Device_state: device.currentValue('contact')] + args
}
}
//smoke detectors
def getSmokeStatus() {
def device = smoke_alarms.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
def bat = getBatteryStatus(device.id)
return [Device_state: device.currentValue('smoke')] + bat
}
}
//garage
def getGarageStatus() {
def device = garage.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
return [Device_state: device.currentValue('door')]
}
}
def openGarage() {
def device = garage.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device.open();
return [Device_id: params.id, result_action: "200"]
}
}
def closeGarage() {
def device = garage.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device.close();
return [Device_id: params.id, result_action: "200"]
}
}
//shades
def getShadeStatus() {
def device = shades.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
return [Device_state: device.currentValue('windowShade')]
}
}
def openShade() {
def device = shades.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device.open();
return [Device_id: params.id, result_action: "200"]
}
}
def presetShade() {
def device = shades.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device.presetPosition();
return [Device_id: params.id, result_action: "200"]
}
}
def closeShade() {
def device = shades.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device.close();
return [Device_id: params.id, result_action: "200"]
}
}
//water sensor
def getWaterSensorStatus() {
def device = water_sensors.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
def bat = getBatteryStatus(device.id)
return [Device_state: device.currentValue('water')] + bat
}
}
//batteries
def getBatteryStatus() {
def device = batteries.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
return [Device_state: device.latestValue("battery")]
}
}
def getBatteryStatus(id) {
def device = batteries.find { it.id == id }
if (!device) {
return []
} else {
return [battery_state: device.latestValue("battery")]
}
}
//LOCKS
def getDoorLockStatus() {
def device = locks.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
def bat = getBatteryStatus(device.id)
return [Device_state: device.currentValue('lock')] + bat
}
}
def lockDoorLock() {
def device = locks.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device.lock();
return [Device_id: params.id, result_action: "200"]
}
}
def unlockDoorLock() {
def device = locks.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device.unlock();
return [Device_id: params.id, result_action: "200"]
}
}
//PRESENCE
def getPresenceStatus() {
def device = presence_sensors.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
def bat = getBatteryStatus(device.id)
return [Device_state: device.currentValue('presence')] + bat
}
}
//MOTION
def getMotionStatus() {
def device = motions.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
def args = getTempSensorsStatus(device.id)
return [Device_state: device.currentValue('motion')] + args
}
}
//OUTLET
def getOutletStatus() {
def device = outlets.find { it.id == params.id }
if (!device) {
device = switches.find { it.id == params.id }
if(!device) {
httpError(404, "Device not found")
}
}
def watt = getMeterStatus(device.id)
return [Device_state: device.currentValue('switch')] + watt
}
def getMeterStatus() {
def device = meters.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
return [Device_id: device.id, Device_type: device.type, Current_watt: device.currentValue("power")]
}
}
def getMeterStatus(id) {
def device = meters.find { it.id == id }
if (!device) {
return []
} else {
return [Current_watt: device.currentValue("power")]
}
}
def turnOnOutlet() {
def device = outlets.find { it.id == params.id }
if (!device) {
device = switches.find { it.id == params.id }
if(!device) {
httpError(404, "Device not found")
}
}
device.on();
return [Device_id: params.id, result_action: "200"]
}
def turnOffOutlet() {
def device = outlets.find { it.id == params.id }
if (!device) {
device = switches.find { it.id == params.id }
if(!device) {
httpError(404, "Device not found")
}
}
device.off();
return [Device_id: params.id, result_action: "200"]
}
//SWITCH
def getSwitchStatus() {
def device = switches.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
return [Device_state: device.currentValue('switch'), Dim: getLevelStatus(params.id)]
}
}
def turnOnSwitch() {
def device = switches.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device.on();
return [Device_id: params.id, result_action: "200"]
}
}
def turnOffSwitch() {
def device = switches.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
device.off();
return [Device_id: params.id, result_action: "200"]
}
}
//TEMPERATURE
def getTempSensorsStatus() {
def device = temperature_sensors.find { it.id == params.id }
if (!device) {
httpError(404, "Device not found")
} else {
def bat = getBatteryStatus(device.id)
def scale = [Scale: location.temperatureScale]
return [Device_state: device.currentValue('temperature')] + scale + bat
}
}
def getTempSensorsStatus(id) {
def device = temperature_sensors.find { it.id == id }
if (!device) {
return []
} else {
def bat = getBatteryStatus(device.id)
return [temperature: device.currentValue('temperature')] + bat
}
}

View File

@@ -39,7 +39,7 @@ definition(
* garageDoors | door | open, close | unknown, closed, open, closing, opening
* cameras | image | take | <String>
* thermostats | thermostat | setHeatingSetpoint, | temperature, heatingSetpoint, coolingSetpoint,
* | | setCoolingSetpoint, | thermostatSetpoint, thermostatMode,
* | | setCoolingSetpoint, | thermostatSetpoint, thermostatMode,
* | | off, heat, cool, auto,| thermostatFanMode, thermostatOperatingState
* | | emergencyHeat, |
* | | setThermostatMode, |
@@ -55,7 +55,7 @@ preferences {
input "contactSensors", "capability.contactSensor", title: "Which Contact Sensors", multiple: true, required: false
input "garageDoors", "capability.garageDoorControl", title: "Which Garage Doors?", multiple: true, required: false
input "locks", "capability.lock", title: "Which Locks?", multiple: true, required: false
input "cameras", "capability.videoCapture", title: "Which Cameras?", multiple: true, required: false
input "cameras", "capability.videoCapture", title: "Which Cameras?", multiple: true, required: false
input "motionSensors", "capability.motionSensor", title: "Which Motion Sensors?", multiple: true, required: false
input "presenceSensors", "capability.presenceSensor", title: "Which Presence Sensors", multiple: true, required: false
input "switches", "capability.switch", title: "Which Switches and Lights?", multiple: true, required: false
@@ -66,54 +66,48 @@ preferences {
def getInputs() {
def inputList = []
inputList += contactSensors ?: []
inputList += garageDoors ?: []
inputList += locks ?: []
inputList += cameras ?: []
inputList += motionSensors ?: []
inputList += presenceSensors ?: []
inputList += switches ?: []
inputList += thermostats ?: []
inputList += waterSensors ?: []
inputList += contactSensors?: []
inputList += garageDoors?: []
inputList += locks?: []
inputList += cameras?: []
inputList += motionSensors?: []
inputList += presenceSensors?: []
inputList += switches?: []
inputList += thermostats?: []
inputList += waterSensors?: []
return inputList
}
//API external Endpoints
mappings {
path("/subscriptionURL/:url") {
action:
[
action: [
PUT: "updateEndpointURL"
]
}
path("/connectionId/:connId") {
action:
[
action: [
PUT: "updateConnectionId"
]
}
path("/devices") {
action:
[
action: [
GET: "getDevices"
]
}
path("/devices/:id") {
action:
[
action: [
GET: "getDevice"
]
}
path("/update/:id") {
action:
[
action: [
PUT: "updateDevice"
]
}
path("/subscription/:id") {
action:
[
POST : "registerDeviceChange",
action: [
POST: "registerDeviceChange",
DELETE: "unregisterDeviceChange"
]
}
@@ -145,7 +139,7 @@ def registerSubscriptions() {
def registerChangeHandler(myList) {
myList.each { myDevice ->
def theAtts = myDevice.supportedAttributes
theAtts.each { att ->
theAtts.each {att ->
subscribe(myDevice, att.name, eventHandler)
log.info "Registering ${myDevice.displayName}.${att.name}"
}
@@ -157,7 +151,7 @@ def registerDeviceChange() {
def myDevice = findDevice(params.id)
def theAtts = myDevice.supportedAttributes
try {
theAtts.each { att ->
theAtts.each {att ->
subscribe(myDevice, att.name, eventHandler)
log.info "Registering ${myDevice.displayName}.${att.name}"
}
@@ -186,16 +180,20 @@ def eventHandler(evt) {
def evt_name = evt.name
def evt_device = evt.device
def evt_deviceType = getDeviceType(evt_device);
def deviceInfo
if(evt_deviceType == "thermostat")
{
deviceInfo = [name: evt_device.displayName, id: evt_device.id, status:evt_device.getStatus(), deviceType:evt_deviceType, manufacturer:evt_device.getManufacturerName(), model:evt_device.getModelName(), attributes: deviceAttributeList(evt_device), locationMode: getLocationModeInfo()]
}
else
{
deviceInfo = [name: evt_device.displayName, id: evt_device.id, status:evt_device.getStatus(), deviceType:evt_deviceType, manufacturer:evt_device.getManufacturerName(), model:evt_device.getModelName(), attributes: deviceAttributeList(evt_device)]
}
def params = [
uri : "${state.endpointURL}/${state.connectionId}",
body: [
name : evt_device.displayName,
id : evt_device.id,
deviceType : evt_deviceType,
manufacturer: evt_device.getManufacturerName(),
model : evt_device.getModelName(),
attributes : deviceAttributeList(evt_device)
]
uri: "${state.endpointURL}/${state.connectionId}",
body: [ deviceInfo ]
]
try {
log.trace "POST URI: ${params.uri}"
@@ -230,10 +228,13 @@ def getDevices() {
def deviceData = []
inputs?.each {
def deviceType = getDeviceType(it)
if (deviceType == "thermostat") {
deviceData << [name: it.displayName, id: it.id, deviceType: deviceType, manufacturer: it.getManufacturerName(), model: it.getModelName(), attributes: deviceAttributeList(it), locationMode: getLocationModeInfo()]
} else {
deviceData << [name: it.displayName, id: it.id, deviceType: deviceType, manufacturer: it.getManufacturerName(), model: it.getModelName(), attributes: deviceAttributeList(it)]
if(deviceType == "thermostat")
{
deviceData << [name: it.displayName, id: it.id, status:it.getStatus(), deviceType:deviceType, manufacturer:it.getManufacturerName(), model:it.getModelName(), attributes: deviceAttributeList(it), locationMode: getLocationModeInfo()]
}
else
{
deviceData << [name: it.displayName, id: it.id, status:it.getStatus(), deviceType:deviceType, manufacturer:it.getManufacturerName(), model:it.getModelName(), attributes: deviceAttributeList(it)]
}
}
@@ -246,10 +247,13 @@ def getDevice() {
def it = findDevice(params.id)
def deviceType = getDeviceType(it)
def device
if (deviceType == "thermostat") {
device = [name: it.displayName, id: it.id, deviceType: deviceType, manufacturer: it.getManufacturerName(), model: it.getModelName(), attributes: deviceAttributeList(it), locationMode: getLocationModeInfo()]
} else {
device = [name: it.displayName, id: it.id, deviceType: deviceType, manufacturer: it.getManufacturerName(), model: it.getModelName(), attributes: deviceAttributeList(it)]
if(deviceType == "thermostat")
{
device = [name: it.displayName, id: it.id, status:it.getStatus(), deviceType:deviceType, manufacturer:it.getManufacturerName(), model:it.getModelName(), attributes: deviceAttributeList(it), locationMode: getLocationModeInfo()]
}
else
{
device = [name: it.displayName, id: it.id, status:it.getStatus(), deviceType:deviceType, manufacturer:it.getManufacturerName(), model:it.getModelName(), attributes: deviceAttributeList(it)]
}
log.debug "getDevice, return: ${device}"
return device
@@ -261,18 +265,18 @@ void updateDevice() {
request.JSON.each {
def command = it.key
def value = it.value
if (command) {
if (command){
def commandList = mapDeviceCommands(command, value)
command = commandList[0]
value = commandList[1]
if (command == "setAwayMode") {
log.info "Setting away mode to ${value}"
if (location.modes?.find { it.name == value }) {
if (location.modes?.find {it.name == value}) {
location.setMode(value)
}
} else if (command == "thermostatSetpoint") {
switch (device.currentThermostatMode) {
}else if (command == "thermostatSetpoint"){
switch(device.currentThermostatMode){
case "cool":
log.info "Update: ${device.displayName}, [${command}, ${value}]"
device.setCoolingSetpoint(value)
@@ -286,7 +290,7 @@ void updateDevice() {
httpError(501, "this mode: ${device.currentThermostatMode} does not allow changing thermostat setpoint.")
break
}
} else if (!device) {
}else if (!device) {
log.error "updateDevice, Device not found"
httpError(404, "Device not found")
} else if (!device.hasCommand(command)) {
@@ -296,11 +300,11 @@ void updateDevice() {
if (command == "setColor") {
log.info "Update: ${device.displayName}, [${command}, ${value}]"
device."$command"(hex: value)
} else if (value.isNumber()) {
} else if(value.isNumber()) {
def intValue = value as Integer
log.info "Update: ${device.displayName}, [${command}, ${intValue}(int)]"
device."$command"(intValue)
} else if (value) {
} else if (value){
log.info "Update: ${device.displayName}, [${command}, ${value}]"
device."$command"(value)
} else {
@@ -322,19 +326,28 @@ private getLocationModeInfo() {
//Map each device to a type given it's capabilities
private getDeviceType(device) {
def deviceType
def caps = device.capabilities
log.debug "capabilities: [${device}, ${caps}]"
def capabilities = device.capabilities
log.debug "capabilities: [${device}, ${capabilities}]"
log.debug "supported commands: [${device}, ${device.supportedCommands}]"
caps.each {
switch (it.name.toLowerCase()) {
//Loop through the device capability list to determine the device type.
capabilities.each {capability ->
switch(capability.name.toLowerCase())
{
case "switch":
deviceType = "switch"
if (caps.any { it.name.toLowerCase() == "power meter" }) {
return deviceType
}
if (caps.any { it.name.toLowerCase() == "switch level" }) {
deviceType = "light"
return deviceType
//If the device also contains "Switch Level" capability, identify it as a "light" device.
if (capabilities.any{it.name.toLowerCase() == "switch level"}){
//If the device also contains "Power Meter" capability, identify it as a "dimmerSwitch" device.
if (capabilities.any{it.name.toLowerCase() == "power meter"}){
deviceType = "dimmerSwitch"
return deviceType
} else {
deviceType = "light"
return deviceType
}
}
break
case "contact sensor":
@@ -375,16 +388,16 @@ private findDevice(deviceId) {
//Return a list of device attributes
private deviceAttributeList(device) {
device.supportedAttributes.collectEntries { attribute ->
device.supportedAttributes.collectEntries { attribute->
try {
[(attribute.name): device.currentValue(attribute.name)]
} catch (e) {
[(attribute.name): null]
[ (attribute.name): device.currentValue(attribute.name) ]
} catch(e) {
[ (attribute.name): null ]
}
}
}
//Map device command and value.
//Map device command and value.
//input command and value are from UWP,
//returns resultCommand and resultValue that corresponds with function and value in SmartApps
private mapDeviceCommands(command, value) {
@@ -414,7 +427,7 @@ private mapDeviceCommands(command, value) {
resultCommand = "setSaturation"
resultValue = value
break
case "ct":
case "colorTemperature":
resultCommand = "setColorTemperature"
resultValue = value
break
@@ -451,7 +464,8 @@ private mapDeviceCommands(command, value) {
if (value == 1 || value == "1" || value == "lock") {
resultCommand = "lock"
resultValue = ""
} else if (value == 0 || value == "0" || value == "unlock") {
}
else if (value == 0 || value == "0" || value == "unlock") {
resultCommand = "unlock"
resultValue = ""
}
@@ -460,6 +474,5 @@ private mapDeviceCommands(command, value) {
break
}
return [resultCommand, resultValue]
return [resultCommand,resultValue]
}

View File

@@ -30,7 +30,7 @@ preferences {
input "havdalahOffset", "number", title: "Minutes After Sundown", required:true
}
section("Your ZipCode") {
input "zipcode", "number", title: "ZipCode", required:true
input "zipcode", "text", title: "ZipCode", required:true
}
section( "Notifications" ) {
input "sendPushMessage", "enum", title: "Send a push notification?", metadata:[values:["Yes","No"]], required:false
@@ -205,4 +205,4 @@ if ( sendPushMessage != "No" ) {
log.debug( "sending text message" )
sendSms( phone, msg )
}
}//END def sendMessage(msg)
}//END def sendMessage(msg)

View File

@@ -1,82 +0,0 @@
/**
* Turn Off
*
* Copyright 2017 Trevor
*
* 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.
*
*/
definition(
name: "Turn Off",
namespace: "TEAPPS",
author: "Trevor",
description: "Turn off a light after its been turned on.",
category: "Convenience",
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")
preferences {
section("Lights") {
input "lights", "capability.switch", required: true, title: "Which lights to turn off after being turned on?", multiple: true
input "offsetHours", "number", title: "How long until the light is turned off (hours)?"
input "offsetMinutes", "number", title: "How long until the light is turned off (minutes)?"
input "offsetSeconds", "number", title: "How long until the light is turned off (seconds)?"
}
}
def installed() {
log.debug "Installed with settings: ${settings}"
initialize()
}
def updated() {
log.debug "Updated with settings: ${settings}"
unsubscribe()
initialize()
}
def initialize() {
// TODO: subscribe to attributes, devices, locations, etc.
//Subscribe to the light device being turned on
subscribe(lights, "switch.on", lightHandler)
}
// TODO: implement event handlers
def lightHandler(evt) {
if("on" == evt.value)
//Light was turned on
log.debug "Light is in ${evt.value} state"
//Get the date and time
def currentTime = new Date()
//Calculate the offset
def timeToTurnOff = new Date(currentTime.time + (offsetHours * 60 * 60 * 1000) + (offsetMinutes * 60 * 1000) + (offsetSeconds * 1000))
log.debug "Scheduling for: $timeToTurnOff"
//Schedule this to run one time
runOnce(timeToTurnOff, turnOff)
}
def turnOff() {
log.debug "turning off lights"
lights.off()
}