mirror of
https://github.com/mtan93/SmartThingsPublic.git
synced 2026-03-08 21:02:56 +00:00
Merge branch 'master' into staging
This commit is contained in:
@@ -1,12 +1,9 @@
|
||||
/**
|
||||
* Keen Home Smart Vent
|
||||
*
|
||||
* Author: Keen Home
|
||||
* Date: 2015-06-23
|
||||
*/
|
||||
// keen home smart vent
|
||||
// http://www.keenhome.io
|
||||
// SmartThings Device Handler v1.0.0
|
||||
|
||||
metadata {
|
||||
definition (name: "Keen Home Smart Vent", namespace: "Keen Home", author: "Gregg Altschul") {
|
||||
definition (name: "Keen Home Smart Vent", namespace: "Keen Home", author: "Keen Home") {
|
||||
capability "Switch Level"
|
||||
capability "Switch"
|
||||
capability "Configuration"
|
||||
@@ -21,6 +18,7 @@ metadata {
|
||||
command "getBattery"
|
||||
command "getTemperature"
|
||||
command "setZigBeeIdTile"
|
||||
command "clearObstruction"
|
||||
|
||||
fingerprint endpoint: "1",
|
||||
profileId: "0104",
|
||||
@@ -42,9 +40,10 @@ metadata {
|
||||
// UI tile definitions
|
||||
tiles {
|
||||
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
|
||||
state "on", action:"switch.off", icon:"st.vents.vent-open-text", backgroundColor:"#53a7c0"
|
||||
state "off", action:"switch.on", icon:"st.vents.vent-closed", backgroundColor:"#ffffff"
|
||||
state "obstructed", action: "switch.off", icon:"st.vents.vent-closed", backgroundColor:"#ff0000"
|
||||
state "on", action: "switch.off", icon: "st.vents.vent-open-text", backgroundColor: "#53a7c0"
|
||||
state "off", action: "switch.on", icon: "st.vents.vent-closed", backgroundColor: "#ffffff"
|
||||
state "obstructed", action: "clearObstruction", icon: "st.vents.vent-closed", backgroundColor: "#ff0000"
|
||||
state "clearing", action: "", icon: "st.vents.vent-closed", backgroundColor: "#ffff33"
|
||||
}
|
||||
controlTile("levelSliderControl", "device.level", "slider", height: 1, width: 2, inactiveLabel: false) {
|
||||
state "level", action:"switch level.setLevel"
|
||||
@@ -206,12 +205,12 @@ private Map makeOnOffResult(rawValue) {
|
||||
|
||||
private Map makeLevelResult(rawValue) {
|
||||
def linkText = getLinkText(device)
|
||||
// log.debug "rawValue: ${rawValue}"
|
||||
def value = Integer.parseInt(rawValue, 16)
|
||||
def rangeMax = 254
|
||||
|
||||
// catch obstruction level
|
||||
if (value == 255) {
|
||||
log.debug "obstructed"
|
||||
log.debug "${linkText} is obstructed"
|
||||
// Just return here. Once the vent is power cycled
|
||||
// it will go back to the previous level before obstruction.
|
||||
// Therefore, no need to update level on the display.
|
||||
@@ -220,24 +219,9 @@ private Map makeLevelResult(rawValue) {
|
||||
value: "obstructed",
|
||||
descriptionText: "${linkText} is obstructed. Please power cycle."
|
||||
]
|
||||
} else if ( device.currentValue("switch") == "obstructed" &&
|
||||
value == 254) {
|
||||
// When the device is reset after an obstruction, the switch
|
||||
// state will be obstructed and the value coming from the device
|
||||
// will be 254. Since we're not using heating/cooling mode from
|
||||
// the device type handler, we need to bump it down to the lower
|
||||
// (cooling) range
|
||||
sendEvent(makeOnOffResult(1)) // clear the obstructed switch state
|
||||
value = rangeMax
|
||||
}
|
||||
// else if (device.currentValue("switch") == "off") {
|
||||
// sendEvent(makeOnOffResult(1)) // turn back on if in off state
|
||||
// }
|
||||
|
||||
|
||||
// log.debug "pre-value: ${value}"
|
||||
value = Math.floor(value / rangeMax * 100)
|
||||
// log.debug "post-value: ${value}"
|
||||
|
||||
return [
|
||||
name: "level",
|
||||
@@ -327,35 +311,79 @@ private def makeSerialResult(serial) {
|
||||
value: serial,
|
||||
descriptionText: "${linkText} has serial ${serial}" ]
|
||||
}
|
||||
/**** COMMAND METHODS ****/
|
||||
// def mfgCode() {
|
||||
// ["zcl mfg-code 0x115B", "delay 200"]
|
||||
// }
|
||||
|
||||
// takes a level from 0 to 100 and translates it to a ZigBee move to level with on/off command
|
||||
private def makeLevelCommand(level) {
|
||||
def rangeMax = 254
|
||||
def scaledLevel = Math.round(level * rangeMax / 100)
|
||||
log.debug "scaled level for ${level}%: ${scaledLevel}"
|
||||
|
||||
// convert to hex string and pad to two digits
|
||||
def hexLevel = new BigInteger(scaledLevel.toString()).toString(16).padLeft(2, '0')
|
||||
|
||||
"st cmd 0x${device.deviceNetworkId} 1 8 4 {${hexLevel} 0000}"
|
||||
}
|
||||
|
||||
/**** COMMAND METHODS ****/
|
||||
def on() {
|
||||
log.debug "on()"
|
||||
def linkText = getLinkText(device)
|
||||
log.debug "open ${linkText}"
|
||||
|
||||
// only change the state if the vent is not obstructed
|
||||
if (device.currentValue("switch") == "obstructed") {
|
||||
log.error("cannot open because ${linkText} is obstructed")
|
||||
return
|
||||
}
|
||||
|
||||
sendEvent(makeOnOffResult(1))
|
||||
"st cmd 0x${device.deviceNetworkId} 1 6 1 {}"
|
||||
}
|
||||
|
||||
def off() {
|
||||
log.debug "off()"
|
||||
def linkText = getLinkText(device)
|
||||
log.debug "close ${linkText}"
|
||||
|
||||
// only change the state if the vent is not obstructed
|
||||
if (device.currentValue("switch") == "obstructed") {
|
||||
log.error("cannot close because ${linkText} is obstructed")
|
||||
return
|
||||
}
|
||||
|
||||
sendEvent(makeOnOffResult(0))
|
||||
"st cmd 0x${device.deviceNetworkId} 1 6 0 {}"
|
||||
}
|
||||
|
||||
// does this work?
|
||||
def toggle() {
|
||||
log.debug "toggle()"
|
||||
def clearObstruction() {
|
||||
def linkText = getLinkText(device)
|
||||
log.debug "attempting to clear ${linkText} obstruction"
|
||||
|
||||
"st cmd 0x${device.deviceNetworkId} 1 6 2 {}"
|
||||
sendEvent([
|
||||
name: "switch",
|
||||
value: "clearing",
|
||||
descriptionText: "${linkText} is clearing obstruction"
|
||||
])
|
||||
|
||||
// send a move command to ensure level attribute gets reset for old, buggy firmware
|
||||
// then send a reset to factory defaults
|
||||
// finally re-configure to ensure reports and binding is still properly set after the rtfd
|
||||
[
|
||||
makeLevelCommand(device.currentValue("level")), "delay 500",
|
||||
"st cmd 0x${device.deviceNetworkId} 1 0 0 {}", "delay 5000"
|
||||
] + configure()
|
||||
}
|
||||
|
||||
def setLevel(value) {
|
||||
log.debug "setting level: ${value}"
|
||||
|
||||
def linkText = getLinkText(device)
|
||||
|
||||
// only change the level if the vent is not obstructed
|
||||
def currentState = device.currentValue("switch")
|
||||
|
||||
if (currentState == "obstructed") {
|
||||
log.error("cannot set level because ${linkText} is obstructed")
|
||||
return
|
||||
}
|
||||
|
||||
sendEvent(name: "level", value: value)
|
||||
if (value > 0) {
|
||||
sendEvent(name: "switch", value: "on", descriptionText: "${linkText} is on by setting a level")
|
||||
@@ -363,29 +391,26 @@ def setLevel(value) {
|
||||
else {
|
||||
sendEvent(name: "switch", value: "off", descriptionText: "${linkText} is off by setting level to 0")
|
||||
}
|
||||
def rangeMax = 254
|
||||
def computedLevel = Math.round(value * rangeMax / 100)
|
||||
log.debug "computedLevel: ${computedLevel}"
|
||||
|
||||
def level = new BigInteger(computedLevel.toString()).toString(16)
|
||||
log.debug "level: ${level}"
|
||||
|
||||
if (level.size() < 2){
|
||||
level = '0' + level
|
||||
}
|
||||
|
||||
"st cmd 0x${device.deviceNetworkId} 1 8 4 {${level} 0000}"
|
||||
makeLevelCommand(value)
|
||||
}
|
||||
|
||||
|
||||
def getOnOff() {
|
||||
log.debug "getOnOff()"
|
||||
|
||||
// disallow on/off updates while vent is obstructed
|
||||
if (device.currentValue("switch") == "obstructed") {
|
||||
log.error("cannot update open/close status because ${getLinkText(device)} is obstructed")
|
||||
return []
|
||||
}
|
||||
|
||||
["st rattr 0x${device.deviceNetworkId} 1 0x0006 0"]
|
||||
}
|
||||
|
||||
def getPressure() {
|
||||
log.debug "getPressure()"
|
||||
|
||||
// using a Keen Home specific attribute in the pressure measurement cluster
|
||||
[
|
||||
"zcl mfg-code 0x115B", "delay 200",
|
||||
"zcl global read 0x0403 0x20", "delay 200",
|
||||
@@ -395,12 +420,13 @@ def getPressure() {
|
||||
|
||||
def getLevel() {
|
||||
log.debug "getLevel()"
|
||||
// rattr = read attribute
|
||||
// 0x${} = device net id
|
||||
// 1 = endpoint
|
||||
// 8 = cluster id (level control, in this case)
|
||||
// 0 = attribute within cluster
|
||||
// sendEvent(name: "level", value: value)
|
||||
|
||||
// disallow level updates while vent is obstructed
|
||||
if (device.currentValue("switch") == "obstructed") {
|
||||
log.error("cannot update level status because ${getLinkText(device)} is obstructed")
|
||||
return []
|
||||
}
|
||||
|
||||
["st rattr 0x${device.deviceNetworkId} 1 0x0008 0x0000"]
|
||||
}
|
||||
|
||||
@@ -425,78 +451,59 @@ def setZigBeeIdTile() {
|
||||
name: "zigbeeId",
|
||||
value: device.zigbeeId,
|
||||
descriptionText: "${linkText} has zigbeeId ${device.zigbeeId}" ])
|
||||
return [
|
||||
return [
|
||||
name: "zigbeeId",
|
||||
value: device.zigbeeId,
|
||||
descriptionText: "${linkText} has zigbeeId ${device.zigbeeId}" ]
|
||||
}
|
||||
|
||||
def refresh() {
|
||||
getOnOff() +
|
||||
getOnOff() +
|
||||
getLevel() +
|
||||
getTemperature() +
|
||||
getPressure() +
|
||||
getBattery()
|
||||
}
|
||||
|
||||
private byte[] reverseArray(byte[] array) {
|
||||
int i = 0;
|
||||
int j = array.length - 1;
|
||||
byte tmp;
|
||||
while (j > i) {
|
||||
tmp = array[j];
|
||||
array[j] = array[i];
|
||||
array[i] = tmp;
|
||||
j--;
|
||||
i++;
|
||||
}
|
||||
return array
|
||||
}
|
||||
|
||||
private String swapEndianHex(String hex) {
|
||||
reverseArray(hex.decodeHex()).encodeHex()
|
||||
}
|
||||
|
||||
def configure() {
|
||||
log.debug "CONFIGURE"
|
||||
log.debug "zigbeeId: ${device.hub.zigbeeId}"
|
||||
|
||||
// get ZigBee ID by hidden tile because that's the only way we can do it
|
||||
setZigBeeIdTile()
|
||||
|
||||
def configCmds = [
|
||||
// binding commands
|
||||
// bind reporting clusters to hub
|
||||
"zdo bind 0x${device.deviceNetworkId} 1 1 0x0006 {${device.zigbeeId}} {}", "delay 500",
|
||||
"zdo bind 0x${device.deviceNetworkId} 1 1 0x0008 {${device.zigbeeId}} {}", "delay 500",
|
||||
"zdo bind 0x${device.deviceNetworkId} 1 1 0x0402 {${device.zigbeeId}} {}", "delay 500",
|
||||
"zdo bind 0x${device.deviceNetworkId} 1 1 0x0403 {${device.zigbeeId}} {}", "delay 500",
|
||||
"zdo bind 0x${device.deviceNetworkId} 1 1 0x0001 {${device.zigbeeId}} {}", "delay 500",
|
||||
|
||||
// configure report commands
|
||||
// [cluster] [attr] [type] [min-interval] [max-interval] [min-change]
|
||||
"zdo bind 0x${device.deviceNetworkId} 1 1 0x0001 {${device.zigbeeId}} {}", "delay 500"
|
||||
|
||||
// mike 2015/06/22: preconfigured; see tech spec
|
||||
// configure report commands
|
||||
// zcl global send-me-a-report [cluster] [attr] [type] [min-interval] [max-interval] [min-change]
|
||||
|
||||
// report with these parameters is preconfigured in firmware, can be overridden here
|
||||
// vent on/off state - type: boolean, change: 1
|
||||
// "zcl global send-me-a-report 6 0 0x10 5 60 {01}", "delay 200",
|
||||
// "send 0x${device.deviceNetworkId} 1 1", "delay 1500",
|
||||
|
||||
// mike 2015/06/22: preconfigured; see tech spec
|
||||
// report with these parameters is preconfigured in firmware, can be overridden here
|
||||
// vent level - type: int8u, change: 1
|
||||
// "zcl global send-me-a-report 8 0 0x20 5 60 {01}", "delay 200",
|
||||
// "send 0x${device.deviceNetworkId} 1 1", "delay 1500",
|
||||
|
||||
// mike 2015/06/22: temp and pressure reports are preconfigured, but
|
||||
// we'd like to override their settings for our own purposes
|
||||
// report with these parameters is preconfigured in firmware, can be overridden here
|
||||
// temperature - type: int16s, change: 0xA = 10 = 0.1C
|
||||
"zcl global send-me-a-report 0x0402 0 0x29 10 60 {0A00}", "delay 200",
|
||||
"send 0x${device.deviceNetworkId} 1 1", "delay 1500",
|
||||
// "zcl global send-me-a-report 0x0402 0 0x29 60 60 {0A00}", "delay 200",
|
||||
// "send 0x${device.deviceNetworkId} 1 1", "delay 1500",
|
||||
|
||||
// mike 2015/06/22: use new custom pressure attribute
|
||||
// pressure - type: int32u, change: 1 = 0.1Pa
|
||||
"zcl mfg-code 0x115B", "delay 200",
|
||||
"zcl global send-me-a-report 0x0403 0x20 0x22 10 60 {010000}", "delay 200",
|
||||
"send 0x${device.deviceNetworkId} 1 1", "delay 1500"
|
||||
// report with these parameters is preconfigured in firmware, can be overridden here
|
||||
// keen home custom pressure (tenths of Pascals) - type: int32u, change: 1 = 0.1Pa
|
||||
// "zcl mfg-code 0x115B", "delay 200",
|
||||
// "zcl global send-me-a-report 0x0403 0x20 0x22 60 60 {010000}", "delay 200",
|
||||
// "send 0x${device.deviceNetworkId} 1 1", "delay 1500",
|
||||
|
||||
// mike 2015/06/22: preconfigured; see tech spec
|
||||
// report with these parameters is preconfigured in firmware, can be overridden here
|
||||
// battery - type: int8u, change: 1
|
||||
// "zcl global send-me-a-report 1 0x21 0x20 60 3600 {01}", "delay 200",
|
||||
// "send 0x${device.deviceNetworkId} 1 1", "delay 1500",
|
||||
|
||||
@@ -20,7 +20,8 @@ definition(
|
||||
description: "Use this free SmartApp in conjunction with the ObyThing Music app for your Mac to control and automate music and more with iTunes and SmartThings.",
|
||||
category: "SmartThings Labs",
|
||||
iconUrl: "http://obycode.com/obything/ObyThingSTLogo.png",
|
||||
iconX2Url: "http://obycode.com/obything/ObyThingSTLogo@2x.png")
|
||||
iconX2Url: "http://obycode.com/obything/ObyThingSTLogo@2x.png",
|
||||
singleInstance: true)
|
||||
|
||||
|
||||
preferences {
|
||||
|
||||
@@ -22,7 +22,8 @@ definition(
|
||||
category: "SmartThings Labs",
|
||||
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Partner/netamo-icon-1.png",
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/netamo-icon-1%402x.png",
|
||||
oauth: true
|
||||
oauth: true,
|
||||
singleInstance: true
|
||||
){
|
||||
appSetting "clientId"
|
||||
appSetting "clientSecret"
|
||||
|
||||
@@ -13,7 +13,8 @@ definition(
|
||||
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Partner/jawbone-up.png",
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/jawbone-up@2x.png",
|
||||
oauth: true,
|
||||
usePreferencesForAuthorization: false
|
||||
usePreferencesForAuthorization: false,
|
||||
singleInstance: true
|
||||
) {
|
||||
appSetting "clientId"
|
||||
appSetting "clientSecret"
|
||||
|
||||
@@ -26,7 +26,8 @@ definition(
|
||||
iconUrl: "http://i.imgur.com/HU0ANBp.png",
|
||||
iconX2Url: "http://i.imgur.com/HU0ANBp.png",
|
||||
iconX3Url: "http://i.imgur.com/HU0ANBp.png",
|
||||
oauth: true)
|
||||
oauth: true,
|
||||
singleInstance: true)
|
||||
|
||||
|
||||
preferences {
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
category: "SmartThings Labs",
|
||||
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
|
||||
iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png"
|
||||
iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
|
||||
singleInstance: true
|
||||
)
|
||||
|
||||
preferences {
|
||||
|
||||
@@ -26,7 +26,8 @@ definition(
|
||||
description: "Connect your Ecobee thermostat to SmartThings.",
|
||||
category: "SmartThings Labs",
|
||||
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Partner/ecobee.png",
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/ecobee@2x.png"
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/ecobee@2x.png",
|
||||
singleInstance: true
|
||||
) {
|
||||
appSetting "clientId"
|
||||
appSetting "serverUrl"
|
||||
|
||||
@@ -23,7 +23,8 @@ definition(
|
||||
description: "Connect and take pictures using your Foscam camera from inside the Smartthings app.",
|
||||
category: "SmartThings Internal",
|
||||
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Partner/foscam.png",
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/foscam@2x.png"
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/foscam@2x.png",
|
||||
singleInstance: true
|
||||
)
|
||||
|
||||
preferences {
|
||||
|
||||
@@ -23,7 +23,8 @@ definition(
|
||||
description: "Allows you to connect your Philips Hue lights with SmartThings and control them from your Things area or Dashboard in the SmartThings Mobile app. Adjust colors by going to the Thing detail screen for your Hue lights (tap the gear on Hue tiles).\n\nPlease update your Hue Bridge first, outside of the SmartThings app, using the Philips Hue app.",
|
||||
category: "SmartThings Labs",
|
||||
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Partner/hue.png",
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/hue@2x.png"
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/hue@2x.png",
|
||||
singleInstance: true
|
||||
)
|
||||
|
||||
preferences {
|
||||
|
||||
@@ -22,7 +22,8 @@ definition(
|
||||
category: "SmartThings Labs",
|
||||
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Partner/life360.png",
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/life360@2x.png",
|
||||
oauth: [displayName: "Life360", displayLink: "Life360"]
|
||||
oauth: [displayName: "Life360", displayLink: "Life360"],
|
||||
singleInstance: true
|
||||
) {
|
||||
appSetting "clientId"
|
||||
appSetting "clientSecret"
|
||||
|
||||
@@ -13,7 +13,8 @@ definition(
|
||||
iconUrl: "https://cloud.lifx.com/images/lifx.png",
|
||||
iconX2Url: "https://cloud.lifx.com/images/lifx.png",
|
||||
iconX3Url: "https://cloud.lifx.com/images/lifx.png",
|
||||
oauth: true) {
|
||||
oauth: true,
|
||||
singleInstance: true) {
|
||||
appSetting "clientId"
|
||||
appSetting "clientSecret"
|
||||
}
|
||||
|
||||
@@ -43,7 +43,8 @@ definition(
|
||||
category: "SmartThings Labs",
|
||||
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Partner/harmony.png",
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/harmony%402x.png",
|
||||
oauth: [displayName: "Logitech Harmony", displayLink: "http://www.logitech.com/en-us/harmony-remotes"]
|
||||
oauth: [displayName: "Logitech Harmony", displayLink: "http://www.logitech.com/en-us/harmony-remotes"],
|
||||
singleInstance: true
|
||||
){
|
||||
appSetting "clientId"
|
||||
appSetting "clientSecret"
|
||||
|
||||
@@ -22,7 +22,8 @@ definition(
|
||||
description: "Allows you to control your Samsung TV from the SmartThings app. Perform basic functions like power Off, source, volume, channels and other remote control functions.",
|
||||
category: "SmartThings Labs",
|
||||
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Samsung/samsung-remote%402x.png",
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Samsung/samsung-remote%403x.png"
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Samsung/samsung-remote%403x.png",
|
||||
singleInstance: true
|
||||
)
|
||||
|
||||
preferences {
|
||||
|
||||
@@ -23,7 +23,8 @@ definition(
|
||||
description: "Integrate your Tesla car with SmartThings.",
|
||||
category: "SmartThings Labs",
|
||||
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Partner/tesla-app%402x.png",
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/tesla-app%403x.png"
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/tesla-app%403x.png",
|
||||
singleInstance: true
|
||||
)
|
||||
|
||||
preferences {
|
||||
|
||||
@@ -22,7 +22,8 @@ definition(
|
||||
description: "Allows you to integrate your WeMo Switch and Wemo Motion sensor with SmartThings.",
|
||||
category: "SmartThings Labs",
|
||||
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Partner/wemo.png",
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/wemo@2x.png"
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/wemo@2x.png",
|
||||
singleInstance: true
|
||||
)
|
||||
|
||||
preferences {
|
||||
|
||||
@@ -24,7 +24,8 @@ definition(
|
||||
category: "Connections",
|
||||
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Partner/withings.png",
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/withings%402x.png",
|
||||
oauth: true
|
||||
oauth: true,
|
||||
singleInstance: true
|
||||
) {
|
||||
appSetting "clientId"
|
||||
appSetting "clientSecret"
|
||||
|
||||
@@ -24,7 +24,8 @@ definition(
|
||||
category: "SmartThings Internal",
|
||||
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience%402x.png",
|
||||
oauth: true
|
||||
oauth: true,
|
||||
singleInstance: true
|
||||
) {
|
||||
appSetting "serverUrl"
|
||||
}
|
||||
|
||||
@@ -58,7 +58,8 @@ definition(
|
||||
description: "Connect your Quirky to SmartThings.",
|
||||
category: "SmartThings Labs",
|
||||
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Partner/quirky.png",
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/quirky@2x.png"
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/quirky@2x.png",
|
||||
singleInstance: true
|
||||
) {
|
||||
appSetting "clientId"
|
||||
appSetting "clientSecret"
|
||||
|
||||
@@ -25,7 +25,8 @@ definition(
|
||||
description: "Connect your TCP bulbs to SmartThings using Cloud to Cloud integration. You must create a remote login acct on TCP Mobile App.",
|
||||
category: "SmartThings Labs",
|
||||
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Partner/tcp.png",
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/tcp@2x.png"
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/tcp@2x.png",
|
||||
singleInstance: true
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user