mirror of
https://github.com/mtan93/SmartThingsPublic.git
synced 2026-03-10 05:11:51 +00:00
Compare commits
1 Commits
MSA-1903-1
...
MSA-1900-9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2640a9ac87 |
@@ -1,839 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Fibaro Dimmer 2 (US)
|
||||
*
|
||||
* github: Eric Maycock (erocm123)
|
||||
* email: erocmail@gmail.com
|
||||
* Date: 2016-07-31 8:03PM
|
||||
* Copyright Eric Maycock
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing permissions and limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
metadata {
|
||||
definition (name: "Fibaro Dimmer 2", namespace: "erocm123", author: "Eric Maycock") {
|
||||
capability "Actuator"
|
||||
capability "Switch"
|
||||
capability "Switch Level"
|
||||
capability "Refresh"
|
||||
capability "Configuration"
|
||||
capability "Sensor"
|
||||
capability "Polling"
|
||||
capability "Energy Meter"
|
||||
capability "Power Meter"
|
||||
capability "Button"
|
||||
capability "Health Check"
|
||||
|
||||
attribute "needUpdate", "string"
|
||||
|
||||
fingerprint deviceId: "0x1101", inClusters: "0x72,0x86,0x70,0x85,0x8E,0x26,0x7A,0x27,0x73,0xEF,0x26,0x2B"
|
||||
fingerprint deviceId: "0x1101", inClusters: "0x5E,0x20,0x86,0x72,0x26,0x5A,0x59,0x85,0x73,0x98,0x7A,0x56,0x70,0x31,0x32,0x8E,0x60,0x75,0x71,0x27"
|
||||
|
||||
}
|
||||
|
||||
preferences {
|
||||
input description: "Once you change values on this page, the corner of the \"configuration\" icon will change orange until all configuration parameters are updated.", title: "Settings", displayDuringSetup: false, type: "paragraph", element: "paragraph"
|
||||
generate_preferences(configuration_model())
|
||||
}
|
||||
|
||||
simulator {
|
||||
|
||||
}
|
||||
|
||||
tiles(scale: 2){
|
||||
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
|
||||
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
||||
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00a0dc", nextState:"turningOff"
|
||||
attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00a0dc", nextState:"turningOff"
|
||||
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
||||
}
|
||||
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
|
||||
attributeState "level", action:"switch level.setLevel"
|
||||
}
|
||||
tileAttribute ("statusText", key: "SECONDARY_CONTROL") {
|
||||
attributeState "statusText", label:'${currentValue}'
|
||||
}
|
||||
}
|
||||
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
||||
state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
|
||||
}
|
||||
valueTile("power", "device.power", decoration: "flat", width: 2, height: 2) {
|
||||
state "default", label:'${currentValue} W'
|
||||
}
|
||||
valueTile("energy", "device.energy", decoration: "flat", width: 2, height: 2) {
|
||||
state "default", label:'${currentValue} kWh'
|
||||
}
|
||||
standardTile("reset", "device.energy", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
||||
state "default", label:'reset kWh', action:"reset"
|
||||
}
|
||||
standardTile("configure", "device.needUpdate", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
||||
state "NO" , label:'', action:"configuration.configure", icon:"st.secondary.configure"
|
||||
state "YES", label:'', action:"configuration.configure", icon:"https://github.com/erocm123/SmartThingsPublic/raw/master/devicetypes/erocm123/qubino-flush-1d-relay.src/configure@2x.png"
|
||||
}
|
||||
|
||||
|
||||
main "switch"
|
||||
details (["switch", "power", "energy", "refresh", "configure", "reset"])
|
||||
}
|
||||
}
|
||||
|
||||
def parse(String description) {
|
||||
def result = null
|
||||
if (description.startsWith("Err")) {
|
||||
result = createEvent(descriptionText:description, isStateChange:true)
|
||||
} else if (description != "updated") {
|
||||
def cmd = zwave.parse(description, [0x20: 1, 0x84: 1, 0x98: 1, 0x56: 1, 0x60: 3])
|
||||
if (cmd) {
|
||||
result = zwaveEvent(cmd)
|
||||
}
|
||||
}
|
||||
|
||||
def statusTextmsg = ""
|
||||
if (device.currentState('power') && device.currentState('energy')) statusTextmsg = "${device.currentState('power').value} W ${device.currentState('energy').value} kWh"
|
||||
sendEvent(name:"statusText", value:statusTextmsg, displayed:false)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd) {
|
||||
logging("BasicReport: $cmd")
|
||||
def events = []
|
||||
if (cmd.value == 0) {
|
||||
events << createEvent(name: "switch", value: "off")
|
||||
} else if (cmd.value == 255) {
|
||||
events << createEvent(name: "switch", value: "on")
|
||||
} else {
|
||||
events << createEvent(name: "switch", value: "on")
|
||||
events << createEvent(name: "switchLevel", value: cmd.value)
|
||||
}
|
||||
|
||||
def request = update_needed_settings()
|
||||
|
||||
if(request != []){
|
||||
return [response(commands(request)), events]
|
||||
} else {
|
||||
return events
|
||||
}
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.sceneactivationv1.SceneActivationSet cmd) {
|
||||
logging("SceneActivationSet: $cmd")
|
||||
logging("sceneId: $cmd.sceneId")
|
||||
logging("dimmingDuration: $cmd.dimmingDuration")
|
||||
logging("Configuration for preference \"Switch Type\" is set to ${settings."20"}")
|
||||
|
||||
if (settings."20" == "2") {
|
||||
logging("Switch configured as Roller blinds")
|
||||
switch (cmd.sceneId) {
|
||||
// Roller blinds S1
|
||||
case 10: // Turn On (1x click)
|
||||
buttonEvent(1, "pushed")
|
||||
break
|
||||
case 13: // Release
|
||||
buttonEvent(1, "held")
|
||||
break
|
||||
case 14: // 2x click
|
||||
buttonEvent(2, "pushed")
|
||||
break
|
||||
case 17: // Brightening
|
||||
buttonEvent(2, "held")
|
||||
break
|
||||
// Roller blinds S2
|
||||
case 11: // Turn Off
|
||||
buttonEvent(3, "pushed")
|
||||
break
|
||||
case 13: // Release
|
||||
buttonEvent(3, "held")
|
||||
break
|
||||
case 14: // 2x click
|
||||
buttonEvent(4, "pushed")
|
||||
break
|
||||
case 15: // 3x click
|
||||
buttonEvent(5, "pushed")
|
||||
break
|
||||
case 18: // Dimming
|
||||
buttonEvent(4, "held")
|
||||
break
|
||||
default:
|
||||
logging("Unhandled SceneActivationSet: ${cmd}")
|
||||
break
|
||||
}
|
||||
} else if (settings."20" == "1") {
|
||||
logging("Switch configured as Toggle")
|
||||
switch (cmd.sceneId) {
|
||||
// Toggle S1
|
||||
case 10: // Off to On
|
||||
buttonEvent(1, "pushed")
|
||||
break
|
||||
case 11: // On to Off
|
||||
buttonEvent(1, "held")
|
||||
break
|
||||
case 14: // 2x click
|
||||
buttonEvent(2, "pushed")
|
||||
break
|
||||
// Toggle S2
|
||||
case 20: // Off to On
|
||||
buttonEvent(3, "pushed")
|
||||
break
|
||||
case 21: // On to Off
|
||||
buttonEvent(3, "held")
|
||||
break
|
||||
case 24: // 2x click
|
||||
buttonEvent(4, "pushed")
|
||||
break
|
||||
case 25: // 3x click
|
||||
buttonEvent(5, "pushed")
|
||||
break
|
||||
default:
|
||||
logging("Unhandled SceneActivationSet: ${cmd}")
|
||||
break
|
||||
|
||||
}
|
||||
} else {
|
||||
if (settings."20" == "0") logging("Switch configured as Momentary") else logging("Switch type not configured")
|
||||
switch (cmd.sceneId) {
|
||||
// Momentary S1
|
||||
case 16: // 1x click
|
||||
buttonEvent(1, "pushed")
|
||||
break
|
||||
case 14: // 2x click
|
||||
buttonEvent(2, "pushed")
|
||||
break
|
||||
case 12: // held
|
||||
buttonEvent(1, "held")
|
||||
break
|
||||
case 13: // release
|
||||
buttonEvent(2, "held")
|
||||
break
|
||||
// Momentary S2
|
||||
case 26: // 1x click
|
||||
buttonEvent(3, "pushed")
|
||||
break
|
||||
case 24: // 2x click
|
||||
buttonEvent(4, "pushed")
|
||||
break
|
||||
case 25: // 3x click
|
||||
buttonEvent(5, "pushed")
|
||||
break
|
||||
case 22: // held
|
||||
buttonEvent(3, "held")
|
||||
break
|
||||
case 23: // release
|
||||
buttonEvent(4, "held")
|
||||
break
|
||||
default:
|
||||
logging("Unhandled SceneActivationSet: ${cmd}")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def buttonEvent(button, value) {
|
||||
logging("buttonEvent() Button:$button, Value:$value")
|
||||
createEvent(name: "button", value: value, data: [buttonNumber: button], descriptionText: "$device.displayName button $button was $value", isStateChange: true)
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.switchmultilevelv3.SwitchMultilevelReport cmd) {
|
||||
logging(cmd)
|
||||
dimmerEvents(cmd)
|
||||
}
|
||||
|
||||
def dimmerEvents(physicalgraph.zwave.Command cmd) {
|
||||
logging(cmd)
|
||||
def result = []
|
||||
def value = (cmd.value ? "on" : "off")
|
||||
def switchEvent = createEvent(name: "switch", value: value, descriptionText: "$device.displayName was turned $value")
|
||||
result << switchEvent
|
||||
if (cmd.value) {
|
||||
result << createEvent(name: "level", value: cmd.value, unit: "%")
|
||||
}
|
||||
if (switchEvent.isStateChange) {
|
||||
result << response(["delay 3000", zwave.meterV2.meterGet(scale: 2).format()])
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.associationv2.AssociationReport cmd) {
|
||||
logging("AssociationReport $cmd")
|
||||
state."association${cmd.groupingIdentifier}" = cmd.nodeId[0]
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityMessageEncapsulation cmd) {
|
||||
def encapsulatedCommand = cmd.encapsulatedCommand([0x20: 1, 0x84: 1])
|
||||
if (encapsulatedCommand) {
|
||||
state.sec = 1
|
||||
def result = zwaveEvent(encapsulatedCommand)
|
||||
result = result.collect {
|
||||
if (it instanceof physicalgraph.device.HubAction && !it.toString().startsWith("9881")) {
|
||||
response(cmd.CMD + "00" + it.toString())
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.crc16encapv1.Crc16Encap cmd) {
|
||||
def versions = [0x31: 5, 0x30: 1, 0x9C: 1, 0x70: 2, 0x85: 2]
|
||||
def version = versions[cmd.commandClass as Integer]
|
||||
def ccObj = version ? zwave.commandClass(cmd.commandClass, version) : zwave.commandClass(cmd.commandClass)
|
||||
def encapsulatedCommand = ccObj?.command(cmd.command)?.parse(cmd.data)
|
||||
if (encapsulatedCommand) {
|
||||
zwaveEvent(encapsulatedCommand)
|
||||
}
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
||||
logging("Unhandled Z-Wave Event: $cmd")
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.meterv3.MeterReport cmd) {
|
||||
logging(cmd)
|
||||
if (cmd.meterType == 1) {
|
||||
if (cmd.scale == 0) {
|
||||
return createEvent(name: "energy", value: cmd.scaledMeterValue, unit: "kWh")
|
||||
} else if (cmd.scale == 1) {
|
||||
return createEvent(name: "energy", value: cmd.scaledMeterValue, unit: "kVAh")
|
||||
} else if (cmd.scale == 2) {
|
||||
return createEvent(name: "power", value: Math.round(cmd.scaledMeterValue), unit: "W")
|
||||
} else {
|
||||
return createEvent(name: "electric", value: cmd.scaledMeterValue, unit: ["pulses", "V", "A", "R/Z", ""][cmd.scale - 3])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv5.SensorMultilevelReport cmd){
|
||||
logging("SensorMultilevelReport: $cmd")
|
||||
def map = [:]
|
||||
switch (cmd.sensorType) {
|
||||
case 4:
|
||||
map.name = "power"
|
||||
map.value = cmd.scaledSensorValue.toInteger().toString()
|
||||
map.unit = cmd.scale == 1 ? "Btu/h" : "W"
|
||||
break
|
||||
default:
|
||||
map.descriptionText = cmd.toString()
|
||||
}
|
||||
createEvent(map)
|
||||
}
|
||||
|
||||
def on() {
|
||||
commands([zwave.basicV1.basicSet(value: 0xFF), zwave.basicV1.basicGet()])
|
||||
}
|
||||
|
||||
def off() {
|
||||
commands([zwave.basicV1.basicSet(value: 0x00), zwave.basicV1.basicGet()])
|
||||
}
|
||||
|
||||
def refresh() {
|
||||
logging("$device.displayName refresh()")
|
||||
|
||||
def cmds = []
|
||||
if (state.lastRefresh != null && now() - state.lastRefresh < 5000) {
|
||||
logging("Refresh Double Press")
|
||||
def configuration = parseXml(configuration_model())
|
||||
configuration.Value.each
|
||||
{
|
||||
if ( "${it.@setting_type}" == "zwave" ) {
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: "${it.@index}".toInteger())
|
||||
}
|
||||
}
|
||||
cmds << zwave.firmwareUpdateMdV2.firmwareMdGet()
|
||||
} else {
|
||||
cmds << zwave.meterV2.meterGet(scale: 0)
|
||||
cmds << zwave.meterV2.meterGet(scale: 2)
|
||||
cmds << zwave.basicV1.basicGet()
|
||||
}
|
||||
|
||||
state.lastRefresh = now()
|
||||
|
||||
commands(cmds)
|
||||
}
|
||||
|
||||
def ping() {
|
||||
logging("$device.displayName ping()")
|
||||
|
||||
def cmds = []
|
||||
|
||||
cmds << zwave.meterV2.meterGet(scale: 0)
|
||||
cmds << zwave.meterV2.meterGet(scale: 2)
|
||||
cmds << zwave.basicV1.basicGet()
|
||||
|
||||
commands(cmds)
|
||||
}
|
||||
|
||||
def setLevel(level) {
|
||||
if(level > 99) level = 99
|
||||
if(level < 1) level = 1
|
||||
def cmds = []
|
||||
cmds << zwave.basicV1.basicSet(value: level)
|
||||
cmds << zwave.switchMultilevelV1.switchMultilevelGet()
|
||||
|
||||
commands(cmds)
|
||||
}
|
||||
|
||||
def updated()
|
||||
{
|
||||
state.enableDebugging = settings.enableDebugging
|
||||
logging("updated() is being called")
|
||||
sendEvent(name: "checkInterval", value: 2 * 30 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
||||
state.needfwUpdate = ""
|
||||
|
||||
def cmds = update_needed_settings()
|
||||
|
||||
sendEvent(name:"needUpdate", value: device.currentValue("needUpdate"), displayed:false, isStateChange: true)
|
||||
|
||||
response(commands(cmds))
|
||||
}
|
||||
|
||||
private command(physicalgraph.zwave.Command cmd) {
|
||||
if (state.sec) {
|
||||
zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
|
||||
} else {
|
||||
cmd.format()
|
||||
}
|
||||
}
|
||||
|
||||
private commands(commands, delay=1500) {
|
||||
delayBetween(commands.collect{ command(it) }, delay)
|
||||
}
|
||||
|
||||
def generate_preferences(configuration_model)
|
||||
{
|
||||
def configuration = parseXml(configuration_model)
|
||||
|
||||
configuration.Value.each
|
||||
{
|
||||
switch(it.@type)
|
||||
{
|
||||
case ["byte","short","four"]:
|
||||
input "${it.@index}", "number",
|
||||
title:"${it.@label}\n" + "${it.Help}",
|
||||
range: "${it.@min}..${it.@max}",
|
||||
defaultValue: "${it.@value}",
|
||||
displayDuringSetup: "${it.@displayDuringSetup}"
|
||||
break
|
||||
case "list":
|
||||
def items = []
|
||||
it.Item.each { items << ["${it.@value}":"${it.@label}"] }
|
||||
input "${it.@index}", "enum",
|
||||
title:"${it.@label}\n" + "${it.Help}",
|
||||
defaultValue: "${it.@value}",
|
||||
displayDuringSetup: "${it.@displayDuringSetup}",
|
||||
options: items
|
||||
break
|
||||
case "decimal":
|
||||
input "${it.@index}", "decimal",
|
||||
title:"${it.@label}\n" + "${it.Help}",
|
||||
range: "${it.@min}..${it.@max}",
|
||||
defaultValue: "${it.@value}",
|
||||
displayDuringSetup: "${it.@displayDuringSetup}"
|
||||
break
|
||||
case "boolean":
|
||||
input "${it.@index}", "boolean",
|
||||
title:"${it.@label}\n" + "${it.Help}",
|
||||
defaultValue: "${it.@value}",
|
||||
displayDuringSetup: "${it.@displayDuringSetup}"
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def update_current_properties(cmd)
|
||||
{
|
||||
def currentProperties = state.currentProperties ?: [:]
|
||||
|
||||
currentProperties."${cmd.parameterNumber}" = cmd.configurationValue
|
||||
|
||||
if (settings."${cmd.parameterNumber}" != null)
|
||||
{
|
||||
if (settings."${cmd.parameterNumber}".toInteger() == convertParam("${cmd.parameterNumber}".toInteger(), cmd2Integer(cmd.configurationValue)))
|
||||
{
|
||||
sendEvent(name:"needUpdate", value:"NO", displayed:false, isStateChange: true)
|
||||
}
|
||||
else
|
||||
{
|
||||
sendEvent(name:"needUpdate", value:"YES", displayed:false, isStateChange: true)
|
||||
}
|
||||
}
|
||||
|
||||
state.currentProperties = currentProperties
|
||||
}
|
||||
|
||||
def update_needed_settings()
|
||||
{
|
||||
def cmds = []
|
||||
def currentProperties = state.currentProperties ?: [:]
|
||||
|
||||
def configuration = parseXml(configuration_model())
|
||||
def isUpdateNeeded = "NO"
|
||||
|
||||
if(!state.needfwUpdate || state.needfwUpdate == ""){
|
||||
logging("Requesting device firmware version")
|
||||
cmds << zwave.firmwareUpdateMdV2.firmwareMdGet()
|
||||
}
|
||||
if(!state.association1 || state.association1 == "" || state.association1 == "1"){
|
||||
logging("Setting association group 1")
|
||||
cmds << zwave.associationV2.associationSet(groupingIdentifier:1, nodeId:zwaveHubNodeId)
|
||||
cmds << zwave.associationV2.associationGet(groupingIdentifier:1)
|
||||
}
|
||||
if(!state.association2 || state.association2 == "" || state.association1 == "2"){
|
||||
logging("Setting association group 2")
|
||||
cmds << zwave.associationV2.associationSet(groupingIdentifier:2, nodeId:zwaveHubNodeId)
|
||||
cmds << zwave.associationV2.associationGet(groupingIdentifier:2)
|
||||
}
|
||||
|
||||
configuration.Value.each
|
||||
{
|
||||
if ("${it.@setting_type}" == "zwave"){
|
||||
if (currentProperties."${it.@index}" == null)
|
||||
{
|
||||
if (device.currentValue("currentFirmware") == null || "${it.@fw}".indexOf(device.currentValue("currentFirmware")) >= 0){
|
||||
isUpdateNeeded = "YES"
|
||||
logging("Current value of parameter ${it.@index} is unknown")
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: it.@index.toInteger())
|
||||
}
|
||||
}
|
||||
else if (settings."${it.@index}" != null && convertParam(it.@index.toInteger(), cmd2Integer(currentProperties."${it.@index}")) != settings."${it.@index}".toInteger())
|
||||
{
|
||||
if (device.currentValue("currentFirmware") == null || "${it.@fw}".indexOf(device.currentValue("currentFirmware")) >= 0){
|
||||
isUpdateNeeded = "YES"
|
||||
|
||||
logging("Parameter ${it.@index} will be updated to " + settings."${it.@index}")
|
||||
def convertedConfigurationValue = convertParam(it.@index.toInteger(), settings."${it.@index}".toInteger())
|
||||
cmds << zwave.configurationV1.configurationSet(configurationValue: integer2Cmd(convertedConfigurationValue, it.@byteSize.toInteger()), parameterNumber: it.@index.toInteger(), size: it.@byteSize.toInteger())
|
||||
cmds << zwave.configurationV1.configurationGet(parameterNumber: it.@index.toInteger())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sendEvent(name:"needUpdate", value: isUpdateNeeded, displayed:false, isStateChange: true)
|
||||
return cmds
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert 1 and 2 bytes values to integer
|
||||
*/
|
||||
def cmd2Integer(array) {
|
||||
|
||||
switch(array.size()) {
|
||||
case 1:
|
||||
array[0]
|
||||
break
|
||||
case 2:
|
||||
((array[0] & 0xFF) << 8) | (array[1] & 0xFF)
|
||||
break
|
||||
case 3:
|
||||
((array[0] & 0xFF) << 16) | ((array[1] & 0xFF) << 8) | (array[2] & 0xFF)
|
||||
break
|
||||
case 4:
|
||||
((array[0] & 0xFF) << 24) | ((array[1] & 0xFF) << 16) | ((array[2] & 0xFF) << 8) | (array[3] & 0xFF)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
def integer2Cmd(value, size) {
|
||||
switch(size) {
|
||||
case 1:
|
||||
[value]
|
||||
break
|
||||
case 2:
|
||||
def short value1 = value & 0xFF
|
||||
def short value2 = (value >> 8) & 0xFF
|
||||
[value2, value1]
|
||||
break
|
||||
case 3:
|
||||
def short value1 = value & 0xFF
|
||||
def short value2 = (value >> 8) & 0xFF
|
||||
def short value3 = (value >> 16) & 0xFF
|
||||
[value3, value2, value1]
|
||||
break
|
||||
case 4:
|
||||
def short value1 = value & 0xFF
|
||||
def short value2 = (value >> 8) & 0xFF
|
||||
def short value3 = (value >> 16) & 0xFF
|
||||
def short value4 = (value >> 24) & 0xFF
|
||||
[value4, value3, value2, value1]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.configurationv2.ConfigurationReport cmd) {
|
||||
update_current_properties(cmd)
|
||||
logging("${device.displayName} parameter '${cmd.parameterNumber}' with a byte size of '${cmd.size}' is set to '${cmd2Integer(cmd.configurationValue)}'")
|
||||
}
|
||||
|
||||
def zwaveEvent(physicalgraph.zwave.commands.firmwareupdatemdv2.FirmwareMdReport cmd){
|
||||
logging("Firmware Report ${cmd.toString()}")
|
||||
def firmwareVersion
|
||||
switch(cmd.checksum){
|
||||
case "3281":
|
||||
firmwareVersion = "3.08"
|
||||
break;
|
||||
default:
|
||||
firmwareVersion = cmd.checksum
|
||||
}
|
||||
state.needfwUpdate = "false"
|
||||
updateDataValue("firmware", firmwareVersion.toString())
|
||||
createEvent(name: "currentFirmware", value: firmwareVersion)
|
||||
}
|
||||
|
||||
def configure() {
|
||||
state.enableDebugging = settings.enableDebugging
|
||||
logging("Configuring Device For SmartThings Use")
|
||||
def cmds = []
|
||||
|
||||
cmds = update_needed_settings()
|
||||
|
||||
if (cmds != []) commands(cmds)
|
||||
}
|
||||
|
||||
def convertParam(number, value) {
|
||||
switch (number){
|
||||
case 201:
|
||||
if (value < 0)
|
||||
256 + value
|
||||
else if (value > 100)
|
||||
value - 256
|
||||
else
|
||||
value
|
||||
break
|
||||
case 202:
|
||||
if (value < 0)
|
||||
256 + value
|
||||
else if (value > 100)
|
||||
value - 256
|
||||
else
|
||||
value
|
||||
break
|
||||
case 203:
|
||||
if (value < 0)
|
||||
65536 + value
|
||||
else if (value > 1000)
|
||||
value - 65536
|
||||
else
|
||||
value
|
||||
break
|
||||
case 204:
|
||||
if (value < 0)
|
||||
256 + value
|
||||
else if (value > 100)
|
||||
value - 256
|
||||
else
|
||||
value
|
||||
break
|
||||
default:
|
||||
value
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
private def logging(message) {
|
||||
if (state.enableDebugging == null || state.enableDebugging == "true") log.debug "$message"
|
||||
}
|
||||
|
||||
|
||||
def configuration_model()
|
||||
{
|
||||
'''
|
||||
<configuration>
|
||||
<Value type="byte" byteSize="1" index="1" label="Minimum brightness level" min="1" max="98" value="1" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
(parameter is set automatically during the calibration process)
|
||||
The parameter can be changed manually after the calibration.
|
||||
Range: 1~98
|
||||
Default: 1
|
||||
</Help>
|
||||
</Value>
|
||||
<Value type="byte" byteSize="1" index="2" label="Maximum brightness level" min="2" max="99" value="99" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
(parameter is set automatically during the calibration process)
|
||||
The parameter can be changed manually after the calibration.
|
||||
Range: 2~99
|
||||
Default: 99
|
||||
</Help>
|
||||
</Value>
|
||||
<Value type="byte" byteSize="1" index="5" label="Automatic control - dimming step size" min="1" max="99" value="1" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
This parameter defines the percentage value of dimming step during the automatic control.
|
||||
Range: 1~99
|
||||
Default: 1
|
||||
</Help>
|
||||
</Value>
|
||||
<Value type="short" byteSize="2" index="6" label="Automatic control - time of a dimming step" min="0" max="255" value="1" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
This parameter defines the time of single dimming step set in parameter 5 during the automatic control.
|
||||
Range: 0~255
|
||||
Default: 1
|
||||
</Help>
|
||||
</Value>
|
||||
<Value type="byte" byteSize="1" index="7" label="Manual control - dimming step size" min="1" max="99" value="1" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
This parameter defines the percentage value of dimming step during the manual control.
|
||||
Range: 1~99
|
||||
Default: 1
|
||||
</Help>
|
||||
</Value>
|
||||
<Value type="short" byteSize="2" index="8" label="Manual control - time of a dimming step" min="0" max="255" value="5" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
This parameter defines the time of single dimming step set in parameter 7 during the manual control.
|
||||
Range: 0~255
|
||||
Default: 5
|
||||
</Help>
|
||||
</Value>
|
||||
<Value type="list" byteSize="1" index="9" label="State of the device after a power failure" min="0" max="1" value="1" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
The Dimmer 2 will return to the last state before power failure.
|
||||
0 - the Dimmer 2 does not save the state before a power failure, it returns to the "off" position
|
||||
1 - the Dimmer 2 restores its state before power failure
|
||||
Range: 0~1
|
||||
Default: 1
|
||||
</Help>
|
||||
<Item label="Off" value="0" />
|
||||
<Item label="Previous State" value="1" />
|
||||
</Value>
|
||||
<Value type="short" byteSize="2" index="10" label="Timer functionality (auto - off)" min="0" max="32767" value="0" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
This parameter allows to automatically switch off the device after specified time (seconds) from switching on the light source.
|
||||
Range: 1~32767
|
||||
Default: 0
|
||||
</Help>
|
||||
</Value>
|
||||
<Value type="byte" byteSize="1" index="19" label="Forced switch on brightness level" min="0" max="99" value="0" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
If the parameter is active, switching on the Dimmer 2 (S1 single click) will always set this brightness level.
|
||||
Range: 0~99
|
||||
Default: 0
|
||||
</Help>
|
||||
</Value>
|
||||
<Value type="list" byteSize="1" index="20" label="Switch type" min="0" max="2" value="0" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
Choose between momentary, toggle and roller blind switch.
|
||||
Range: 0~2
|
||||
Default: 0
|
||||
</Help>
|
||||
<Item label="Momentary" value="0" />
|
||||
<Item label="Toggle" value="1" />
|
||||
<Item label="Roller Blind" value="2" />
|
||||
</Value>
|
||||
<Value type="list" byteSize="1" index="22" label="Assign toggle switch status to the device status " min="0" max="1" value="0" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
By default each change of toggle switch position results in action of Dimmer 2 (switch on/off) regardless the physical connection of contacts.
|
||||
0 - device changes status on switch status change
|
||||
1 - device status is synchronized with switch status
|
||||
Range: 0~1
|
||||
Default: 0
|
||||
</Help>
|
||||
<Item label="Default" value="0" />
|
||||
<Item label="Synchronized" value="1" />
|
||||
</Value>
|
||||
<Value type="list" byteSize="1" index="23" label="Double click option" min="0" max="1" value="1" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
set the brightness level to MAX
|
||||
Range: 0~1
|
||||
Default: 1
|
||||
</Help>
|
||||
<Item label="Disabled" value="0" />
|
||||
<Item label="Enabled" value="1" />
|
||||
</Value>
|
||||
<Value type="list" byteSize="1" index="26" label="The function of 3-way switch" min="0" max="1" value="0" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
Switch no. 2 controls the Dimmer 2 additionally (in 3-way switch mode). Function disabled for parameter 20 set to 2 (roller blind switch).
|
||||
Range: 0~1
|
||||
Default: 0
|
||||
</Help>
|
||||
<Item label="Disabled" value="0" />
|
||||
<Item label="Enabled" value="1" />
|
||||
</Value>
|
||||
<Value type="list" byteSize="1" index="28" label="Scene activation functionality" min="0" max="1" value="1" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
SCENE ID depends on the switch type configurations.
|
||||
Range: 0~1
|
||||
Default: 0
|
||||
</Help>
|
||||
<Item label="Disabled" value="0" />
|
||||
<Item label="Enabled" value="1" />
|
||||
</Value>
|
||||
<Value type="list" byteSize="1" index="29" label="Switch functionality of S1 and S2" min="0" max="1" value="0" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
This parameter allows for switching the role of keys connected to S1 and S2 without changes in connection.
|
||||
Range: 0~1
|
||||
Default: 0
|
||||
</Help>
|
||||
<Item label="Standard" value="0" />
|
||||
<Item label="Switched" value="1" />
|
||||
</Value>
|
||||
<Value type="list" byteSize="1" index="35" label="Auto-calibration after power on" min="0" max="4" value="1" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
This parameter determines the trigger of auto-calibration procedure, e.g. power on, load error, etc.
|
||||
0 - No auto-calibration of the load after power on
|
||||
1 - Auto-calibration performed after first power on
|
||||
2 - Auto-calibration performed after each power on
|
||||
3 - Auto-calibration performed after first power on or after each LOAD ERROR alarm (no load, load failure, burnt out bulb), if parameter 37 is set to 1 also after alarms: SURGE (Dimmer 2 output overvoltage) and OVERCURRENT (Dimmer 2 output overcurrent)
|
||||
4 - Auto-calibration performed after each power on or after each LOAD ERROR alarm (no load, load failure, burnt out bulb), if parameter 37 is set to 1 also after alarms: SURGE (Dimmer 2 output overvoltage) and OVERCURRENT (Dimmer 2 output overcurrent)
|
||||
Range: 0~4
|
||||
Default: 1
|
||||
</Help>
|
||||
<Item label="0" value="0" />
|
||||
<Item label="1" value="1" />
|
||||
<Item label="2" value="2" />
|
||||
<Item label="3" value="3" />
|
||||
<Item label="4" value="4" />
|
||||
</Value>
|
||||
<Value type="short" byteSize="2" index="39" label="Max Power load" min="0" max="350" value="250" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
This parameter defines the maximum load for a dimmer.
|
||||
Range: 0~350
|
||||
Default: 250
|
||||
</Help>
|
||||
</Value>
|
||||
<Value type="byte" byteSize="1" index="50" label="Active power reports" min="0" max="100" value="10" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
The parameter defines the power level change that will result in a new power report being sent. The value is a percentage of the previous report.
|
||||
Range: 0~100
|
||||
Default: 10
|
||||
</Help>
|
||||
</Value>
|
||||
<Value type="short" byteSize="2" index="52" label="Periodic active power and energy reports" min="0" max="32767" value="3600" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
Parameter 52 defines a time period between consecutive reports. Timer is reset and counted from zero after each report.
|
||||
Range: 0~32767
|
||||
Default: 3600
|
||||
</Help>
|
||||
</Value>
|
||||
<Value type="short" byteSize="2" index="53" label="Energy reports" min="0" max="255" value="10" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
Energy level change which will result in sending a new energy report.
|
||||
Range: 0~255
|
||||
Default: 10
|
||||
</Help>
|
||||
</Value>
|
||||
<Value type="list" byteSize="1" index="54" label="Self-measurement" min="0" max="1" value="0" setting_type="zwave" fw="3.08">
|
||||
<Help>
|
||||
The Dimmer 2 may include active power and energy consumed by itself in reports sent to the main controller.
|
||||
Range: 0~1
|
||||
Default: 0
|
||||
</Help>
|
||||
<Item label="Disabled" value="0" />
|
||||
<Item label="Enabled" value="1" />
|
||||
</Value>
|
||||
<Value type="boolean" index="enableDebugging" label="Enable Debug Logging?" value="true" setting_type="preference" fw="3.08">
|
||||
<Help>
|
||||
</Help>
|
||||
</Value>
|
||||
</configuration>
|
||||
'''
|
||||
}
|
||||
711
smartapps/app-home-ai/app-home-ai.src/app-home-ai.groovy
Normal file
711
smartapps/app-home-ai/app-home-ai.src/app-home-ai.groovy
Normal file
@@ -0,0 +1,711 @@
|
||||
definition(
|
||||
name: "app.home.ai",
|
||||
namespace: "app.home.ai",
|
||||
author: "Eric Greer",
|
||||
description: "SmartThings SmartApp for app.home.ai.",
|
||||
category: "Fun & Social",
|
||||
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"
|
||||
)
|
||||
|
||||
// These are preferences displayed in the smart phone app
|
||||
preferences {
|
||||
// we need a settings section to enable subscriptions
|
||||
section("Pick which devices home.ai will help you automate:"){
|
||||
input "motion", "capability.motionSensor", title: "Choose motion sensors", required: false, multiple: true
|
||||
input "contact", "capability.contactSensor", title: "Choose contact sensors", required: false, multiple: true
|
||||
input "lightswitch", "capability.switch", title: "Choose normal power switches", required: false, multiple: true
|
||||
input "lightswitchlevel", "capability.switchLevel", title: "Choose dimmer power switches", required: false, multiple: true
|
||||
input "presence", "capability.presenceSensor", title: "Choose presence sensors", required: false, multiple: true
|
||||
// removed in prod until dual-signal devices are supported
|
||||
//input "tempSensor", "capability.temperatureMeasurement", title: "Choose temperature sensors", required: false, multiple: true
|
||||
//input "humidity", "capability.relativeHumidityMeasurement", title: "Choose humidity sensors", required: false, multiple: true
|
||||
input "waterSensor", "capability.waterSensor", title: "Choose water sensors", required: false, multiple: true
|
||||
input "lock", "capability.lock", title: "Pick Door Locks", required: false, multiple: true
|
||||
input "garagedoor", "capability.garageDoorControl", title: "Pick garage doors", required: false, multiple: true
|
||||
input "touchsensor", "capability.touchSensor", title: "Pick touch sensors", required: false, multiple: true
|
||||
input "speechparser", "capability.speechRecognition", title: "Pick speech recognizers", required: false, multiple: true
|
||||
input "soundsensor", "capability.soundSensor", title: "Pick sound sensors", required: false, multiple: true
|
||||
input "smokedetector", "capability.smokeDetector", title: "Pick smoke detectors", required: false, multiple: true
|
||||
input "sleepsensor", "capability.sleepSensor", title: "Pick sleep sensors", required: false, multiple: true
|
||||
input "carbonsensor", "capability.carbonMonoxideDetector", title: "Pick carbon monoxide detectors", required: false, multiple: true
|
||||
input "button", "capability.button", title: "Pick buttons", required: false, multiple: true
|
||||
input "beacon", "capability.beacon", title: "Pick beacons", required: false, multiple: true
|
||||
input "alarm", "capability.alarm", title: "Pick alarms", required: false, multiple: true
|
||||
input "thermostat", "capability.thermostat", title: "Pick thermostats", required: false, multiple: true
|
||||
input "voltage", "capability.voltageMeasurement", title: "Pick voltage sensors", required: false, multiple: true
|
||||
input "windowshade", "capability.windowShade", title: "Pick window shades", required: false, multiple: true
|
||||
input "powermeter", "capability.powerMeter", title: "Pick power meters", required: false, multiple: true
|
||||
}
|
||||
}
|
||||
|
||||
// vlaues for security system are 'away', 'stay', or 'off'
|
||||
// off security
|
||||
def offSecurity() {
|
||||
sendLocationEvent(
|
||||
name: "alarmSystemStatus",
|
||||
value: "off",
|
||||
displayed: false,
|
||||
isStateChange: true)
|
||||
}
|
||||
|
||||
// stay security
|
||||
def staySecurity() {
|
||||
sendLocationEvent(
|
||||
name: "alarmSystemStatus",
|
||||
value: "stay",
|
||||
displayed: false,
|
||||
isStateChange: true)
|
||||
}
|
||||
|
||||
// away security
|
||||
def awaySecurity() {
|
||||
sendLocationEvent(
|
||||
name: "alarmSystemStatus",
|
||||
value: "away",
|
||||
displayed: false,
|
||||
isStateChange: true)
|
||||
}
|
||||
|
||||
// sets window shade open temperature
|
||||
def setWindowShadeOpen() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setWindowShadeOpen command recieved ${deviceID}")
|
||||
windowshade.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating window shade because it is the one specified: ${deviceID}");
|
||||
it.open()
|
||||
} else {
|
||||
log.debug("NOT operting window shade because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sets window shade close temperature
|
||||
def setWindowShadeClosed() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setWindowShadeClosed command recieved ${deviceID}")
|
||||
windowshade.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating window shade because it is the one specified: ${deviceID}");
|
||||
it.close()
|
||||
} else {
|
||||
log.debug("NOT operting window shade because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sets thermostat heating temperature
|
||||
def setThermostatHeatTemp() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setThermostatHeat command recieved ${deviceID}")
|
||||
thermostat.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating thermostat because it is the one specified: ${deviceID}");
|
||||
it.setHeatingSetpoint(params.temp)
|
||||
} else {
|
||||
log.debug("NOT operting thermostat because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sets thermostat cooling temperature
|
||||
def setThermostatCoolTemp() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setThermostatCool command recieved ${deviceID}")
|
||||
thermostat.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating thermostat because it is the one specified: ${deviceID}");
|
||||
it.setCoolingSetpoint(params.temp)
|
||||
} else {
|
||||
log.debug("NOT operting thermostat because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sets thermostat off
|
||||
def setThermostatOff() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setThermostatOff command recieved ${deviceID}")
|
||||
thermostat.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating thermostat because it is the one specified: ${deviceID}");
|
||||
it.off()
|
||||
} else {
|
||||
log.debug("NOT operting thermostat because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sets thermostat to heat
|
||||
def setThermostatHeat() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setThermostatHeat command recieved ${deviceID}")
|
||||
thermostat.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating thermostat because it is the one specified: ${deviceID}");
|
||||
it.heat()
|
||||
} else {
|
||||
log.debug("NOT operting thermostat because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sets thermostat to cool
|
||||
def setThermostatCool() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setThermostatCool command recieved ${deviceID}")
|
||||
thermostat.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating thermostat because it is the one specified: ${deviceID}");
|
||||
it.cool()
|
||||
} else {
|
||||
log.debug("NOT operting thermostat because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sets thermostat mode
|
||||
def setThermostatMode() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setThermostatMode command recieved ${deviceID}")
|
||||
thermostat.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating thermostat because it is the one specified: ${deviceID}");
|
||||
it.setThermostatMode(params.mode)
|
||||
} else {
|
||||
log.debug("NOT operting thermostat because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sets thermostat fan mode
|
||||
def setThermostatFanMode() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setThermostatFanMode command recieved ${deviceID}")
|
||||
thermostat.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating thermostat because it is the one specified: ${deviceID}");
|
||||
it.setThermostatFanMode(params.mode)
|
||||
} else {
|
||||
log.debug("NOT operting thermostat because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sends an alarm strobe
|
||||
def strobeAlarm() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Alarm strobe command recieved ${deviceID}")
|
||||
alarm.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating alarm because it is the one specified: ${deviceID}");
|
||||
it.strobe()
|
||||
} else {
|
||||
log.debug("NOT operting alarm because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sends an alarm siren
|
||||
def sirenAlarm() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Alarm siren command recieved ${deviceID}")
|
||||
alarm.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating alarm because it is the one specified: ${deviceID}");
|
||||
it.siren()
|
||||
} else {
|
||||
log.debug("NOT operting alarm because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// disables an alarm siren
|
||||
def silenceAlarm() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Alarm silence command recieved ${deviceID}")
|
||||
alarm.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating alarm because it is the one specified: ${deviceID}");
|
||||
it.off()
|
||||
} else {
|
||||
log.debug("NOT operting alarm because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// opens a garage door
|
||||
def openGarage() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Open Garage command recieved ${deviceID}")
|
||||
garagedoor.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating garage door because it is the one specified: ${deviceID}");
|
||||
it.open()
|
||||
} else {
|
||||
log.debug("NOT operting garage door device because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// closes a garage door
|
||||
def closeGarage() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Close Garage command recieved ${deviceID}")
|
||||
garagedoor.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating garage door because it is the one specified: ${deviceID}");
|
||||
it.close()
|
||||
} else {
|
||||
log.debug("NOT operting garage door device because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// lock locks a door lock
|
||||
def lockDoor() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Lock command recieved ${deviceID}")
|
||||
lock.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating lock device because it is the one specified: ${deviceID}");
|
||||
it.lock()
|
||||
} else {
|
||||
log.debug("NOT operting lock device because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unlock unlocks a door lock
|
||||
def unlockDoor() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Unlock command recieved ${deviceID}")
|
||||
lock.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating lock device because it is the one specified: ${deviceID}");
|
||||
it.unlock()
|
||||
} else {
|
||||
log.debug("NOT operting lock device because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// turns on a wall switch as instructed from the homeai webservice
|
||||
def switchOn() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Switch on command recieved ${deviceID}")
|
||||
lightswitch.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating switch device because it is the one specified: ${deviceID}");
|
||||
it.on()
|
||||
} else {
|
||||
log.debug("Skipping switch device because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// turns off a wall switch as instructed from the homeai webservice
|
||||
def switchOff() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Switch off desired for ${deviceID}")
|
||||
lightswitch.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating switch device because it is the one specified: ${deviceID}");
|
||||
it.off()
|
||||
} else {
|
||||
log.debug("Skipping switch device because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fetch the id of this smartthings hub
|
||||
def hubId() {
|
||||
log.debug("hub id requested.")
|
||||
def response = [hubId: location.hubs.id[0]]
|
||||
}
|
||||
|
||||
// This handles requests for device inventories
|
||||
def inventory() {
|
||||
def response = []
|
||||
|
||||
lightswitch.each {
|
||||
response << [name: it.displayName, value: it.currentValue("switch"), deviceId: it.id, type: "lightSwitch"]
|
||||
}
|
||||
|
||||
contact.each {
|
||||
response << [name: it.displayName, value: it.currentValue("contact"), deviceId: it.id, type: "contact"]
|
||||
}
|
||||
|
||||
|
||||
motion.each {
|
||||
response << [name: it.displayName, value: it.currentValue("motion"), deviceId: it.id, type: "motion"]
|
||||
}
|
||||
|
||||
presence.each {
|
||||
response << [name: it.displayName, value: it.currentValue("presence"), deviceId: it.id, type: "presence"]
|
||||
}
|
||||
|
||||
// removed until dual device functions are supported on the backend
|
||||
//tempSensor.each {
|
||||
// response << [name: it.displayName, value: it.currentValue("temperature"), deviceId: it.id, type: "tempSensor"]
|
||||
//}
|
||||
|
||||
//humidity.each {
|
||||
// response << [name: it.displayName, value: it.currentValue("humidity"), deviceId: it.id, type: "humiditySensor"]
|
||||
//}
|
||||
|
||||
|
||||
waterSensor.each {
|
||||
response << [name: it.displayName, value: it.currentValue("water"), deviceId: it.id, type: "waterSensor"]
|
||||
}
|
||||
|
||||
lock.each {
|
||||
response << [name: it.displayName, value: it.currentValue("lock"), deviceId: it.id, type: "lock"]
|
||||
}
|
||||
|
||||
|
||||
garagedoor.each {
|
||||
response << [name: it.displayName, value: it.currentValue("door"), deviceId: it.id, type: "garagedoor"]
|
||||
}
|
||||
|
||||
|
||||
touchsensor.each {
|
||||
response << [name: it.displayName, value: it.currentValue("touch"), deviceId: it.id, type: "touchsensor"]
|
||||
}
|
||||
|
||||
|
||||
speechparser.each {
|
||||
response << [name: it.displayName, value: it.currentValue("phraseSpoken"), deviceId: it.id, type: "speechparser"]
|
||||
}
|
||||
|
||||
|
||||
soundsensor.each {
|
||||
response << [name: it.displayName, value: it.currentValue("sound"), deviceId: it.id, type: "sound"]
|
||||
}
|
||||
|
||||
|
||||
smokedetector.each {
|
||||
response << [name: it.displayName, value: it.currentValue("smoke"), deviceId: it.id, type: "smoke"]
|
||||
}
|
||||
|
||||
|
||||
sleepsensor.each {
|
||||
response << [name: it.displayName, value: it.currentValue("sleeping"), deviceId: it.id, type: "sleepsensor"]
|
||||
}
|
||||
|
||||
|
||||
carbonsensor.each {
|
||||
response << [name: it.displayName, value: it.currentValue("carbonMonoxide"), deviceId: it.id, type: "carbonsensor"]
|
||||
}
|
||||
|
||||
|
||||
button.each {
|
||||
response << [name: it.displayName, value: it.currentValue("button"), deviceId: it.id, type: "button"]
|
||||
}
|
||||
|
||||
|
||||
beacon.each {
|
||||
response << [name: it.displayName, value: it.currentValue("presence"), deviceId: it.id, type: "beacon"]
|
||||
}
|
||||
|
||||
|
||||
alarm.each {
|
||||
response << [name: it.displayName, value: it.currentValue("alarm"), deviceId: it.id, type: "alarm"]
|
||||
}
|
||||
|
||||
|
||||
thermostat.each {
|
||||
response << [name: it.displayName, value: it.currentValue("thermostatMode"), deviceId: it.id, type: "thermostat"]
|
||||
}
|
||||
|
||||
|
||||
voltage.each {
|
||||
response << [name: it.displayName, value: it.currentValue("voltage"), deviceId: it.id, type: "voltage"]
|
||||
}
|
||||
|
||||
|
||||
windowshade.each {
|
||||
response << [name: it.displayName, value: it.currentValue("windowShade"), deviceId: it.id, type: "windowshade"]
|
||||
}
|
||||
|
||||
|
||||
powermeter.each {
|
||||
response << [name: it.displayName, value: it.currentValue("power"), deviceId: it.id, type: "powermeter"]
|
||||
}
|
||||
|
||||
|
||||
lightswitchlevel.each {
|
||||
response << [name: it.displayName, value: it.currentValue("level"), deviceId: it.id, type: "lightswitchlevel"]
|
||||
}
|
||||
|
||||
|
||||
|
||||
log.debug("Inventory request processed. Response: " + response)
|
||||
return response
|
||||
}
|
||||
|
||||
// After the user hits the 'install' button in the mobile app
|
||||
def installed() {
|
||||
initialize()
|
||||
}
|
||||
|
||||
// After app settings are changed. All subscriptions are wiped before this is invoked by smartthings.
|
||||
def updated() {
|
||||
unsubscribe()
|
||||
initialize()
|
||||
}
|
||||
|
||||
// This appears to be what the tutorials meant to use in the examples
|
||||
def initialize() {
|
||||
|
||||
// SHM subscription
|
||||
// evt.value will be "off", "stay", or "away"
|
||||
subscribe(location, "alarmSystemStatus", eventForwarder)
|
||||
|
||||
|
||||
// motion sensor subscription
|
||||
subscribe(motion, "motion", eventForwarder)
|
||||
|
||||
|
||||
// Contact sensor subscription
|
||||
subscribe(contact, "contact", eventForwarder)
|
||||
|
||||
|
||||
// power plug subscription
|
||||
subscribe(lightswitch, "switch", eventForwarder)
|
||||
|
||||
|
||||
// presence sensor subscription
|
||||
subscribe(presence, "presence", eventForwarder)
|
||||
|
||||
|
||||
// temperature sensor subscription
|
||||
subscribe(tempSensor, "temperature", eventForwarder)
|
||||
|
||||
|
||||
// water sensor subscription
|
||||
subscribe(waterSensor, "water", eventForwarder)
|
||||
|
||||
|
||||
// humidity sensor subscription
|
||||
subscribe(humidity, "humidity", eventForwarder)
|
||||
|
||||
|
||||
// lock subscription
|
||||
subscribe(lock, "lock", eventForwarder)
|
||||
|
||||
|
||||
// garage door subscription
|
||||
subscribe(garagedoor, "garagedoor", eventForwarder)
|
||||
|
||||
|
||||
// touch sensor subscription
|
||||
subscribe(touchsensor, "touchsensor", eventForwarder)
|
||||
|
||||
|
||||
// speech parser subscription
|
||||
subscribe(speechparser, "phraseSpoken", eventForwarder)
|
||||
|
||||
|
||||
// sound sensor subscription
|
||||
subscribe(soundsensor, "sound", eventForwarder)
|
||||
|
||||
|
||||
// smoke detector subscription
|
||||
subscribe(smokedetector, "smoke", eventForwarder)
|
||||
|
||||
|
||||
// sleep sensor subscription
|
||||
subscribe(sleepsensor, "sleeping", eventForwarder)
|
||||
|
||||
|
||||
// carbon monoxide sensor subscription
|
||||
subscribe(carbonsensor, "carbonMonoxide", eventForwarder)
|
||||
|
||||
|
||||
// button subscription
|
||||
subscribe(button, "button", eventForwarder)
|
||||
|
||||
|
||||
// beacon subscription
|
||||
subscribe(beacon, "presence", eventForwarder)
|
||||
|
||||
|
||||
// alarm subscription
|
||||
subscribe(alarm, "alarm", eventForwarder)
|
||||
|
||||
// thermostat subscriptions
|
||||
subscribe(thermostat, "temperature", eventForwarder)
|
||||
subscribe(thermostat, "heatingSetpoint", eventForwarder)
|
||||
subscribe(thermostat, "coolingSetpoint", eventForwarder)
|
||||
subscribe(thermostat, "thermostatSetpoint", eventForwarder)
|
||||
subscribe(thermostat, "thermostatMode", eventForwarder)
|
||||
subscribe(thermostat, "thermostatFanMode", eventForwarder)
|
||||
subscribe(thermostat, "thermostatOperatingState", eventForwarder)
|
||||
|
||||
// voltage subscription
|
||||
subscribe(voltage, "voltage", eventForwarder)
|
||||
|
||||
// window shade subscription
|
||||
subscribe(windowshade, "windowShade", eventForwarder)
|
||||
|
||||
// shm events
|
||||
subscribe(location, "alarmSystemStatus", shmEventForwarder)
|
||||
|
||||
// power meter subscription
|
||||
subscribe(powermeter, "power", eventForwarder)
|
||||
|
||||
// level switch (dimmer switch)
|
||||
subscribe(lightswitchlevel, "level", eventForwarder)
|
||||
|
||||
}
|
||||
|
||||
def shmEventForwarder(evt) {
|
||||
// evt.value will be "off", "stay", or "away"
|
||||
log.debug("FORWARDING SHM CHANGE" + evt.value + " " + evt.hub.id)
|
||||
|
||||
def deviceState = evt.value
|
||||
def deviceId = "smarthomemonitor"
|
||||
def hubId = hubId()
|
||||
def params = [
|
||||
uri: "https://app.home.ai",
|
||||
path: "/smartThingsPostback/shmStateChange/${hubId}/${deviceId}/${deviceState}"
|
||||
]
|
||||
log.info(params)
|
||||
httpGet(params)
|
||||
}
|
||||
|
||||
// This is used to forward events to the home.ai webservice
|
||||
def eventForwarder(evt) {
|
||||
|
||||
def hubId = location.hubs.id[0]
|
||||
|
||||
log.debug(params.uri + " " + params.path)
|
||||
log.debug("FORWARDING EVENT" + evt.deviceId + " " + evt.value + " " + hubId)
|
||||
|
||||
def deviceId = evt.deviceId
|
||||
def deviceState = evt.value
|
||||
def params = [
|
||||
uri: "https://app.home.ai",
|
||||
path: "/smartThingsPostback/stateChange/${hubId}/${deviceId}/${deviceState}"
|
||||
]
|
||||
log.info(params)
|
||||
httpGet(params)
|
||||
}
|
||||
|
||||
// Mappings that serve web requests against our smart app
|
||||
mappings {
|
||||
path("/inventory") {
|
||||
action: [
|
||||
GET: "inventory"
|
||||
]
|
||||
}
|
||||
path("/hubId") {
|
||||
action: [
|
||||
GET: "hubId"
|
||||
]
|
||||
}
|
||||
path("/switchOn/:deviceID") {
|
||||
action: [
|
||||
GET: "switchOn"
|
||||
]
|
||||
}
|
||||
path("/switchOff/:deviceID") {
|
||||
action: [
|
||||
GET: "switchOff"
|
||||
]
|
||||
}
|
||||
path("/lock/:deviceID") {
|
||||
action: [
|
||||
GET: "lockDoor"
|
||||
]
|
||||
}
|
||||
path("/unlock/:deviceID") {
|
||||
action: [
|
||||
GET: "unlockDoor"
|
||||
]
|
||||
}
|
||||
path("/opengarage/:deviceID") {
|
||||
action: [
|
||||
GET: "openGarage"
|
||||
]
|
||||
}
|
||||
path("/closegarage/:deviceID") {
|
||||
action: [
|
||||
GET: "closeGarage"
|
||||
]
|
||||
}
|
||||
path("/strobeAlarm/:deviceID") {
|
||||
action: [
|
||||
GET: "strobeAlarm"
|
||||
]
|
||||
}
|
||||
path("/sirenAlarm/:deviceID") {
|
||||
action: [
|
||||
GET: "sirenAlarm"
|
||||
]
|
||||
}
|
||||
path("/silenceAlarm/:deviceID") {
|
||||
action: [
|
||||
GET: "silenceAlarm"
|
||||
]
|
||||
}
|
||||
path("/setThermostatHeatTemp/:deviceID/:temp") {
|
||||
action: [
|
||||
GET: "setThermostatHeatTemp"
|
||||
]
|
||||
}
|
||||
path("/setThermostatCoolTemp/:deviceID/:temp") {
|
||||
action: [
|
||||
GET: "setThermostatCoolTemp"
|
||||
]
|
||||
}
|
||||
path("/setThermostatHeat/:deviceID") {
|
||||
action: [
|
||||
GET: "setThermostatHeat"
|
||||
]
|
||||
}
|
||||
path("/setThermostatCool/:deviceID") {
|
||||
action: [
|
||||
GET: "setThermostatCool"
|
||||
]
|
||||
}
|
||||
path("/setThermostatMode/:deviceID/:mode") {
|
||||
action: [
|
||||
GET: "setThermostatMode"
|
||||
]
|
||||
}
|
||||
path("/setThermostatFanMode/:deviceID/:mode") {
|
||||
action: [
|
||||
GET: "setThermostatFanMode"
|
||||
]
|
||||
}
|
||||
path("/closeWindowShade/:deviceID") {
|
||||
action: [
|
||||
GET: "setWindowShadeClosed"
|
||||
]
|
||||
}
|
||||
path("/openWindowShade/:deviceID") {
|
||||
action: [
|
||||
GET: "setWindowShadeOpen"
|
||||
]
|
||||
}
|
||||
path("/awaySecurity") {
|
||||
action: [
|
||||
GET: "awaySecurity"
|
||||
]
|
||||
}
|
||||
path("/staySecurity") {
|
||||
action: [
|
||||
GET: "staySecurity"
|
||||
]
|
||||
}
|
||||
path("/offSecurity") {
|
||||
action: [
|
||||
GET: "offSecurity"
|
||||
]
|
||||
}
|
||||
}
|
||||
829
smartapps/demo-home-ai/demo-home-ai.src/demo-home-ai.groovy
Normal file
829
smartapps/demo-home-ai/demo-home-ai.src/demo-home-ai.groovy
Normal file
@@ -0,0 +1,829 @@
|
||||
definition(
|
||||
name: "demo.home.ai",
|
||||
namespace: "demo.home.ai",
|
||||
author: "Eric Greer",
|
||||
description: "SmartThings demo SmartApp for home.ai.",
|
||||
category: "Fun & Social",
|
||||
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"
|
||||
)
|
||||
|
||||
// These are preferences displayed in the smart phone app
|
||||
preferences {
|
||||
// we need a settings section to enable subscriptions
|
||||
section("Pick which devices home.ai will help you automate:"){
|
||||
input "motion", "capability.motionSensor", title: "Choose motion sensors", required: false, multiple: true
|
||||
input "contact", "capability.contactSensor", title: "Choose contact sensors", required: false, multiple: true
|
||||
input "lightswitch", "capability.switch", title: "Choose normal power switches", required: false, multiple: true
|
||||
input "lightswitchlevel", "capability.switchLevel", title: "Choose dimmer power switches", required: false, multiple: true
|
||||
input "presence", "capability.presenceSensor", title: "Choose presence sensors", required: false, multiple: true
|
||||
input "tempSensor", "capability.temperatureMeasurement", title: "Choose temperature sensors", required: false, multiple: true
|
||||
input "humidity", "capability.relativeHumidityMeasurement", title: "Choose humidity sensors", required: false, multiple: true
|
||||
input "waterSensor", "capability.waterSensor", title: "Choose water sensors", required: false, multiple: true
|
||||
input "lock", "capability.lock", title: "Pick Door Locks", required: false, multiple: true
|
||||
input "garagedoor", "capability.garageDoorControl", title: "Pick garage doors", required: false, multiple: true
|
||||
input "touchsensor", "capability.touchSensor", title: "Pick touch sensors", required: false, multiple: true
|
||||
input "speechparser", "capability.speechRecognition", title: "Pick speech recognizers", required: false, multiple: true
|
||||
input "soundsensor", "capability.soundSensor", title: "Pick sound sensors", required: false, multiple: true
|
||||
input "smokedetector", "capability.smokeDetector", title: "Pick smoke detectors", required: false, multiple: true
|
||||
input "sleepsensor", "capability.sleepSensor", title: "Pick sleep sensors", required: false, multiple: true
|
||||
input "carbonsensor", "capability.carbonMonoxideDetector", title: "Pick carbon monoxide detectors", required: false, multiple: true
|
||||
input "button", "capability.button", title: "Pick buttons", required: false, multiple: true
|
||||
input "beacon", "capability.beacon", title: "Pick beacons", required: false, multiple: true
|
||||
input "alarm", "capability.alarm", title: "Pick alarms", required: false, multiple: true
|
||||
input "thermostat", "capability.thermostat", title: "Pick thermostats", required: false, multiple: true
|
||||
input "voltage", "capability.voltageMeasurement", title: "Pick voltage sensors", required: false, multiple: true
|
||||
input "windowshade", "capability.windowShade", title: "Pick window shades", required: false, multiple: true
|
||||
input "powermeter", "capability.powerMeter", title: "Pick power meters", required: false, multiple: true
|
||||
}
|
||||
}
|
||||
|
||||
// vlaues for security system are 'away', 'stay', or 'off'
|
||||
// off security
|
||||
def offSecurity() {
|
||||
sendLocationEvent(
|
||||
name: "alarmSystemStatus",
|
||||
value: "off",
|
||||
displayed: false,
|
||||
isStateChange: true)
|
||||
}
|
||||
|
||||
// stay security
|
||||
def staySecurity() {
|
||||
sendLocationEvent(
|
||||
name: "alarmSystemStatus",
|
||||
value: "stay",
|
||||
displayed: false,
|
||||
isStateChange: true)
|
||||
}
|
||||
|
||||
// away security
|
||||
def awaySecurity() {
|
||||
sendLocationEvent(
|
||||
name: "alarmSystemStatus",
|
||||
value: "away",
|
||||
displayed: false,
|
||||
isStateChange: true)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// sets window shade open temperature
|
||||
def setWindowShadeOpen() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setWindowShadeOpen command recieved ${deviceID}")
|
||||
windowshade.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating window shade because it is the one specified: ${deviceID}");
|
||||
it.open()
|
||||
} else {
|
||||
log.debug("NOT operting window shade because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sets window shade close temperature
|
||||
def setWindowShadeClosed() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setWindowShadeClosed command recieved ${deviceID}")
|
||||
windowshade.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating window shade because it is the one specified: ${deviceID}");
|
||||
it.close()
|
||||
} else {
|
||||
log.debug("NOT operting window shade because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// sets thermostat heating temperature
|
||||
def setThermostatHeatTemp() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setThermostatHeat command recieved ${deviceID}")
|
||||
thermostat.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating thermostat because it is the one specified: ${deviceID}");
|
||||
it.setHeatingSetpoint(params.temp)
|
||||
} else {
|
||||
log.debug("NOT operting thermostat because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sets thermostat cooling temperature
|
||||
def setThermostatCoolTemp() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setThermostatCool command recieved ${deviceID}")
|
||||
thermostat.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating thermostat because it is the one specified: ${deviceID}");
|
||||
it.setCoolingSetpoint(params.temp)
|
||||
} else {
|
||||
log.debug("NOT operting thermostat because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sets thermostat off
|
||||
def setThermostatOff() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setThermostatOff command recieved ${deviceID}")
|
||||
thermostat.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating thermostat because it is the one specified: ${deviceID}");
|
||||
it.off()
|
||||
} else {
|
||||
log.debug("NOT operting thermostat because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// sets thermostat to heat
|
||||
def setThermostatHeat() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setThermostatHeat command recieved ${deviceID}")
|
||||
thermostat.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating thermostat because it is the one specified: ${deviceID}");
|
||||
it.heat()
|
||||
} else {
|
||||
log.debug("NOT operting thermostat because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// sets thermostat to cool
|
||||
def setThermostatCool() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setThermostatCool command recieved ${deviceID}")
|
||||
thermostat.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating thermostat because it is the one specified: ${deviceID}");
|
||||
it.cool()
|
||||
} else {
|
||||
log.debug("NOT operting thermostat because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// sets thermostat mode
|
||||
def setThermostatMode() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setThermostatMode command recieved ${deviceID}")
|
||||
thermostat.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating thermostat because it is the one specified: ${deviceID}");
|
||||
it.setThermostatMode(params.mode)
|
||||
} else {
|
||||
log.debug("NOT operting thermostat because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
// sets thermostat fan mode
|
||||
def setThermostatFanMode() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setThermostatFanMode command recieved ${deviceID}")
|
||||
thermostat.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating thermostat because it is the one specified: ${deviceID}");
|
||||
it.setThermostatFanMode(params.mode)
|
||||
} else {
|
||||
log.debug("NOT operting thermostat because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// sends an alarm strobe
|
||||
def strobeAlarm() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Alarm strobe command recieved ${deviceID}")
|
||||
alarm.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating alarm because it is the one specified: ${deviceID}");
|
||||
it.strobe()
|
||||
} else {
|
||||
log.debug("NOT operting alarm because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sends an alarm siren
|
||||
def sirenAlarm() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Alarm siren command recieved ${deviceID}")
|
||||
alarm.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating alarm because it is the one specified: ${deviceID}");
|
||||
it.siren()
|
||||
} else {
|
||||
log.debug("NOT operting alarm because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// disables an alarm siren
|
||||
def silenceAlarm() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Alarm silence command recieved ${deviceID}")
|
||||
alarm.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating alarm because it is the one specified: ${deviceID}");
|
||||
it.off()
|
||||
} else {
|
||||
log.debug("NOT operting alarm because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// opens a garage door
|
||||
def openGarage() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Open Garage command recieved ${deviceID}")
|
||||
garagedoor.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating garage door because it is the one specified: ${deviceID}");
|
||||
it.open()
|
||||
} else {
|
||||
log.debug("NOT operting garage door device because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// closes a garage door
|
||||
def closeGarage() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Close Garage command recieved ${deviceID}")
|
||||
garagedoor.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating garage door because it is the one specified: ${deviceID}");
|
||||
it.close()
|
||||
} else {
|
||||
log.debug("NOT operting garage door device because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// lock locks a door lock
|
||||
def lockDoor() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Lock command recieved ${deviceID}")
|
||||
lock.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating lock device because it is the one specified: ${deviceID}");
|
||||
it.lock()
|
||||
} else {
|
||||
log.debug("NOT operting lock device because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unlock unlocks a door lock
|
||||
def unlockDoor() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Unlock command recieved ${deviceID}")
|
||||
lock.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating lock device because it is the one specified: ${deviceID}");
|
||||
it.unlock()
|
||||
} else {
|
||||
log.debug("NOT operting lock device because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// turns on a wall switch as instructed from the homeai webservice
|
||||
def switchOn() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Switch on command recieved ${deviceID}")
|
||||
lightswitch.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating switch device because it is the one specified: ${deviceID}");
|
||||
it.on()
|
||||
} else {
|
||||
log.debug("Skipping switch device because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// turns off a wall switch as instructed from the homeai webservice
|
||||
def switchOff() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Switch off desired for ${deviceID}")
|
||||
lightswitch.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating switch device because it is the one specified: ${deviceID}");
|
||||
it.off()
|
||||
} else {
|
||||
log.debug("Skipping switch device because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// sets a level switch to off
|
||||
def setLevelSwitch0() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Level switch off desired for ${deviceID}")
|
||||
lightswitchlevel.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating level switch device because it is the one specified: ${deviceID}");
|
||||
it.setLevel(0)
|
||||
} else {
|
||||
log.debug("Skipping level switch device because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// sets a level switch to 25%
|
||||
def setLevelSwitch25() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Level switch 25 desired for ${deviceID}")
|
||||
lightswitchlevel.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating level switch device because it is the one specified: ${deviceID}");
|
||||
it.setLevel(25)
|
||||
} else {
|
||||
log.debug("Skipping level switch device because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// sets a level switch to 50%
|
||||
def setLevelSwitch50() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Level switch 50 desired for ${deviceID}")
|
||||
lightswitchlevel.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating level switch device because it is the one specified: ${deviceID}");
|
||||
it.setLevel(50)
|
||||
} else {
|
||||
log.debug("Skipping level switch device because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// sets a level switch to 75%
|
||||
def setLevelSwitch75() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Level switch 75 desired for ${deviceID}")
|
||||
lightswitchlevel.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating level switch device because it is the one specified: ${deviceID}");
|
||||
it.setLevel(75)
|
||||
} else {
|
||||
log.debug("Skipping level switch device because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// sets a level switch to 100%
|
||||
def setLevelSwitch100() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Level switch 100 desired for ${deviceID}")
|
||||
lightswitchlevel.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating level switch device because it is the one specified: ${deviceID}");
|
||||
it.setLevel(100)
|
||||
} else {
|
||||
log.debug("Skipping level switch device because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// fetch the id of this smartthings hub
|
||||
def hubId() {
|
||||
log.debug("hub id requested.")
|
||||
def response = [hubId: location.hubs.id[0]]
|
||||
}
|
||||
|
||||
// This handles requests for device inventories
|
||||
def inventory() {
|
||||
def response = []
|
||||
|
||||
lightswitch.each {
|
||||
response << [name: it.displayName, value: it.currentValue("switch"), deviceId: it.id, type: "lightSwitch"]
|
||||
}
|
||||
|
||||
contact.each {
|
||||
response << [name: it.displayName, value: it.currentValue("contact"), deviceId: it.id, type: "contact"]
|
||||
}
|
||||
|
||||
|
||||
motion.each {
|
||||
response << [name: it.displayName, value: it.currentValue("motion"), deviceId: it.id, type: "motion"]
|
||||
}
|
||||
|
||||
|
||||
presence.each {
|
||||
response << [name: it.displayName, value: it.currentValue("presence"), deviceId: it.id, type: "presence"]
|
||||
}
|
||||
|
||||
|
||||
tempSensor.each {
|
||||
response << [name: it.displayName, value: it.currentValue("temperature"), deviceId: it.id, type: "tempSensor"]
|
||||
}
|
||||
|
||||
|
||||
waterSensor.each {
|
||||
response << [name: it.displayName, value: it.currentValue("water"), deviceId: it.id, type: "waterSensor"]
|
||||
}
|
||||
|
||||
|
||||
humidity.each {
|
||||
response << [name: it.displayName, value: it.currentValue("humidity"), deviceId: it.id, type: "humiditySensor"]
|
||||
}
|
||||
|
||||
|
||||
lock.each {
|
||||
response << [name: it.displayName, value: it.currentValue("lock"), deviceId: it.id, type: "lock"]
|
||||
}
|
||||
|
||||
|
||||
garagedoor.each {
|
||||
response << [name: it.displayName, value: it.currentValue("door"), deviceId: it.id, type: "garagedoor"]
|
||||
}
|
||||
|
||||
|
||||
touchsensor.each {
|
||||
response << [name: it.displayName, value: it.currentValue("touch"), deviceId: it.id, type: "touchsensor"]
|
||||
}
|
||||
|
||||
|
||||
speechparser.each {
|
||||
response << [name: it.displayName, value: it.currentValue("phraseSpoken"), deviceId: it.id, type: "speechparser"]
|
||||
}
|
||||
|
||||
|
||||
soundsensor.each {
|
||||
response << [name: it.displayName, value: it.currentValue("sound"), deviceId: it.id, type: "sound"]
|
||||
}
|
||||
|
||||
|
||||
smokedetector.each {
|
||||
response << [name: it.displayName, value: it.currentValue("smoke"), deviceId: it.id, type: "smoke"]
|
||||
}
|
||||
|
||||
|
||||
sleepsensor.each {
|
||||
response << [name: it.displayName, value: it.currentValue("sleeping"), deviceId: it.id, type: "sleepsensor"]
|
||||
}
|
||||
|
||||
|
||||
carbonsensor.each {
|
||||
response << [name: it.displayName, value: it.currentValue("carbonMonoxide"), deviceId: it.id, type: "carbonsensor"]
|
||||
}
|
||||
|
||||
|
||||
button.each {
|
||||
response << [name: it.displayName, value: it.currentValue("button"), deviceId: it.id, type: "button"]
|
||||
}
|
||||
|
||||
|
||||
beacon.each {
|
||||
response << [name: it.displayName, value: it.currentValue("presence"), deviceId: it.id, type: "beacon"]
|
||||
}
|
||||
|
||||
|
||||
alarm.each {
|
||||
response << [name: it.displayName, value: it.currentValue("alarm"), deviceId: it.id, type: "alarm"]
|
||||
}
|
||||
|
||||
|
||||
thermostat.each {
|
||||
response << [name: it.displayName, value: it.currentValue("thermostatMode"), deviceId: it.id, type: "thermostat"]
|
||||
}
|
||||
|
||||
|
||||
voltage.each {
|
||||
response << [name: it.displayName, value: it.currentValue("voltage"), deviceId: it.id, type: "voltage"]
|
||||
}
|
||||
|
||||
|
||||
windowshade.each {
|
||||
response << [name: it.displayName, value: it.currentValue("windowShade"), deviceId: it.id, type: "windowshade"]
|
||||
}
|
||||
|
||||
|
||||
powermeter.each {
|
||||
response << [name: it.displayName, value: it.currentValue("power"), deviceId: it.id, type: "powermeter"]
|
||||
}
|
||||
|
||||
|
||||
lightswitchlevel.each {
|
||||
response << [name: it.displayName, value: it.currentValue("level"), deviceId: it.id, type: "lightswitchlevel"]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
log.debug("Inventory request processed. Response: " + response)
|
||||
return response
|
||||
}
|
||||
|
||||
// After the user hits the 'install' button in the mobile app
|
||||
def installed() {
|
||||
initialize()
|
||||
|
||||
|
||||
}
|
||||
|
||||
// After app settings are changed. All subscriptions are wiped before this is invoked by smartthings.
|
||||
def updated() {
|
||||
unsubscribe()
|
||||
initialize()
|
||||
|
||||
}
|
||||
|
||||
// This appears to be what the tutorials meant to use in the examples
|
||||
def initialize() {
|
||||
|
||||
// motion sensor subscription
|
||||
subscribe(motion, "motion", eventForwarder)
|
||||
|
||||
|
||||
// Contact sensor subscription
|
||||
subscribe(contact, "contact", eventForwarder)
|
||||
|
||||
|
||||
// power plug subscription
|
||||
subscribe(lightswitch, "switch", eventForwarder)
|
||||
|
||||
|
||||
// presence sensor subscription
|
||||
subscribe(presence, "presence", eventForwarder)
|
||||
|
||||
|
||||
// temperature sensor subscription
|
||||
subscribe(tempSensor, "temperature", eventForwarder)
|
||||
|
||||
|
||||
// water sensor subscription
|
||||
subscribe(waterSensor, "water", eventForwarder)
|
||||
|
||||
|
||||
// humidity sensor subscription
|
||||
subscribe(humidity, "humidity", eventForwarder)
|
||||
|
||||
|
||||
// lock subscription
|
||||
subscribe(lock, "lock", eventForwarder)
|
||||
|
||||
|
||||
// garage door subscription
|
||||
subscribe(garagedoor, "garagedoor", eventForwarder)
|
||||
|
||||
|
||||
// touch sensor subscription
|
||||
subscribe(touchsensor, "touchsensor", eventForwarder)
|
||||
|
||||
|
||||
// speech parser subscription
|
||||
subscribe(speechparser, "phraseSpoken", eventForwarder)
|
||||
|
||||
|
||||
// sound sensor subscription
|
||||
subscribe(soundsensor, "sound", eventForwarder)
|
||||
|
||||
|
||||
// smoke detector subscription
|
||||
subscribe(smokedetector, "smoke", eventForwarder)
|
||||
|
||||
|
||||
// sleep sensor subscription
|
||||
subscribe(sleepsensor, "sleeping", eventForwarder)
|
||||
|
||||
|
||||
// carbon monoxide sensor subscription
|
||||
subscribe(carbonsensor, "carbonMonoxide", eventForwarder)
|
||||
|
||||
|
||||
// button subscription
|
||||
subscribe(button, "button", eventForwarder)
|
||||
|
||||
|
||||
// beacon subscription
|
||||
subscribe(beacon, "presence", eventForwarder)
|
||||
|
||||
|
||||
// alarm subscription
|
||||
subscribe(alarm, "alarm", eventForwarder)
|
||||
|
||||
// thermostat subscriptions
|
||||
subscribe(thermostat, "temperature", eventForwarder)
|
||||
subscribe(thermostat, "heatingSetpoint", eventForwarder)
|
||||
subscribe(thermostat, "coolingSetpoint", eventForwarder)
|
||||
subscribe(thermostat, "thermostatSetpoint", eventForwarder)
|
||||
subscribe(thermostat, "thermostatMode", eventForwarder)
|
||||
subscribe(thermostat, "thermostatFanMode", eventForwarder)
|
||||
subscribe(thermostat, "thermostatOperatingState", eventForwarder)
|
||||
|
||||
// voltage subscription
|
||||
subscribe(voltage, "voltage", eventForwarder)
|
||||
|
||||
// window shade subscription
|
||||
subscribe(windowshade, "windowShade", eventForwarder)
|
||||
|
||||
// shm events
|
||||
subscribe(location, "alarmSystemStatus", shmEventForwarder)
|
||||
|
||||
// power meter subscription
|
||||
subscribe(powermeter, "power", eventForwarder)
|
||||
|
||||
// level switch (dimmer switch)
|
||||
subscribe(lightswitchlevel, "level", eventForwarder)
|
||||
}
|
||||
|
||||
// This is used to forward events to the home.ai webservice
|
||||
def eventForwarder(evt) {
|
||||
|
||||
|
||||
log.debug(params.uri + " " + params.path)
|
||||
|
||||
log.debug("FORWARDING EVENT" + evt.deviceId + " " + evt.value + " " + evt.hub.id)
|
||||
|
||||
def deviceId = evt.deviceId
|
||||
def deviceState = evt.value
|
||||
def hubId = evt.hub.id
|
||||
def params = [
|
||||
uri: "https://demo.home.ai",
|
||||
path: "/smartThingsPostback/stateChange/${hubId}/${deviceId}/${deviceState}"
|
||||
]
|
||||
log.info(params)
|
||||
httpGet(params)
|
||||
}
|
||||
|
||||
// Mappings that serve web requests against our smart app
|
||||
mappings {
|
||||
path("/inventory") {
|
||||
action: [
|
||||
GET: "inventory"
|
||||
]
|
||||
}
|
||||
path("/hubId") {
|
||||
action: [
|
||||
GET: "hubId"
|
||||
]
|
||||
}
|
||||
path("/switchOn/:deviceID") {
|
||||
action: [
|
||||
GET: "switchOn"
|
||||
]
|
||||
}
|
||||
path("/switchOff/:deviceID") {
|
||||
action: [
|
||||
GET: "switchOff"
|
||||
]
|
||||
}
|
||||
path("/lock/:deviceID") {
|
||||
action: [
|
||||
GET: "lockDoor"
|
||||
]
|
||||
}
|
||||
path("/unlock/:deviceID") {
|
||||
action: [
|
||||
GET: "unlockDoor"
|
||||
]
|
||||
}
|
||||
path("/opengarage/:deviceID") {
|
||||
action: [
|
||||
GET: "openGarage"
|
||||
]
|
||||
}
|
||||
path("/closegarage/:deviceID") {
|
||||
action: [
|
||||
GET: "closeGarage"
|
||||
]
|
||||
}
|
||||
|
||||
path("/strobeAlarm/:deviceID") {
|
||||
action: [
|
||||
GET: "strobeAlarm"
|
||||
]
|
||||
}
|
||||
path("/sirenAlarm/:deviceID") {
|
||||
action: [
|
||||
GET: "sirenAlarm"
|
||||
]
|
||||
}
|
||||
path("/silenceAlarm/:deviceID") {
|
||||
action: [
|
||||
GET: "silenceAlarm"
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
path("/setThermostatHeatTemp/:deviceID/:temp") {
|
||||
action: [
|
||||
GET: "setThermostatHeatTemp"
|
||||
]
|
||||
}
|
||||
path("/setThermostatCoolTemp/:deviceID/:temp") {
|
||||
action: [
|
||||
GET: "setThermostatCoolTemp"
|
||||
]
|
||||
}
|
||||
path("/setThermostatHeat/:deviceID") {
|
||||
action: [
|
||||
GET: "setThermostatHeat"
|
||||
]
|
||||
}
|
||||
path("/setThermostatCool/:deviceID") {
|
||||
action: [
|
||||
GET: "setThermostatCool"
|
||||
]
|
||||
}
|
||||
path("/setThermostatMode/:deviceID/:mode") {
|
||||
action: [
|
||||
GET: "setThermostatMode"
|
||||
]
|
||||
}
|
||||
path("/setThermostatFanMode/:deviceID/:mode") {
|
||||
action: [
|
||||
GET: "setThermostatFanMode"
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
path("/closeWindowShade/:deviceID") {
|
||||
action: [
|
||||
GET: "setWindowShadeClosed"
|
||||
]
|
||||
}
|
||||
path("/openWindowShade/:deviceID") {
|
||||
action: [
|
||||
GET: "setWindowShadeOpen"
|
||||
]
|
||||
}
|
||||
|
||||
// level switch setting endpoints
|
||||
path("/levelSwitch0/:deviceID") {
|
||||
action: [
|
||||
GET: "setLevelSwitch0"
|
||||
]
|
||||
}
|
||||
path("/levelSwitch25/:deviceID") {
|
||||
action: [
|
||||
GET: "setLevelSwitch25"
|
||||
]
|
||||
}
|
||||
path("/levelSwitch50/:deviceID") {
|
||||
action: [
|
||||
GET: "setLevelSwitch50"
|
||||
]
|
||||
}
|
||||
path("/levelSwitch75/:deviceID") {
|
||||
action: [
|
||||
GET: "setLevelSwitch75"
|
||||
]
|
||||
}
|
||||
path("/levelSwitch100/:deviceID") {
|
||||
action: [
|
||||
GET: "setLevelSwitch100"
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Smart home monitor controls
|
||||
path("/awaySecurity") {
|
||||
action: [
|
||||
GET: "awaySecurity"
|
||||
]
|
||||
}
|
||||
path("/staySecurity") {
|
||||
action: [
|
||||
GET: "staySecurity"
|
||||
]
|
||||
}
|
||||
path("/offSecurity") {
|
||||
action: [
|
||||
GET: "offSecurity"
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,713 @@
|
||||
definition(
|
||||
name: "stage.app.home.ai",
|
||||
namespace: "stage.app.home.ai",
|
||||
author: "Eric Greer",
|
||||
description: "SmartThings SmartApp for stage.app.home.ai.",
|
||||
category: "Fun & Social",
|
||||
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"
|
||||
)
|
||||
|
||||
// These are preferences displayed in the smart phone app
|
||||
preferences {
|
||||
// we need a settings section to enable subscriptions
|
||||
section("Pick which devices home.ai will help you automate:"){
|
||||
input "motion", "capability.motionSensor", title: "Choose motion sensors", required: false, multiple: true
|
||||
input "contact", "capability.contactSensor", title: "Choose contact sensors", required: false, multiple: true
|
||||
input "lightswitch", "capability.switch", title: "Choose normal power switches", required: false, multiple: true
|
||||
input "lightswitchlevel", "capability.switchLevel", title: "Choose dimmer power switches", required: false, multiple: true
|
||||
input "presence", "capability.presenceSensor", title: "Choose presence sensors", required: false, multiple: true
|
||||
input "tempSensor", "capability.temperatureMeasurement", title: "Choose temperature sensors", required: false, multiple: true
|
||||
input "humidity", "capability.relativeHumidityMeasurement", title: "Choose humidity sensors", required: false, multiple: true
|
||||
input "waterSensor", "capability.waterSensor", title: "Choose water sensors", required: false, multiple: true
|
||||
input "lock", "capability.lock", title: "Pick Door Locks", required: false, multiple: true
|
||||
input "garagedoor", "capability.garageDoorControl", title: "Pick garage doors", required: false, multiple: true
|
||||
input "touchsensor", "capability.touchSensor", title: "Pick touch sensors", required: false, multiple: true
|
||||
input "speechparser", "capability.speechRecognition", title: "Pick speech recognizers", required: false, multiple: true
|
||||
input "soundsensor", "capability.soundSensor", title: "Pick sound sensors", required: false, multiple: true
|
||||
input "smokedetector", "capability.smokeDetector", title: "Pick smoke detectors", required: false, multiple: true
|
||||
input "sleepsensor", "capability.sleepSensor", title: "Pick sleep sensors", required: false, multiple: true
|
||||
input "carbonsensor", "capability.carbonMonoxideDetector", title: "Pick carbon monoxide detectors", required: false, multiple: true
|
||||
input "button", "capability.button", title: "Pick buttons", required: false, multiple: true
|
||||
input "beacon", "capability.beacon", title: "Pick beacons", required: false, multiple: true
|
||||
input "alarm", "capability.alarm", title: "Pick alarms", required: false, multiple: true
|
||||
input "thermostat", "capability.thermostat", title: "Pick thermostats", required: false, multiple: true
|
||||
input "voltage", "capability.voltageMeasurement", title: "Pick voltage sensors", required: false, multiple: true
|
||||
input "windowshade", "capability.windowShade", title: "Pick window shades", required: false, multiple: true
|
||||
input "powermeter", "capability.powerMeter", title: "Pick power meters", required: false, multiple: true
|
||||
}
|
||||
}
|
||||
|
||||
// vlaues for security system are 'away', 'stay', or 'off'
|
||||
// off security
|
||||
def offSecurity() {
|
||||
sendLocationEvent(
|
||||
name: "alarmSystemStatus",
|
||||
value: "off",
|
||||
displayed: false,
|
||||
isStateChange: true
|
||||
)
|
||||
}
|
||||
|
||||
// stay security
|
||||
def staySecurity() {
|
||||
sendLocationEvent(
|
||||
name: "alarmSystemStatus",
|
||||
value: "stay",
|
||||
displayed: false,
|
||||
isStateChange: true
|
||||
)
|
||||
}
|
||||
|
||||
// away security
|
||||
def awaySecurity() {
|
||||
sendLocationEvent(
|
||||
name: "alarmSystemStatus",
|
||||
value: "away",
|
||||
displayed: false,
|
||||
isStateChange: true
|
||||
)
|
||||
}
|
||||
|
||||
// sets window shade open temperature
|
||||
def setWindowShadeOpen() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setWindowShadeOpen command recieved ${deviceID}")
|
||||
windowshade.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating window shade because it is the one specified: ${deviceID}");
|
||||
it.open()
|
||||
} else {
|
||||
log.debug("NOT operting window shade because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sets window shade close temperature
|
||||
def setWindowShadeClosed() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setWindowShadeClosed command recieved ${deviceID}")
|
||||
windowshade.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating window shade because it is the one specified: ${deviceID}");
|
||||
it.close()
|
||||
} else {
|
||||
log.debug("NOT operting window shade because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sets thermostat heating temperature
|
||||
def setThermostatHeatTemp() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setThermostatHeat command recieved ${deviceID}")
|
||||
thermostat.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating thermostat because it is the one specified: ${deviceID}");
|
||||
it.setHeatingSetpoint(params.temp)
|
||||
} else {
|
||||
log.debug("NOT operting thermostat because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sets thermostat cooling temperature
|
||||
def setThermostatCoolTemp() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setThermostatCool command recieved ${deviceID}")
|
||||
thermostat.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating thermostat because it is the one specified: ${deviceID}");
|
||||
it.setCoolingSetpoint(params.temp)
|
||||
} else {
|
||||
log.debug("NOT operting thermostat because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sets thermostat off
|
||||
def setThermostatOff() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setThermostatOff command recieved ${deviceID}")
|
||||
thermostat.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating thermostat because it is the one specified: ${deviceID}");
|
||||
it.off()
|
||||
} else {
|
||||
log.debug("NOT operting thermostat because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sets thermostat to heat
|
||||
def setThermostatHeat() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setThermostatHeat command recieved ${deviceID}")
|
||||
thermostat.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating thermostat because it is the one specified: ${deviceID}");
|
||||
it.heat()
|
||||
} else {
|
||||
log.debug("NOT operting thermostat because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sets thermostat to cool
|
||||
def setThermostatCool() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setThermostatCool command recieved ${deviceID}")
|
||||
thermostat.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating thermostat because it is the one specified: ${deviceID}");
|
||||
it.cool()
|
||||
} else {
|
||||
log.debug("NOT operting thermostat because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sets thermostat mode
|
||||
def setThermostatMode() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setThermostatMode command recieved ${deviceID}")
|
||||
thermostat.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating thermostat because it is the one specified: ${deviceID}");
|
||||
it.setThermostatMode(params.mode)
|
||||
} else {
|
||||
log.debug("NOT operting thermostat because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sets thermostat fan mode
|
||||
def setThermostatFanMode() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("setThermostatFanMode command recieved ${deviceID}")
|
||||
thermostat.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating thermostat because it is the one specified: ${deviceID}");
|
||||
it.setThermostatFanMode(params.mode)
|
||||
} else {
|
||||
log.debug("NOT operting thermostat because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sends an alarm strobe
|
||||
def strobeAlarm() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Alarm strobe command recieved ${deviceID}")
|
||||
alarm.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating alarm because it is the one specified: ${deviceID}");
|
||||
it.strobe()
|
||||
} else {
|
||||
log.debug("NOT operting alarm because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sends an alarm siren
|
||||
def sirenAlarm() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Alarm siren command recieved ${deviceID}")
|
||||
alarm.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating alarm because it is the one specified: ${deviceID}");
|
||||
it.siren()
|
||||
} else {
|
||||
log.debug("NOT operting alarm because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// disables an alarm siren
|
||||
def silenceAlarm() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Alarm silence command recieved ${deviceID}")
|
||||
alarm.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating alarm because it is the one specified: ${deviceID}");
|
||||
it.off()
|
||||
} else {
|
||||
log.debug("NOT operting alarm because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// opens a garage door
|
||||
def openGarage() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Open Garage command recieved ${deviceID}")
|
||||
garagedoor.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating garage door because it is the one specified: ${deviceID}");
|
||||
it.open()
|
||||
} else {
|
||||
log.debug("NOT operting garage door device because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// closes a garage door
|
||||
def closeGarage() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Close Garage command recieved ${deviceID}")
|
||||
garagedoor.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating garage door because it is the one specified: ${deviceID}");
|
||||
it.close()
|
||||
} else {
|
||||
log.debug("NOT operting garage door device because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// lock locks a door lock
|
||||
def lockDoor() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Lock command recieved ${deviceID}")
|
||||
lock.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating lock device because it is the one specified: ${deviceID}");
|
||||
it.lock()
|
||||
} else {
|
||||
log.debug("NOT operting lock device because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unlock unlocks a door lock
|
||||
def unlockDoor() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Unlock command recieved ${deviceID}")
|
||||
lock.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating lock device because it is the one specified: ${deviceID}");
|
||||
it.unlock()
|
||||
} else {
|
||||
log.debug("NOT operting lock device because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// turns on a wall switch as instructed from the homeai webservice
|
||||
def switchOn() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Switch on command recieved ${deviceID}")
|
||||
lightswitch.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating switch device because it is the one specified: ${deviceID}");
|
||||
it.on()
|
||||
} else {
|
||||
log.debug("Skipping switch device because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// turns off a wall switch as instructed from the homeai webservice
|
||||
def switchOff() {
|
||||
def deviceID = params.deviceID
|
||||
log.debug("Switch off desired for ${deviceID}")
|
||||
lightswitch.each {
|
||||
if (it.id == deviceID) {
|
||||
log.debug("Operating switch device because it is the one specified: ${deviceID}");
|
||||
it.off()
|
||||
} else {
|
||||
log.debug("Skipping switch device because it is not the one specified: ${deviceID}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fetch the id of this smartthings hub
|
||||
def hubId() {
|
||||
log.debug("hub id requested.")
|
||||
def response = [hubId: location.hubs.id[0]]
|
||||
}
|
||||
|
||||
// This handles requests for device inventories
|
||||
def inventory() {
|
||||
def response = []
|
||||
|
||||
lightswitch.each {
|
||||
response << [name: it.displayName, value: it.currentValue("switch"), deviceId: it.id, type: "lightSwitch"]
|
||||
}
|
||||
|
||||
contact.each {
|
||||
response << [name: it.displayName, value: it.currentValue("contact"), deviceId: it.id, type: "contact"]
|
||||
}
|
||||
|
||||
|
||||
motion.each {
|
||||
response << [name: it.displayName, value: it.currentValue("motion"), deviceId: it.id, type: "motion"]
|
||||
}
|
||||
|
||||
presence.each {
|
||||
response << [name: it.displayName, value: it.currentValue("presence"), deviceId: it.id, type: "presence"]
|
||||
}
|
||||
|
||||
// removed until dual device functions are supported on the backend
|
||||
//tempSensor.each {
|
||||
// response << [name: it.displayName, value: it.currentValue("temperature"), deviceId: it.id, type: "tempSensor"]
|
||||
//}
|
||||
|
||||
//humidity.each {
|
||||
// response << [name: it.displayName, value: it.currentValue("humidity"), deviceId: it.id, type: "humiditySensor"]
|
||||
//}
|
||||
|
||||
|
||||
waterSensor.each {
|
||||
response << [name: it.displayName, value: it.currentValue("water"), deviceId: it.id, type: "waterSensor"]
|
||||
}
|
||||
|
||||
lock.each {
|
||||
response << [name: it.displayName, value: it.currentValue("lock"), deviceId: it.id, type: "lock"]
|
||||
}
|
||||
|
||||
|
||||
garagedoor.each {
|
||||
response << [name: it.displayName, value: it.currentValue("door"), deviceId: it.id, type: "garagedoor"]
|
||||
}
|
||||
|
||||
|
||||
touchsensor.each {
|
||||
response << [name: it.displayName, value: it.currentValue("touch"), deviceId: it.id, type: "touchsensor"]
|
||||
}
|
||||
|
||||
|
||||
speechparser.each {
|
||||
response << [name: it.displayName, value: it.currentValue("phraseSpoken"), deviceId: it.id, type: "speechparser"]
|
||||
}
|
||||
|
||||
|
||||
soundsensor.each {
|
||||
response << [name: it.displayName, value: it.currentValue("sound"), deviceId: it.id, type: "sound"]
|
||||
}
|
||||
|
||||
|
||||
smokedetector.each {
|
||||
response << [name: it.displayName, value: it.currentValue("smoke"), deviceId: it.id, type: "smoke"]
|
||||
}
|
||||
|
||||
|
||||
sleepsensor.each {
|
||||
response << [name: it.displayName, value: it.currentValue("sleeping"), deviceId: it.id, type: "sleepsensor"]
|
||||
}
|
||||
|
||||
|
||||
carbonsensor.each {
|
||||
response << [name: it.displayName, value: it.currentValue("carbonMonoxide"), deviceId: it.id, type: "carbonsensor"]
|
||||
}
|
||||
|
||||
|
||||
button.each {
|
||||
response << [name: it.displayName, value: it.currentValue("button"), deviceId: it.id, type: "button"]
|
||||
}
|
||||
|
||||
|
||||
beacon.each {
|
||||
response << [name: it.displayName, value: it.currentValue("presence"), deviceId: it.id, type: "beacon"]
|
||||
}
|
||||
|
||||
|
||||
alarm.each {
|
||||
response << [name: it.displayName, value: it.currentValue("alarm"), deviceId: it.id, type: "alarm"]
|
||||
}
|
||||
|
||||
|
||||
thermostat.each {
|
||||
response << [name: it.displayName, value: it.currentValue("thermostatMode"), deviceId: it.id, type: "thermostat"]
|
||||
}
|
||||
|
||||
|
||||
voltage.each {
|
||||
response << [name: it.displayName, value: it.currentValue("voltage"), deviceId: it.id, type: "voltage"]
|
||||
}
|
||||
|
||||
|
||||
windowshade.each {
|
||||
response << [name: it.displayName, value: it.currentValue("windowShade"), deviceId: it.id, type: "windowshade"]
|
||||
}
|
||||
|
||||
|
||||
powermeter.each {
|
||||
response << [name: it.displayName, value: it.currentValue("power"), deviceId: it.id, type: "powermeter"]
|
||||
}
|
||||
|
||||
|
||||
lightswitchlevel.each {
|
||||
response << [name: it.displayName, value: it.currentValue("level"), deviceId: it.id, type: "lightswitchlevel"]
|
||||
}
|
||||
|
||||
|
||||
|
||||
log.debug("Inventory request processed. Response: " + response)
|
||||
return response
|
||||
}
|
||||
|
||||
// After the user hits the 'install' button in the mobile app
|
||||
def installed() {
|
||||
initialize()
|
||||
}
|
||||
|
||||
// After app settings are changed. All subscriptions are wiped before this is invoked by smartthings.
|
||||
def updated() {
|
||||
unsubscribe()
|
||||
initialize()
|
||||
}
|
||||
|
||||
// This appears to be what the tutorials meant to use in the examples
|
||||
def initialize() {
|
||||
|
||||
// SHM subscription
|
||||
// evt.value will be "off", "stay", or "away"
|
||||
subscribe(location, "alarmSystemStatus", eventForwarder)
|
||||
|
||||
|
||||
// motion sensor subscription
|
||||
subscribe(motion, "motion", eventForwarder)
|
||||
|
||||
|
||||
// Contact sensor subscription
|
||||
subscribe(contact, "contact", eventForwarder)
|
||||
|
||||
|
||||
// power plug subscription
|
||||
subscribe(lightswitch, "switch", eventForwarder)
|
||||
|
||||
|
||||
// presence sensor subscription
|
||||
subscribe(presence, "presence", eventForwarder)
|
||||
|
||||
|
||||
// temperature sensor subscription
|
||||
subscribe(tempSensor, "temperature", eventForwarder)
|
||||
|
||||
|
||||
// water sensor subscription
|
||||
subscribe(waterSensor, "water", eventForwarder)
|
||||
|
||||
|
||||
// humidity sensor subscription
|
||||
subscribe(humidity, "humidity", eventForwarder)
|
||||
|
||||
|
||||
// lock subscription
|
||||
subscribe(lock, "lock", eventForwarder)
|
||||
|
||||
|
||||
// garage door subscription
|
||||
subscribe(garagedoor, "garagedoor", eventForwarder)
|
||||
|
||||
|
||||
// touch sensor subscription
|
||||
subscribe(touchsensor, "touchsensor", eventForwarder)
|
||||
|
||||
|
||||
// speech parser subscription
|
||||
subscribe(speechparser, "phraseSpoken", eventForwarder)
|
||||
|
||||
|
||||
// sound sensor subscription
|
||||
subscribe(soundsensor, "sound", eventForwarder)
|
||||
|
||||
|
||||
// smoke detector subscription
|
||||
subscribe(smokedetector, "smoke", eventForwarder)
|
||||
|
||||
|
||||
// sleep sensor subscription
|
||||
subscribe(sleepsensor, "sleeping", eventForwarder)
|
||||
|
||||
|
||||
// carbon monoxide sensor subscription
|
||||
subscribe(carbonsensor, "carbonMonoxide", eventForwarder)
|
||||
|
||||
|
||||
// button subscription
|
||||
subscribe(button, "button", eventForwarder)
|
||||
|
||||
|
||||
// beacon subscription
|
||||
subscribe(beacon, "presence", eventForwarder)
|
||||
|
||||
|
||||
// alarm subscription
|
||||
subscribe(alarm, "alarm", eventForwarder)
|
||||
|
||||
// thermostat subscriptions
|
||||
subscribe(thermostat, "temperature", eventForwarder)
|
||||
subscribe(thermostat, "heatingSetpoint", eventForwarder)
|
||||
subscribe(thermostat, "coolingSetpoint", eventForwarder)
|
||||
subscribe(thermostat, "thermostatSetpoint", eventForwarder)
|
||||
subscribe(thermostat, "thermostatMode", eventForwarder)
|
||||
subscribe(thermostat, "thermostatFanMode", eventForwarder)
|
||||
subscribe(thermostat, "thermostatOperatingState", eventForwarder)
|
||||
|
||||
// voltage subscription
|
||||
subscribe(voltage, "voltage", eventForwarder)
|
||||
|
||||
// window shade subscription
|
||||
subscribe(windowshade, "windowShade", eventForwarder)
|
||||
|
||||
// shm events
|
||||
subscribe(location, "alarmSystemStatus", shmEventForwarder)
|
||||
|
||||
// power meter subscription
|
||||
subscribe(powermeter, "power", eventForwarder)
|
||||
|
||||
// level switch (dimmer switch)
|
||||
subscribe(lightswitchlevel, "level", eventForwarder)
|
||||
}
|
||||
|
||||
def shmEventForwarder(evt) {
|
||||
// evt.value will be "off", "stay", or "away"
|
||||
log.debug("FORWARDING SHM CHANGE" + evt.value + " " + evt.hub.id)
|
||||
|
||||
def deviceState = evt.value
|
||||
def deviceId = "smarthomemonitor"
|
||||
def hubId = hubId()
|
||||
def params = [
|
||||
uri: "https://stage.app.home.ai",
|
||||
path: "/smartThingsPostback/shmStateChange/${hubId}/${deviceId}/${deviceState}"
|
||||
]
|
||||
log.info(params)
|
||||
httpGet(params)
|
||||
|
||||
}
|
||||
|
||||
// This is used to forward events to the home.ai webservice
|
||||
def eventForwarder(evt) {
|
||||
|
||||
def hubId = location.hubs.id[0]
|
||||
|
||||
log.debug(params.uri + " " + params.path)
|
||||
log.debug("FORWARDING EVENT" + evt.deviceId + " " + evt.value + " " + hubId)
|
||||
|
||||
def deviceId = evt.deviceId
|
||||
def deviceState = evt.value
|
||||
def params = [
|
||||
uri: "https://stage.app.home.ai",
|
||||
path: "/smartThingsPostback/stateChange/${hubId}/${deviceId}/${deviceState}"
|
||||
]
|
||||
log.info(params)
|
||||
httpGet(params)
|
||||
}
|
||||
|
||||
// Mappings that serve web requests against our smart app
|
||||
mappings {
|
||||
path("/inventory") {
|
||||
action: [
|
||||
GET: "inventory"
|
||||
]
|
||||
}
|
||||
path("/hubId") {
|
||||
action: [
|
||||
GET: "hubId"
|
||||
]
|
||||
}
|
||||
path("/switchOn/:deviceID") {
|
||||
action: [
|
||||
GET: "switchOn"
|
||||
]
|
||||
}
|
||||
path("/switchOff/:deviceID") {
|
||||
action: [
|
||||
GET: "switchOff"
|
||||
]
|
||||
}
|
||||
path("/lock/:deviceID") {
|
||||
action: [
|
||||
GET: "lockDoor"
|
||||
]
|
||||
}
|
||||
path("/unlock/:deviceID") {
|
||||
action: [
|
||||
GET: "unlockDoor"
|
||||
]
|
||||
}
|
||||
path("/opengarage/:deviceID") {
|
||||
action: [
|
||||
GET: "openGarage"
|
||||
]
|
||||
}
|
||||
path("/closegarage/:deviceID") {
|
||||
action: [
|
||||
GET: "closeGarage"
|
||||
]
|
||||
}
|
||||
path("/strobeAlarm/:deviceID") {
|
||||
action: [
|
||||
GET: "strobeAlarm"
|
||||
]
|
||||
}
|
||||
path("/sirenAlarm/:deviceID") {
|
||||
action: [
|
||||
GET: "sirenAlarm"
|
||||
]
|
||||
}
|
||||
path("/silenceAlarm/:deviceID") {
|
||||
action: [
|
||||
GET: "silenceAlarm"
|
||||
]
|
||||
}
|
||||
path("/setThermostatHeatTemp/:deviceID/:temp") {
|
||||
action: [
|
||||
GET: "setThermostatHeatTemp"
|
||||
]
|
||||
}
|
||||
path("/setThermostatCoolTemp/:deviceID/:temp") {
|
||||
action: [
|
||||
GET: "setThermostatCoolTemp"
|
||||
]
|
||||
}
|
||||
path("/setThermostatHeat/:deviceID") {
|
||||
action: [
|
||||
GET: "setThermostatHeat"
|
||||
]
|
||||
}
|
||||
path("/setThermostatCool/:deviceID") {
|
||||
action: [
|
||||
GET: "setThermostatCool"
|
||||
]
|
||||
}
|
||||
path("/setThermostatMode/:deviceID/:mode") {
|
||||
action: [
|
||||
GET: "setThermostatMode"
|
||||
]
|
||||
}
|
||||
path("/setThermostatFanMode/:deviceID/:mode") {
|
||||
action: [
|
||||
GET: "setThermostatFanMode"
|
||||
]
|
||||
}
|
||||
path("/closeWindowShade/:deviceID") {
|
||||
action: [
|
||||
GET: "setWindowShadeClosed"
|
||||
]
|
||||
}
|
||||
path("/openWindowShade/:deviceID") {
|
||||
action: [
|
||||
GET: "setWindowShadeOpen"
|
||||
]
|
||||
}
|
||||
path("/awaySecurity") {
|
||||
action: [
|
||||
GET: "awaySecurity"
|
||||
]
|
||||
}
|
||||
path("/staySecurity") {
|
||||
action: [
|
||||
GET: "staySecurity"
|
||||
]
|
||||
}
|
||||
path("/offSecurity") {
|
||||
action: [
|
||||
GET: "offSecurity"
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user