mirror of
https://github.com/mtan93/SmartThingsPublic.git
synced 2026-03-30 06:13:05 +01:00
Compare commits
1 Commits
PROD_2017.
...
MSA-1817-1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f140fe0d29 |
@@ -9,7 +9,7 @@ apply plugin: 'smartthings-slack'
|
|||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath "com.smartthings.deployment:executable-deployment-scripts:1.0.11"
|
classpath "com.smartthings.deployment:executable-deployment-scripts:1.0.8"
|
||||||
}
|
}
|
||||||
repositories {
|
repositories {
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
|
|||||||
@@ -21,14 +21,12 @@ metadata {
|
|||||||
capability "Tamper Alert"
|
capability "Tamper Alert"
|
||||||
capability "Temperature Measurement"
|
capability "Temperature Measurement"
|
||||||
capability "Water Sensor"
|
capability "Water Sensor"
|
||||||
capability "Health Check"
|
|
||||||
|
|
||||||
fingerprint deviceId: "0x0701", inClusters: "0x5E, 0x22, 0x85, 0x59, 0x20, 0x80, 0x70, 0x56, 0x5A, 0x7A, 0x72, 0x8E, 0x71, 0x73, 0x98, 0x9C, 0x31, 0x86", outClusters: ""
|
fingerprint deviceId: "0x0701", inClusters: "0x5E, 0x22, 0x85, 0x59, 0x20, 0x80, 0x70, 0x56, 0x5A, 0x7A, 0x72, 0x8E, 0x71, 0x73, 0x98, 0x9C, 0x31, 0x86", outClusters: ""
|
||||||
fingerprint mfr:"010F", prod:"0B01", model:"2002"
|
|
||||||
fingerprint mfr:"010F", prod:"0B01", model:"1002"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
simulator {
|
simulator {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tiles(scale: 2) {
|
tiles(scale: 2) {
|
||||||
@@ -124,9 +122,11 @@ def zwaveEvent(physicalgraph.zwave.commands.wakeupv2.WakeUpNotification cmd)
|
|||||||
{
|
{
|
||||||
def event = createEvent(descriptionText: "${device.displayName} woke up", displayed: false)
|
def event = createEvent(descriptionText: "${device.displayName} woke up", displayed: false)
|
||||||
def cmds = []
|
def cmds = []
|
||||||
// cmds << encap(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 1, scale: 0))
|
|
||||||
// cmds << "delay 500"
|
|
||||||
cmds << encap(zwave.batteryV1.batteryGet())
|
cmds << encap(zwave.batteryV1.batteryGet())
|
||||||
|
cmds << "delay 500"
|
||||||
|
cmds << encap(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 1, scale: 0))
|
||||||
|
cmds << "delay 1200"
|
||||||
|
cmds << encap(zwave.wakeUpV1.wakeUpNoMoreInformation())
|
||||||
[event, response(cmds)]
|
[event, response(cmds)]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,19 +153,6 @@ def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.DeviceSpecifi
|
|||||||
updateDataValue("serialNumber", serialNumber)
|
updateDataValue("serialNumber", serialNumber)
|
||||||
log.debug "${device.displayName} - serial number: ${serialNumber}"
|
log.debug "${device.displayName} - serial number: ${serialNumber}"
|
||||||
}
|
}
|
||||||
|
|
||||||
def response_cmds = []
|
|
||||||
if (!device.currentState("temperature")) {
|
|
||||||
response_cmds << encap(zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 1, scale: 0))
|
|
||||||
}
|
|
||||||
if (!getDataValue("version") && !zwaveInfo.ver) {
|
|
||||||
log.debug "Requesting Version Report"
|
|
||||||
response_cmds << "delay 500"
|
|
||||||
response_cmds << encap(zwave.versionV1.versionGet())
|
|
||||||
}
|
|
||||||
response_cmds << "delay 1000"
|
|
||||||
response_cmds << encap(zwave.wakeUpV2.wakeUpNoMoreInformation())
|
|
||||||
[[:], response(response_cmds)]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def zwaveEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd) {
|
def zwaveEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd) {
|
||||||
@@ -178,20 +165,12 @@ def zwaveEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
|
def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
|
||||||
def result = []
|
|
||||||
def map = [:]
|
def map = [:]
|
||||||
map.name = "battery"
|
map.name = "battery"
|
||||||
map.value = cmd.batteryLevel == 255 ? 1 : cmd.batteryLevel.toString()
|
map.value = cmd.batteryLevel == 255 ? 1 : cmd.batteryLevel.toString()
|
||||||
map.unit = "%"
|
map.unit = "%"
|
||||||
|
map.displayed = true
|
||||||
result << createEvent(map)
|
createEvent(map)
|
||||||
|
|
||||||
if (!getDataValue("serialNumber")) {
|
|
||||||
result << response(encap(zwave.manufacturerSpecificV2.deviceSpecificGet()))
|
|
||||||
} else {
|
|
||||||
result << response(encap(zwave.wakeUpV2.wakeUpNoMoreInformation()))
|
|
||||||
}
|
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cmd) {
|
def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cmd) {
|
||||||
@@ -249,18 +228,19 @@ def zwaveEvent(physicalgraph.zwave.commands.deviceresetlocallyv1.DeviceResetLoca
|
|||||||
|
|
||||||
def configure() {
|
def configure() {
|
||||||
log.debug "Executing 'configure'"
|
log.debug "Executing 'configure'"
|
||||||
// Device wakes up every 4 hours, this interval of 8h 2m allows us to miss one wakeup notification before marking offline
|
|
||||||
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
|
||||||
|
|
||||||
// default initial state
|
|
||||||
sendEvent(name: "water", value: "dry")
|
|
||||||
|
|
||||||
def cmds = []
|
def cmds = []
|
||||||
|
|
||||||
cmds << zwave.associationV2.associationSet(groupingIdentifier:1, nodeId: [zwaveHubNodeId])
|
cmds += zwave.wakeUpV2.wakeUpIntervalSet(seconds:21600, nodeid: zwaveHubNodeId)//FGFS' default wake up interval
|
||||||
cmds << zwave.batteryV1.batteryGet() // other queries sent as response to BatteryReport
|
cmds += zwave.manufacturerSpecificV2.manufacturerSpecificGet()
|
||||||
|
cmds += zwave.manufacturerSpecificV2.deviceSpecificGet()
|
||||||
|
cmds += zwave.versionV1.versionGet()
|
||||||
|
cmds += zwave.batteryV1.batteryGet()
|
||||||
|
cmds += zwave.sensorMultilevelV5.sensorMultilevelGet(sensorType: 1, scale: 0)
|
||||||
|
cmds += zwave.associationV2.associationSet(groupingIdentifier:1, nodeId: [zwaveHubNodeId])
|
||||||
|
cmds += zwave.wakeUpV2.wakeUpNoMoreInformation()
|
||||||
|
|
||||||
encapSequence(cmds, 200)
|
encapSequence(cmds, 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
private secure(physicalgraph.zwave.Command cmd) {
|
private secure(physicalgraph.zwave.Command cmd) {
|
||||||
@@ -277,10 +257,13 @@ private encapSequence(commands, delay=200) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private encap(physicalgraph.zwave.Command cmd) {
|
private encap(physicalgraph.zwave.Command cmd) {
|
||||||
if (zwaveInfo.zw && !zwaveInfo.zw.contains("s")) {
|
def secureClasses = [0x20, 0x5A, 0x70, 0x71, 0x84, 0x85, 0x8E, 0x9C]
|
||||||
// Secure inclusion failed
|
|
||||||
crc16(cmd)
|
//todo: check if secure inclusion was successful
|
||||||
} else {
|
//if not do not send security-encapsulated command
|
||||||
|
if (secureClasses.find{ it == cmd.commandClassId }) {
|
||||||
secure(cmd)
|
secure(cmd)
|
||||||
|
} else {
|
||||||
|
crc16(cmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,6 @@ metadata {
|
|||||||
capability "Sensor"
|
capability "Sensor"
|
||||||
capability "Tamper Alert"
|
capability "Tamper Alert"
|
||||||
capability "Temperature Measurement"
|
capability "Temperature Measurement"
|
||||||
capability "Health Check"
|
|
||||||
|
|
||||||
fingerprint deviceId: "0x0701", inClusters: "0x5E, 0x20, 0x86, 0x72, 0x5A, 0x59, 0x85, 0x73, 0x84, 0x80, 0x71, 0x56, 0x70, 0x31, 0x8E, 0x22, 0x30, 0x9C, 0x98, 0x7A", outClusters: ""
|
fingerprint deviceId: "0x0701", inClusters: "0x5E, 0x20, 0x86, 0x72, 0x5A, 0x59, 0x85, 0x73, 0x84, 0x80, 0x71, 0x56, 0x70, 0x31, 0x8E, 0x22, 0x30, 0x9C, 0x98, 0x7A", outClusters: ""
|
||||||
}
|
}
|
||||||
@@ -241,8 +240,6 @@ def zwaveEvent(physicalgraph.zwave.commands.deviceresetlocallyv1.DeviceResetLoca
|
|||||||
|
|
||||||
def configure() {
|
def configure() {
|
||||||
log.debug "Executing 'configure'"
|
log.debug "Executing 'configure'"
|
||||||
// Device-Watch simply pings if no device events received for 8 hrs & 2 minutes
|
|
||||||
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
|
||||||
|
|
||||||
def cmds = []
|
def cmds = []
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ metadata {
|
|||||||
capability "Temperature Measurement"
|
capability "Temperature Measurement"
|
||||||
capability "Configuration"
|
capability "Configuration"
|
||||||
capability "Battery"
|
capability "Battery"
|
||||||
capability "Health Check"
|
|
||||||
|
|
||||||
command "resetParams2StDefaults"
|
command "resetParams2StDefaults"
|
||||||
command "listCurrentParams"
|
command "listCurrentParams"
|
||||||
@@ -47,9 +46,6 @@ metadata {
|
|||||||
command "test"
|
command "test"
|
||||||
|
|
||||||
fingerprint deviceId: "0xA102", inClusters: "0x30,0x9C,0x60,0x85,0x8E,0x72,0x70,0x86,0x80,0x84"
|
fingerprint deviceId: "0xA102", inClusters: "0x30,0x9C,0x60,0x85,0x8E,0x72,0x70,0x86,0x80,0x84"
|
||||||
fingerprint mfr:"010F", prod:"0000", model:"2002"
|
|
||||||
fingerprint mfr:"010F", prod:"0000", model:"1002"
|
|
||||||
fingerprint mfr:"010F", prod:"0B00", model:"1001"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
simulator {
|
simulator {
|
||||||
@@ -111,11 +107,20 @@ def parse(String description)
|
|||||||
{
|
{
|
||||||
def result = []
|
def result = []
|
||||||
|
|
||||||
|
if (description == "updated") {
|
||||||
|
if (!state.MSR) {
|
||||||
|
result << response(zwave.wakeUpV1.wakeUpIntervalSet(seconds: 60*60, nodeid:zwaveHubNodeId))
|
||||||
|
result << response(zwave.manufacturerSpecificV2.manufacturerSpecificGet())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
def cmd = zwave.parse(description, [0x31: 2, 0x30: 1, 0x70: 2, 0x71: 1, 0x84: 1, 0x80: 1, 0x9C: 1, 0x72: 2, 0x56: 2, 0x60: 3])
|
def cmd = zwave.parse(description, [0x31: 2, 0x30: 1, 0x70: 2, 0x71: 1, 0x84: 1, 0x80: 1, 0x9C: 1, 0x72: 2, 0x56: 2, 0x60: 3])
|
||||||
|
|
||||||
if (cmd) {
|
if (cmd) {
|
||||||
result += zwaveEvent(cmd) //createEvent(zwaveEvent(cmd))
|
result += zwaveEvent(cmd) //createEvent(zwaveEvent(cmd))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result << response(zwave.batteryV1.batteryGet().format())
|
||||||
|
|
||||||
if ( result[0] != null ) {
|
if ( result[0] != null ) {
|
||||||
log.debug "Parse returned ${result}"
|
log.debug "Parse returned ${result}"
|
||||||
@@ -137,9 +142,10 @@ def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd) {
|
|||||||
def result = [createEvent(descriptionText: "${device.displayName} woke up", isStateChange: false)]
|
def result = [createEvent(descriptionText: "${device.displayName} woke up", isStateChange: false)]
|
||||||
if (!isConfigured()) {
|
if (!isConfigured()) {
|
||||||
// we're still in the process of configuring a newly joined device
|
// we're still in the process of configuring a newly joined device
|
||||||
result << lateConfigure(true)
|
result += lateConfigure(true)
|
||||||
} else {
|
} else {
|
||||||
result << response(zwave.wakeUpV1.wakeUpNoMoreInformation())
|
result += response(zwave.wakeUpV1.wakeUpNoMoreInformation())
|
||||||
|
log.debug "We're done with WakeUp!"
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
@@ -298,12 +304,6 @@ def lateConfigure(setConf = False) {
|
|||||||
*/
|
*/
|
||||||
def configure() {
|
def configure() {
|
||||||
log.debug "Configuring Device..."
|
log.debug "Configuring Device..."
|
||||||
// Device wakes up every 4 hours, this interval allows us to miss one wakeup notification before marking offline
|
|
||||||
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
|
||||||
|
|
||||||
// default initial state
|
|
||||||
sendEvent(name: "water", value: "dry")
|
|
||||||
|
|
||||||
def cmds = []
|
def cmds = []
|
||||||
|
|
||||||
// send associate to group 2 to get alarm data
|
// send associate to group 2 to get alarm data
|
||||||
@@ -314,15 +314,13 @@ def configure() {
|
|||||||
// send associate to group 3 to get sensor data reported only to hub
|
// send associate to group 3 to get sensor data reported only to hub
|
||||||
cmds << zwave.associationV2.associationSet(groupingIdentifier:3, nodeId:[zwaveHubNodeId]).format()
|
cmds << zwave.associationV2.associationSet(groupingIdentifier:3, nodeId:[zwaveHubNodeId]).format()
|
||||||
|
|
||||||
// reporting frequency of temps and battery set to one hour
|
|
||||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,60*60], parameterNumber: 10, size: 2).format()
|
|
||||||
// cmds << zwave.configurationV1.configurationGet(parameterNumber: 10).format()
|
|
||||||
|
|
||||||
// temp hysteresis set to .5 degrees celcius
|
// temp hysteresis set to .5 degrees celcius
|
||||||
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,50], parameterNumber: 12, size: 2).format()
|
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,50], parameterNumber: 12, size: 2).format()
|
||||||
// cmds << zwave.configurationV1.configurationGet(parameterNumber: 12).format()
|
cmds << zwave.configurationV1.configurationGet(parameterNumber: 12).format()
|
||||||
|
|
||||||
cmds << zwave.batteryV1.batteryGet().format()
|
// reporting frequency of temps and battery set to one hour
|
||||||
|
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,60*60], parameterNumber: 10, size: 2).format()
|
||||||
|
cmds << zwave.configurationV1.configurationGet(parameterNumber: 10).format()
|
||||||
|
|
||||||
cmds << zwave.wakeUpV1.wakeUpNoMoreInformation().format()
|
cmds << zwave.wakeUpV1.wakeUpNoMoreInformation().format()
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,6 @@
|
|||||||
capability "Illuminance Measurement"
|
capability "Illuminance Measurement"
|
||||||
capability "Sensor"
|
capability "Sensor"
|
||||||
capability "Battery"
|
capability "Battery"
|
||||||
capability "Health Check"
|
|
||||||
|
|
||||||
command "resetParams2StDefaults"
|
command "resetParams2StDefaults"
|
||||||
command "listCurrentParams"
|
command "listCurrentParams"
|
||||||
@@ -126,9 +125,6 @@
|
|||||||
*/
|
*/
|
||||||
def configure() {
|
def configure() {
|
||||||
log.debug "Configuring Device For SmartThings Use"
|
log.debug "Configuring Device For SmartThings Use"
|
||||||
// Device-Watch simply pings if no device events received for 8 hrs & 2 minutes
|
|
||||||
sendEvent(name: "checkInterval", value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
|
|
||||||
|
|
||||||
def cmds = []
|
def cmds = []
|
||||||
|
|
||||||
// send associate to group 3 to get sensor data reported only to hub
|
// send associate to group 3 to get sensor data reported only to hub
|
||||||
|
|||||||
@@ -1,169 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2016 SmartThings
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at:
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
|
||||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
|
|
||||||
* for the specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
import groovy.transform.Field
|
|
||||||
|
|
||||||
@Field Boolean hasConfiguredHealthCheck = false
|
|
||||||
|
|
||||||
metadata {
|
|
||||||
definition (name: "ZLL White Color Temperature Bulb 5000K", namespace: "smartthings", author: "SmartThings") {
|
|
||||||
|
|
||||||
capability "Actuator"
|
|
||||||
capability "Color Temperature"
|
|
||||||
capability "Configuration"
|
|
||||||
capability "Polling"
|
|
||||||
capability "Refresh"
|
|
||||||
capability "Switch"
|
|
||||||
capability "Switch Level"
|
|
||||||
capability "Health Check"
|
|
||||||
|
|
||||||
attribute "colorName", "string"
|
|
||||||
command "setGenericName"
|
|
||||||
|
|
||||||
fingerprint profileId: "C05E", deviceId: "0220", inClusters: "0000, 0004, 0003, 0006, 0008, 0005, 0300", outClusters: "0019", manufacturer: "Eaton", model: "Halo_LT01", deviceJoinName: "Halo RL56 Wireless"
|
|
||||||
}
|
|
||||||
|
|
||||||
// UI tile definitions
|
|
||||||
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 ("colorName", key: "SECONDARY_CONTROL") {
|
|
||||||
attributeState "colorName", label:'${currentValue}'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
|
||||||
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
|
|
||||||
}
|
|
||||||
|
|
||||||
controlTile("colorTempSliderControl", "device.colorTemperature", "slider", width: 4, height: 2, inactiveLabel: false, range:"(2700..5000)") {
|
|
||||||
state "colorTemperature", action:"color temperature.setColorTemperature"
|
|
||||||
}
|
|
||||||
valueTile("colorTemp", "device.colorTemperature", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
|
||||||
state "colorTemperature", label: '${currentValue} K'
|
|
||||||
}
|
|
||||||
|
|
||||||
main(["switch"])
|
|
||||||
details(["switch", "colorTempSliderControl", "colorTemp", "refresh"])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse incoming device messages to generate events
|
|
||||||
def parse(String description) {
|
|
||||||
log.debug "description is $description"
|
|
||||||
def event = zigbee.getEvent(description)
|
|
||||||
if (event) {
|
|
||||||
if (event.name == "colorTemperature") {
|
|
||||||
event.unit = "K"
|
|
||||||
}
|
|
||||||
sendEvent(event)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
log.warn "DID NOT PARSE MESSAGE for description : $description"
|
|
||||||
log.debug zigbee.parseDescriptionAsMap(description)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def off() {
|
|
||||||
zigbee.off() + ["delay 1500"] + zigbee.onOffRefresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
def on() {
|
|
||||||
zigbee.on() + ["delay 1500"] + zigbee.onOffRefresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
def setLevel(value) {
|
|
||||||
zigbee.setLevel(value) + zigbee.onOffRefresh() + zigbee.levelRefresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
def refresh() {
|
|
||||||
def cmds = zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh()
|
|
||||||
|
|
||||||
// Do NOT config if the device is the Eaton Halo_LT01, it responds with "switch:off" to onOffConfig, and maybe other weird things with the others
|
|
||||||
if (!((device.getDataValue("manufacturer") == "Eaton") && (device.getDataValue("model") == "Halo_LT01"))) {
|
|
||||||
cmds = cmds + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig()
|
|
||||||
}
|
|
||||||
|
|
||||||
cmds
|
|
||||||
}
|
|
||||||
|
|
||||||
def poll() {
|
|
||||||
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PING is used by Device-Watch in attempt to reach the Device
|
|
||||||
* */
|
|
||||||
def ping() {
|
|
||||||
return zigbee.levelRefresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
def healthPoll() {
|
|
||||||
log.debug "healthPoll()"
|
|
||||||
def cmds = zigbee.onOffRefresh() + zigbee.levelRefresh()
|
|
||||||
cmds.each{ sendHubCommand(new physicalgraph.device.HubAction(it))}
|
|
||||||
}
|
|
||||||
|
|
||||||
def configureHealthCheck() {
|
|
||||||
Integer hcIntervalMinutes = 12
|
|
||||||
if (!hasConfiguredHealthCheck) {
|
|
||||||
log.debug "Configuring Health Check, Reporting"
|
|
||||||
unschedule("healthPoll")
|
|
||||||
runEvery5Minutes("healthPoll")
|
|
||||||
// Device-Watch allows 2 check-in misses from device
|
|
||||||
sendEvent(name: "checkInterval", value: hcIntervalMinutes * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
|
|
||||||
hasConfiguredHealthCheck = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def configure() {
|
|
||||||
log.debug "configure()"
|
|
||||||
configureHealthCheck()
|
|
||||||
// Implementation note: for the Eaton Halo_LT01, it responds with "switch:off" to onOffConfig, so be sure this is before the call to onOffRefresh
|
|
||||||
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
def updated() {
|
|
||||||
log.debug "updated()"
|
|
||||||
configureHealthCheck()
|
|
||||||
}
|
|
||||||
|
|
||||||
def setColorTemperature(value) {
|
|
||||||
setGenericName(value)
|
|
||||||
zigbee.setColorTemperature(value) + ["delay 1500"] + zigbee.colorTemperatureRefresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
//Naming based on the wiki article here: http://en.wikipedia.org/wiki/Color_temperature
|
|
||||||
def setGenericName(value){
|
|
||||||
if (value != null) {
|
|
||||||
def genericName = ""
|
|
||||||
if (value < 3300) {
|
|
||||||
genericName = "Soft White"
|
|
||||||
} else if (value < 4150) {
|
|
||||||
genericName = "Moonlight"
|
|
||||||
} else if (value <= 5000) {
|
|
||||||
genericName = "Cool White"
|
|
||||||
} else {
|
|
||||||
genericName = "Daylight"
|
|
||||||
}
|
|
||||||
sendEvent(name: "colorName", value: genericName, displayed: false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,794 +0,0 @@
|
|||||||
/**
|
|
||||||
* Gideon
|
|
||||||
*
|
|
||||||
* Copyright 2016 Nicola Russo
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at:
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
|
||||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
|
|
||||||
* for the specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
definition(
|
|
||||||
name: "Gideon Smart Home",
|
|
||||||
namespace: "gideon.api",
|
|
||||||
author: "Braindrain Solutions ltd",
|
|
||||||
description: "Gideon Smart Home SmartApp allows you to connect and control all of your SmartThings devices through the Gideon app, making your SmartThings devices even smarter.",
|
|
||||||
category: "Family",
|
|
||||||
iconUrl: "http://s33.postimg.org/t77u7y7v3/logo.png",
|
|
||||||
iconX2Url: "http://s33.postimg.org/t77u7y7v3/logo.png",
|
|
||||||
iconX3Url: "http://s33.postimg.org/t77u7y7v3/logo.png",
|
|
||||||
oauth: [displayName: "Gideon Smart Home API app", displayLink: "gideon.ai"])
|
|
||||||
|
|
||||||
preferences {
|
|
||||||
section("Control these contact sensors...") {
|
|
||||||
input "contact", "capability.contactSensor", multiple:true, required:false
|
|
||||||
}
|
|
||||||
section("Control these switch levels...") {
|
|
||||||
input "switchlevels", "capability.switchLevel", multiple:true, required:false
|
|
||||||
}
|
|
||||||
/* section("Control these thermostats...") {
|
|
||||||
input "thermostats", "capability.thermostat", multiple:true, required:false
|
|
||||||
}*/
|
|
||||||
section("Control the color for these devices...") {
|
|
||||||
input "colors", "capability.colorControl", multiple:true, required:false
|
|
||||||
}
|
|
||||||
section("Control the color temperature for these devices...") {
|
|
||||||
input "kelvin", "capability.colorTemperature", multiple:true, required:false
|
|
||||||
}
|
|
||||||
section("Control these switches...") {
|
|
||||||
input "switches", "capability.switch", multiple:true, required:false
|
|
||||||
}
|
|
||||||
section("Control these smoke alarms...") {
|
|
||||||
input "smoke_alarms", "capability.smokeDetector", multiple:true, required:false
|
|
||||||
}
|
|
||||||
section("Control these window shades...") {
|
|
||||||
input "shades", "capability.windowShade", multiple:true, required:false
|
|
||||||
}
|
|
||||||
section("Control these garage doors...") {
|
|
||||||
input "garage", "capability.garageDoorControl", multiple:true, required:false
|
|
||||||
}
|
|
||||||
section("Control these water sensors...") {
|
|
||||||
input "water_sensors", "capability.waterSensor", multiple:true, required:false
|
|
||||||
}
|
|
||||||
section("Control these motion sensors...") {
|
|
||||||
input "motions", "capability.motionSensor", multiple:true, required:false
|
|
||||||
}
|
|
||||||
section("Control these presence sensors...") {
|
|
||||||
input "presence_sensors", "capability.presenceSensor", multiple:true, required:false
|
|
||||||
}
|
|
||||||
section("Control these outlets...") {
|
|
||||||
input "outlets", "capability.outlet", multiple:true, required:false
|
|
||||||
}
|
|
||||||
section("Control these power meters...") {
|
|
||||||
input "meters", "capability.powerMeter", multiple:true, required:false
|
|
||||||
}
|
|
||||||
section("Control these locks...") {
|
|
||||||
input "locks", "capability.lock", multiple:true, required:false
|
|
||||||
}
|
|
||||||
section("Control these temperature sensors...") {
|
|
||||||
input "temperature_sensors", "capability.temperatureMeasurement", multiple:true, required:false
|
|
||||||
}
|
|
||||||
section("Control these batteries...") {
|
|
||||||
input "batteries", "capability.battery", multiple:true, required:false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def installed() {
|
|
||||||
log.debug "Installed with settings: ${settings}"
|
|
||||||
|
|
||||||
initialize()
|
|
||||||
}
|
|
||||||
|
|
||||||
def updated() {
|
|
||||||
log.debug "Updated with settings: ${settings}"
|
|
||||||
|
|
||||||
unsubscribe()
|
|
||||||
initialize()
|
|
||||||
}
|
|
||||||
|
|
||||||
def initialize() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private device(it, type) {
|
|
||||||
it ? [id: it.id, label: it.label, type: type] : null
|
|
||||||
}
|
|
||||||
|
|
||||||
//API Mapping
|
|
||||||
mappings {
|
|
||||||
path("/getalldevices") {
|
|
||||||
action: [
|
|
||||||
GET: "getAllDevices"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
path("/thermostat/setcool/:id/:temp") {
|
|
||||||
action: [
|
|
||||||
GET: "setCoolTemp"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/thermostat/setheat/:id/:temp") {
|
|
||||||
action: [
|
|
||||||
GET: "setHeatTemp"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/thermostat/setfanmode/:id/:mode") {
|
|
||||||
action: [
|
|
||||||
GET: "setFanMode"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/thermostat/setmode/:id/:mode") {
|
|
||||||
action: [
|
|
||||||
GET: "setThermostatMode"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/thermostat/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "getThermostatStatus"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
path("/light/dim/:id/:dim") {
|
|
||||||
action: [
|
|
||||||
GET: "setLevelStatus"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/light/kelvin/:id/:kelvin") {
|
|
||||||
action: [
|
|
||||||
GET: "setKelvin"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/colorlight/:id/:hue/:sat") {
|
|
||||||
action: [
|
|
||||||
GET: "setColor"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/light/status/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "getLightStatus"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/light/on/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "turnOnLight"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/light/off/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "turnOffLight"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/doorlocks/lock/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "lockDoorLock"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/doorlocks/unlock/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "unlockDoorLock"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/doorlocks/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "getDoorLockStatus"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/contacts/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "getContactStatus"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/smoke/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "getSmokeStatus"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/shades/open/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "openShade"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/shades/preset/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "presetShade"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/shades/close/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "closeShade"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/shades/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "getShadeStatus"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/garage/open/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "openGarage"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/garage/close/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "closeGarage"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/garage/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "getGarageStatus"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/watersensors/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "getWaterSensorStatus"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/tempsensors/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "getTempSensorsStatus"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/meters/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "getMeterStatus"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/batteries/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "getBatteryStatus"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/presences/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "getPresenceStatus"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/motions/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "getMotionStatus"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/outlets/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "getOutletStatus"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/outlets/turnon/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "turnOnOutlet"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/outlets/turnoff/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "turnOffOutlet"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/switches/turnon/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "turnOnSwitch"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/switches/turnoff/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "turnOffSwitch"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
path("/switches/:id") {
|
|
||||||
action: [
|
|
||||||
GET: "getSwitchStatus"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//API Methods
|
|
||||||
def getAllDevices() {
|
|
||||||
def locks_list = locks.collect{device(it,"Lock")}
|
|
||||||
/*def thermo_list = thermostats.collect{device(it,"Thermostat")}*/
|
|
||||||
def colors_list = colors.collect{device(it,"Color")}
|
|
||||||
def kelvin_list = kelvin.collect{device(it,"Kelvin")}
|
|
||||||
def contact_list = contact.collect{device(it,"Contact Sensor")}
|
|
||||||
def smokes_list = smoke_alarms.collect{device(it,"Smoke Alarm")}
|
|
||||||
def shades_list = shades.collect{device(it,"Window Shade")}
|
|
||||||
def garage_list = garage.collect{device(it,"Garage Door")}
|
|
||||||
def water_sensors_list = water_sensors.collect{device(it,"Water Sensor")}
|
|
||||||
def presences_list = presence_sensors.collect{device(it,"Presence")}
|
|
||||||
def motions_list = motions.collect{device(it,"Motion")}
|
|
||||||
def outlets_list = outlets.collect{device(it,"Outlet")}
|
|
||||||
def switches_list = switches.collect{device(it,"Switch")}
|
|
||||||
def switchlevels_list = switchlevels.collect{device(it,"Switch Level")}
|
|
||||||
def temp_list = temperature_sensors.collect{device(it,"Temperature")}
|
|
||||||
def meters_list = meters.collect{device(it,"Power Meters")}
|
|
||||||
def battery_list = batteries.collect{device(it,"Batteries")}
|
|
||||||
return outlets_list + kelvin_list + colors_list + switchlevels_list + smokes_list + contact_list + water_sensors_list + shades_list + garage_list + locks_list + presences_list + motions_list + switches_list + temp_list + meters_list + battery_list
|
|
||||||
}
|
|
||||||
|
|
||||||
//thermostat
|
|
||||||
/*
|
|
||||||
def setCoolTemp() {
|
|
||||||
def device = thermostats.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
if(device.hasCommand("setCoolingSetpoint")) {
|
|
||||||
device.setCoolingSetpoint(params.temp.toInteger());
|
|
||||||
return [result_action: "200"]
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
httpError(510, "Not supported!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
def setHeatTemp() {
|
|
||||||
def device = thermostats.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
if(device.hasCommand("setHeatingSetpoint")) {
|
|
||||||
device.setHeatingSetpoint(params.temp.toInteger());
|
|
||||||
return [result_action: "200"]
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
httpError(510, "Not supported!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
def setFanMode() {
|
|
||||||
def device = thermostats.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
if(device.hasCommand("setThermostatFanMode")) {
|
|
||||||
device.setThermostatFanMode(params.mode);
|
|
||||||
return [result_action: "200"]
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
httpError(510, "Not supported!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
def setThermostatMode() {
|
|
||||||
def device = thermostats.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
if(device.hasCommand("setThermostatMode")) {
|
|
||||||
device.setThermostatMode(params.mode);
|
|
||||||
return [result_action: "200"]
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
httpError(510, "Not supported!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
def getThermostatStatus() {
|
|
||||||
def device = thermostats.find{ it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
return [ThermostatOperatingState: device.currentValue('thermostatOperatingState'), ThermostatSetpoint: device.currentValue('thermostatSetpoint'),
|
|
||||||
ThermostatFanMode: device.currentValue('thermostatFanMode'), ThermostatMode: device.currentValue('thermostatMode')]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
//light
|
|
||||||
def turnOnLight() {
|
|
||||||
def device = switches.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
device.on();
|
|
||||||
|
|
||||||
return [Device_id: params.id, result_action: "200"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def turnOffLight() {
|
|
||||||
def device = switches.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
device.off();
|
|
||||||
|
|
||||||
return [Device_id: params.id, result_action: "200"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def getLightStatus() {
|
|
||||||
def device = switches.find{ it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
return [Status: device.currentValue('switch'), Dim: getLevelStatus(params.id), Color: getColorStatus(params.id), Kelvin: getKelvinStatus(params.id)]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//color control
|
|
||||||
def setColor() {
|
|
||||||
def device = colors.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
|
|
||||||
def map = [hue:params.hue.toInteger(), saturation:params.sat.toInteger()]
|
|
||||||
|
|
||||||
device.setColor(map);
|
|
||||||
|
|
||||||
return [Device_id: params.id, result_action: "200"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def getColorStatus(id) {
|
|
||||||
def device = colors.find { it.id == id }
|
|
||||||
if (!device) {
|
|
||||||
return [Color: "none"]
|
|
||||||
} else {
|
|
||||||
return [hue: device.currentValue('hue'), saturation: device.currentValue('saturation')]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//kelvin control
|
|
||||||
def setKelvin() {
|
|
||||||
def device = kelvin.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
|
|
||||||
device.setColorTemperature(params.kelvin.toInteger());
|
|
||||||
|
|
||||||
return [Device_id: params.id, result_action: "200"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def getKelvinStatus(id) {
|
|
||||||
def device = kelvin.find { it.id == id }
|
|
||||||
if (!device) {
|
|
||||||
return [kelvin: "none"]
|
|
||||||
} else {
|
|
||||||
return [kelvin: device.currentValue('colorTemperature')]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//switch level
|
|
||||||
def getLevelStatus() {
|
|
||||||
def device = switchlevels.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
[Level: "No dimmer"]
|
|
||||||
} else {
|
|
||||||
return [Level: device.currentValue('level')]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def getLevelStatus(id) {
|
|
||||||
def device = switchlevels.find { it.id == id }
|
|
||||||
if (!device) {
|
|
||||||
[Level: "No dimmer"]
|
|
||||||
} else {
|
|
||||||
return [Level: device.currentValue('level')]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def setLevelStatus() {
|
|
||||||
def device = switchlevels.find { it.id == params.id }
|
|
||||||
def level = params.dim
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
device.setLevel(level.toInteger())
|
|
||||||
return [result_action: "200", Level: device.currentValue('level')]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//contact sensors
|
|
||||||
def getContactStatus() {
|
|
||||||
def device = contact.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
def args = getTempSensorsStatus(device.id)
|
|
||||||
return [Device_state: device.currentValue('contact')] + args
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//smoke detectors
|
|
||||||
def getSmokeStatus() {
|
|
||||||
def device = smoke_alarms.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
def bat = getBatteryStatus(device.id)
|
|
||||||
return [Device_state: device.currentValue('smoke')] + bat
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//garage
|
|
||||||
def getGarageStatus() {
|
|
||||||
def device = garage.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
return [Device_state: device.currentValue('door')]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def openGarage() {
|
|
||||||
def device = garage.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
|
|
||||||
device.open();
|
|
||||||
|
|
||||||
return [Device_id: params.id, result_action: "200"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def closeGarage() {
|
|
||||||
def device = garage.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
|
|
||||||
device.close();
|
|
||||||
|
|
||||||
return [Device_id: params.id, result_action: "200"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//shades
|
|
||||||
def getShadeStatus() {
|
|
||||||
def device = shades.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
return [Device_state: device.currentValue('windowShade')]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def openShade() {
|
|
||||||
def device = shades.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
|
|
||||||
device.open();
|
|
||||||
|
|
||||||
return [Device_id: params.id, result_action: "200"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def presetShade() {
|
|
||||||
def device = shades.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
|
|
||||||
device.presetPosition();
|
|
||||||
|
|
||||||
return [Device_id: params.id, result_action: "200"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def closeShade() {
|
|
||||||
def device = shades.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
|
|
||||||
device.close();
|
|
||||||
|
|
||||||
return [Device_id: params.id, result_action: "200"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//water sensor
|
|
||||||
def getWaterSensorStatus() {
|
|
||||||
def device = water_sensors.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
def bat = getBatteryStatus(device.id)
|
|
||||||
return [Device_state: device.currentValue('water')] + bat
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//batteries
|
|
||||||
def getBatteryStatus() {
|
|
||||||
def device = batteries.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
return [Device_state: device.latestValue("battery")]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def getBatteryStatus(id) {
|
|
||||||
def device = batteries.find { it.id == id }
|
|
||||||
if (!device) {
|
|
||||||
return []
|
|
||||||
} else {
|
|
||||||
return [battery_state: device.latestValue("battery")]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//LOCKS
|
|
||||||
def getDoorLockStatus() {
|
|
||||||
def device = locks.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
def bat = getBatteryStatus(device.id)
|
|
||||||
return [Device_state: device.currentValue('lock')] + bat
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def lockDoorLock() {
|
|
||||||
def device = locks.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
|
|
||||||
device.lock();
|
|
||||||
|
|
||||||
return [Device_id: params.id, result_action: "200"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def unlockDoorLock() {
|
|
||||||
def device = locks.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
|
|
||||||
device.unlock();
|
|
||||||
|
|
||||||
return [Device_id: params.id, result_action: "200"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//PRESENCE
|
|
||||||
def getPresenceStatus() {
|
|
||||||
|
|
||||||
def device = presence_sensors.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
def bat = getBatteryStatus(device.id)
|
|
||||||
return [Device_state: device.currentValue('presence')] + bat
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//MOTION
|
|
||||||
def getMotionStatus() {
|
|
||||||
|
|
||||||
def device = motions.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
def args = getTempSensorsStatus(device.id)
|
|
||||||
return [Device_state: device.currentValue('motion')] + args
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//OUTLET
|
|
||||||
def getOutletStatus() {
|
|
||||||
|
|
||||||
def device = outlets.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
device = switches.find { it.id == params.id }
|
|
||||||
if(!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
def watt = getMeterStatus(device.id)
|
|
||||||
|
|
||||||
return [Device_state: device.currentValue('switch')] + watt
|
|
||||||
}
|
|
||||||
|
|
||||||
def getMeterStatus() {
|
|
||||||
|
|
||||||
def device = meters.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
return [Device_id: device.id, Device_type: device.type, Current_watt: device.currentValue("power")]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def getMeterStatus(id) {
|
|
||||||
|
|
||||||
def device = meters.find { it.id == id }
|
|
||||||
if (!device) {
|
|
||||||
return []
|
|
||||||
} else {
|
|
||||||
return [Current_watt: device.currentValue("power")]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def turnOnOutlet() {
|
|
||||||
def device = outlets.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
device = switches.find { it.id == params.id }
|
|
||||||
if(!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
device.on();
|
|
||||||
|
|
||||||
return [Device_id: params.id, result_action: "200"]
|
|
||||||
}
|
|
||||||
|
|
||||||
def turnOffOutlet() {
|
|
||||||
def device = outlets.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
device = switches.find { it.id == params.id }
|
|
||||||
if(!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
device.off();
|
|
||||||
|
|
||||||
return [Device_id: params.id, result_action: "200"]
|
|
||||||
}
|
|
||||||
|
|
||||||
//SWITCH
|
|
||||||
def getSwitchStatus() {
|
|
||||||
def device = switches.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
return [Device_state: device.currentValue('switch'), Dim: getLevelStatus(params.id)]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def turnOnSwitch() {
|
|
||||||
def device = switches.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
|
|
||||||
device.on();
|
|
||||||
|
|
||||||
return [Device_id: params.id, result_action: "200"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def turnOffSwitch() {
|
|
||||||
def device = switches.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
|
|
||||||
device.off();
|
|
||||||
|
|
||||||
return [Device_id: params.id, result_action: "200"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//TEMPERATURE
|
|
||||||
def getTempSensorsStatus() {
|
|
||||||
def device = temperature_sensors.find { it.id == params.id }
|
|
||||||
if (!device) {
|
|
||||||
httpError(404, "Device not found")
|
|
||||||
} else {
|
|
||||||
def bat = getBatteryStatus(device.id)
|
|
||||||
def scale = [Scale: location.temperatureScale]
|
|
||||||
return [Device_state: device.currentValue('temperature')] + scale + bat
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def getTempSensorsStatus(id) {
|
|
||||||
def device = temperature_sensors.find { it.id == id }
|
|
||||||
if (!device) {
|
|
||||||
return []
|
|
||||||
} else {
|
|
||||||
def bat = getBatteryStatus(device.id)
|
|
||||||
return [temperature: device.currentValue('temperature')] + bat
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -81,32 +81,38 @@ def getInputs() {
|
|||||||
//API external Endpoints
|
//API external Endpoints
|
||||||
mappings {
|
mappings {
|
||||||
path("/subscriptionURL/:url") {
|
path("/subscriptionURL/:url") {
|
||||||
action: [
|
action:
|
||||||
|
[
|
||||||
PUT: "updateEndpointURL"
|
PUT: "updateEndpointURL"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
path("/connectionId/:connId") {
|
path("/connectionId/:connId") {
|
||||||
action: [
|
action:
|
||||||
|
[
|
||||||
PUT: "updateConnectionId"
|
PUT: "updateConnectionId"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
path("/devices") {
|
path("/devices") {
|
||||||
action: [
|
action:
|
||||||
|
[
|
||||||
GET: "getDevices"
|
GET: "getDevices"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
path("/devices/:id") {
|
path("/devices/:id") {
|
||||||
action: [
|
action:
|
||||||
|
[
|
||||||
GET: "getDevice"
|
GET: "getDevice"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
path("/update/:id") {
|
path("/update/:id") {
|
||||||
action: [
|
action:
|
||||||
|
[
|
||||||
PUT: "updateDevice"
|
PUT: "updateDevice"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
path("/subscription/:id") {
|
path("/subscription/:id") {
|
||||||
action: [
|
action:
|
||||||
|
[
|
||||||
POST : "registerDeviceChange",
|
POST : "registerDeviceChange",
|
||||||
DELETE: "unregisterDeviceChange"
|
DELETE: "unregisterDeviceChange"
|
||||||
]
|
]
|
||||||
@@ -180,20 +186,16 @@ def eventHandler(evt) {
|
|||||||
def evt_name = evt.name
|
def evt_name = evt.name
|
||||||
def evt_device = evt.device
|
def evt_device = evt.device
|
||||||
def evt_deviceType = getDeviceType(evt_device);
|
def evt_deviceType = getDeviceType(evt_device);
|
||||||
def deviceInfo
|
|
||||||
|
|
||||||
if(evt_deviceType == "thermostat")
|
|
||||||
{
|
|
||||||
deviceInfo = [name: evt_device.displayName, id: evt_device.id, status:evt_device.getStatus(), deviceType:evt_deviceType, manufacturer:evt_device.getManufacturerName(), model:evt_device.getModelName(), attributes: deviceAttributeList(evt_device), locationMode: getLocationModeInfo()]
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
deviceInfo = [name: evt_device.displayName, id: evt_device.id, status:evt_device.getStatus(), deviceType:evt_deviceType, manufacturer:evt_device.getManufacturerName(), model:evt_device.getModelName(), attributes: deviceAttributeList(evt_device)]
|
|
||||||
}
|
|
||||||
|
|
||||||
def params = [
|
def params = [
|
||||||
uri : "${state.endpointURL}/${state.connectionId}",
|
uri : "${state.endpointURL}/${state.connectionId}",
|
||||||
body: [ deviceInfo ]
|
body: [
|
||||||
|
name : evt_device.displayName,
|
||||||
|
id : evt_device.id,
|
||||||
|
deviceType : evt_deviceType,
|
||||||
|
manufacturer: evt_device.getManufacturerName(),
|
||||||
|
model : evt_device.getModelName(),
|
||||||
|
attributes : deviceAttributeList(evt_device)
|
||||||
|
]
|
||||||
]
|
]
|
||||||
try {
|
try {
|
||||||
log.trace "POST URI: ${params.uri}"
|
log.trace "POST URI: ${params.uri}"
|
||||||
@@ -228,13 +230,10 @@ def getDevices() {
|
|||||||
def deviceData = []
|
def deviceData = []
|
||||||
inputs?.each {
|
inputs?.each {
|
||||||
def deviceType = getDeviceType(it)
|
def deviceType = getDeviceType(it)
|
||||||
if(deviceType == "thermostat")
|
if (deviceType == "thermostat") {
|
||||||
{
|
deviceData << [name: it.displayName, id: it.id, deviceType: deviceType, manufacturer: it.getManufacturerName(), model: it.getModelName(), attributes: deviceAttributeList(it), locationMode: getLocationModeInfo()]
|
||||||
deviceData << [name: it.displayName, id: it.id, status:it.getStatus(), deviceType:deviceType, manufacturer:it.getManufacturerName(), model:it.getModelName(), attributes: deviceAttributeList(it), locationMode: getLocationModeInfo()]
|
} else {
|
||||||
}
|
deviceData << [name: it.displayName, id: it.id, deviceType: deviceType, manufacturer: it.getManufacturerName(), model: it.getModelName(), attributes: deviceAttributeList(it)]
|
||||||
else
|
|
||||||
{
|
|
||||||
deviceData << [name: it.displayName, id: it.id, status:it.getStatus(), deviceType:deviceType, manufacturer:it.getManufacturerName(), model:it.getModelName(), attributes: deviceAttributeList(it)]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,13 +246,10 @@ def getDevice() {
|
|||||||
def it = findDevice(params.id)
|
def it = findDevice(params.id)
|
||||||
def deviceType = getDeviceType(it)
|
def deviceType = getDeviceType(it)
|
||||||
def device
|
def device
|
||||||
if(deviceType == "thermostat")
|
if (deviceType == "thermostat") {
|
||||||
{
|
device = [name: it.displayName, id: it.id, deviceType: deviceType, manufacturer: it.getManufacturerName(), model: it.getModelName(), attributes: deviceAttributeList(it), locationMode: getLocationModeInfo()]
|
||||||
device = [name: it.displayName, id: it.id, status:it.getStatus(), deviceType:deviceType, manufacturer:it.getManufacturerName(), model:it.getModelName(), attributes: deviceAttributeList(it), locationMode: getLocationModeInfo()]
|
} else {
|
||||||
}
|
device = [name: it.displayName, id: it.id, deviceType: deviceType, manufacturer: it.getManufacturerName(), model: it.getModelName(), attributes: deviceAttributeList(it)]
|
||||||
else
|
|
||||||
{
|
|
||||||
device = [name: it.displayName, id: it.id, status:it.getStatus(), deviceType:deviceType, manufacturer:it.getManufacturerName(), model:it.getModelName(), attributes: deviceAttributeList(it)]
|
|
||||||
}
|
}
|
||||||
log.debug "getDevice, return: ${device}"
|
log.debug "getDevice, return: ${device}"
|
||||||
return device
|
return device
|
||||||
@@ -326,28 +322,19 @@ private getLocationModeInfo() {
|
|||||||
//Map each device to a type given it's capabilities
|
//Map each device to a type given it's capabilities
|
||||||
private getDeviceType(device) {
|
private getDeviceType(device) {
|
||||||
def deviceType
|
def deviceType
|
||||||
def capabilities = device.capabilities
|
def caps = device.capabilities
|
||||||
log.debug "capabilities: [${device}, ${capabilities}]"
|
log.debug "capabilities: [${device}, ${caps}]"
|
||||||
log.debug "supported commands: [${device}, ${device.supportedCommands}]"
|
log.debug "supported commands: [${device}, ${device.supportedCommands}]"
|
||||||
|
caps.each {
|
||||||
//Loop through the device capability list to determine the device type.
|
switch (it.name.toLowerCase()) {
|
||||||
capabilities.each {capability ->
|
|
||||||
switch(capability.name.toLowerCase())
|
|
||||||
{
|
|
||||||
case "switch":
|
case "switch":
|
||||||
deviceType = "switch"
|
deviceType = "switch"
|
||||||
|
if (caps.any { it.name.toLowerCase() == "power meter" }) {
|
||||||
//If the device also contains "Switch Level" capability, identify it as a "light" device.
|
|
||||||
if (capabilities.any{it.name.toLowerCase() == "switch level"}){
|
|
||||||
|
|
||||||
//If the device also contains "Power Meter" capability, identify it as a "dimmerSwitch" device.
|
|
||||||
if (capabilities.any{it.name.toLowerCase() == "power meter"}){
|
|
||||||
deviceType = "dimmerSwitch"
|
|
||||||
return deviceType
|
|
||||||
} else {
|
|
||||||
deviceType = "light"
|
|
||||||
return deviceType
|
return deviceType
|
||||||
}
|
}
|
||||||
|
if (caps.any { it.name.toLowerCase() == "switch level" }) {
|
||||||
|
deviceType = "light"
|
||||||
|
return deviceType
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case "contact sensor":
|
case "contact sensor":
|
||||||
@@ -427,7 +414,7 @@ private mapDeviceCommands(command, value) {
|
|||||||
resultCommand = "setSaturation"
|
resultCommand = "setSaturation"
|
||||||
resultValue = value
|
resultValue = value
|
||||||
break
|
break
|
||||||
case "colorTemperature":
|
case "ct":
|
||||||
resultCommand = "setColorTemperature"
|
resultCommand = "setColorTemperature"
|
||||||
resultValue = value
|
resultValue = value
|
||||||
break
|
break
|
||||||
@@ -464,8 +451,7 @@ private mapDeviceCommands(command, value) {
|
|||||||
if (value == 1 || value == "1" || value == "lock") {
|
if (value == 1 || value == "1" || value == "lock") {
|
||||||
resultCommand = "lock"
|
resultCommand = "lock"
|
||||||
resultValue = ""
|
resultValue = ""
|
||||||
}
|
} else if (value == 0 || value == "0" || value == "unlock") {
|
||||||
else if (value == 0 || value == "0" || value == "unlock") {
|
|
||||||
resultCommand = "unlock"
|
resultCommand = "unlock"
|
||||||
resultValue = ""
|
resultValue = ""
|
||||||
}
|
}
|
||||||
@@ -476,3 +462,4 @@ private mapDeviceCommands(command, value) {
|
|||||||
|
|
||||||
return [resultCommand, resultValue]
|
return [resultCommand, resultValue]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ preferences {
|
|||||||
input "havdalahOffset", "number", title: "Minutes After Sundown", required:true
|
input "havdalahOffset", "number", title: "Minutes After Sundown", required:true
|
||||||
}
|
}
|
||||||
section("Your ZipCode") {
|
section("Your ZipCode") {
|
||||||
input "zipcode", "text", title: "ZipCode", required:true
|
input "zipcode", "number", title: "ZipCode", required:true
|
||||||
}
|
}
|
||||||
section( "Notifications" ) {
|
section( "Notifications" ) {
|
||||||
input "sendPushMessage", "enum", title: "Send a push notification?", metadata:[values:["Yes","No"]], required:false
|
input "sendPushMessage", "enum", title: "Send a push notification?", metadata:[values:["Yes","No"]], required:false
|
||||||
|
|||||||
82
smartapps/teapps/turn-off.src/turn-off.groovy
Normal file
82
smartapps/teapps/turn-off.src/turn-off.groovy
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/**
|
||||||
|
* Turn Off
|
||||||
|
*
|
||||||
|
* Copyright 2017 Trevor
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||||
|
* in compliance with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||||
|
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing permissions and limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
definition(
|
||||||
|
name: "Turn Off",
|
||||||
|
namespace: "TEAPPS",
|
||||||
|
author: "Trevor",
|
||||||
|
description: "Turn off a light after its been turned on.",
|
||||||
|
category: "Convenience",
|
||||||
|
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
|
||||||
|
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
|
||||||
|
iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png")
|
||||||
|
|
||||||
|
|
||||||
|
preferences {
|
||||||
|
|
||||||
|
section("Lights") {
|
||||||
|
input "lights", "capability.switch", required: true, title: "Which lights to turn off after being turned on?", multiple: true
|
||||||
|
input "offsetHours", "number", title: "How long until the light is turned off (hours)?"
|
||||||
|
input "offsetMinutes", "number", title: "How long until the light is turned off (minutes)?"
|
||||||
|
input "offsetSeconds", "number", title: "How long until the light is turned off (seconds)?"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
def installed() {
|
||||||
|
log.debug "Installed with settings: ${settings}"
|
||||||
|
|
||||||
|
initialize()
|
||||||
|
}
|
||||||
|
|
||||||
|
def updated() {
|
||||||
|
log.debug "Updated with settings: ${settings}"
|
||||||
|
|
||||||
|
unsubscribe()
|
||||||
|
initialize()
|
||||||
|
}
|
||||||
|
|
||||||
|
def initialize() {
|
||||||
|
// TODO: subscribe to attributes, devices, locations, etc.
|
||||||
|
|
||||||
|
//Subscribe to the light device being turned on
|
||||||
|
subscribe(lights, "switch.on", lightHandler)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: implement event handlers
|
||||||
|
def lightHandler(evt) {
|
||||||
|
|
||||||
|
if("on" == evt.value)
|
||||||
|
//Light was turned on
|
||||||
|
log.debug "Light is in ${evt.value} state"
|
||||||
|
|
||||||
|
//Get the date and time
|
||||||
|
def currentTime = new Date()
|
||||||
|
|
||||||
|
//Calculate the offset
|
||||||
|
def timeToTurnOff = new Date(currentTime.time + (offsetHours * 60 * 60 * 1000) + (offsetMinutes * 60 * 1000) + (offsetSeconds * 1000))
|
||||||
|
|
||||||
|
log.debug "Scheduling for: $timeToTurnOff"
|
||||||
|
|
||||||
|
//Schedule this to run one time
|
||||||
|
runOnce(timeToTurnOff, turnOff)
|
||||||
|
}
|
||||||
|
|
||||||
|
def turnOff() {
|
||||||
|
log.debug "turning off lights"
|
||||||
|
lights.off()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user