Compare commits

...

27 Commits

Author SHA1 Message Date
OpenT2T
0bcde8a1f0 Modifying 'Publish a SmartApp for OpenT2T - Remove support for multiple subscriptions to a single device.' 2017-06-19 17:28:46 -07:00
OpenT2T
9d63d0bbf9 Modifying 'Publish a SmartApp for OpenT2T - Remove support for multiple subscriptions to a single device.' 2017-06-19 17:25:53 -07:00
OpenT2T
385463772b Modifying 'Publish a SmartApp for OpenT2T - Fix register all device change handler' 2017-05-12 18:23:08 -07:00
OpenT2T
284828c42f Modifying 'Publish a SmartApp for OpenT2T - HMAC support' 2017-05-01 20:10:13 -07:00
OpenT2T
bbdc8faa93 Modifying 'Publish a SmartApp for OpenT2T - Update sensor and subscriptions.' 2017-04-16 19:02:05 -07:00
OpenT2T
48ceadcdb6 Modifying 'Publish a SmartApp for OpenT2T - Update sensor and subscriptions.' 2017-04-16 19:01:30 -07:00
OpenT2T
8e59df0de5 Modifying 'Publish a SmartApp for OpenT2T - Update sensor and subscriptions.' 2017-04-16 19:01:26 -07:00
OpenT2T
d276b80c90 Modifying 'Publish a SmartApp for OpenT2T - Update event messages.' 2017-03-06 01:02:07 -08:00
OpenT2T
8d838ead33 Modifying 'Publish a SmartApp for OpenT2T - Update event messages.' 2017-03-06 01:02:05 -08:00
OpenT2T
bf23f19af5 Modifying 'Update event messages.' 2017-03-06 00:59:48 -08:00
OpenT2T
d5bce43a99 Modifying 'Update event messages.' 2017-03-06 00:59:47 -08:00
OpenT2T
08c6f143dc Modifying 'Support device status.' 2017-03-03 03:11:10 -08:00
OpenT2T
b6f4581d6d Modifying 'Publish a SmartApp for OpenT2T' 2017-03-02 05:20:53 -08:00
OpenT2T
a56cad5e03 Modifying 'Publish a SmartApp for OpenT2T' 2017-03-02 05:20:47 -08:00
OpenT2T
4ed48c8ed4 Modifying 'Publish a SmartApp for OpenT2T' 2017-02-05 19:55:22 -08:00
OpenT2T
0bfd77745e Modifying 'Publish a SmartApp for OpenT2T' 2017-02-05 19:55:17 -08:00
OpenT2T
355f641853 Modifying 'Publish a SmartApp for OpenT2T' 2017-01-09 23:06:17 -08:00
OpenT2T
aba1f48f1f Modifying 'Publish a SmartApp for OpenT2T' 2017-01-09 23:06:16 -08:00
OpenT2T
9bf39136de Modifying 'Publish a SmartApp for OpenT2T' 2017-01-09 22:39:52 -08:00
OpenT2T
97fdc03c00 MSA-1577: This SmartApp enables the end-to-end SmartThings scenarios via OpenT2T. More information on OpenT2T can be found at http://www.opentranslatorstothings.org/#/ 2016-11-14 12:08:30 -08:00
Vinay Rao
8e37b1fce7 Merge pull request #1460 from bbodenmiller/patch-1
Github -> GitHub (Text change, no ticket)
2016-11-13 05:34:47 -08:00
Ben Bodenmiller
439dd634bd Github -> GitHub 2016-11-12 00:19:55 -08:00
Juan Pablo Risso
1db5f75ec5 DVCSMP-2211 - Update Button Number and Holdable capability (#1458) 2016-11-11 16:10:44 -05:00
Juan Pablo Risso
7978f45996 DVCSMP-2221 - Replace display with displayed (#1457) 2016-11-11 14:09:04 -05:00
Vinay Rao
0ab657d5f2 Merge pull request #1456 from SmartThingsCommunity/staging
Rolling down staging hotfix to master
2016-11-11 02:47:42 -08:00
tslagle13
0ae836b023 Merge pull request #1442 from MichaelStruck/MSA-1576-14
MSA-1576: Color Coordinator
2016-11-09 11:18:22 -08:00
Michael Struck
0b4d555d33 MSA-1576: Fixes various bugs and adds a random color feature. 2016-11-09 09:33:31 -08:00
14 changed files with 881 additions and 163 deletions

View File

@@ -1,10 +1,10 @@
# SmartThings Public Github Repo # SmartThings Public GitHub Repo
An official list of SmartApps and Device Types from SmartThings. An official list of SmartApps and Device Types from SmartThings.
Here are some links to help you get started coding right away: Here are some links to help you get started coding right away:
* [Github-specific Documentation](http://docs.smartthings.com/en/latest/tools-and-ide/github-integration.html) * [GitHub-specific Documentation](http://docs.smartthings.com/en/latest/tools-and-ide/github-integration.html)
* [Full Documentation](http://docs.smartthings.com) * [Full Documentation](http://docs.smartthings.com)
* [IDE & Simulator](http://ide.smartthings.com) * [IDE & Simulator](http://ide.smartthings.com)
* [Community Forums](http://community.smartthings.com) * [Community Forums](http://community.smartthings.com)

View File

@@ -15,6 +15,7 @@ metadata {
definition (name: "Aeon Key Fob", namespace: "smartthings", author: "SmartThings") { definition (name: "Aeon Key Fob", namespace: "smartthings", author: "SmartThings") {
capability "Actuator" capability "Actuator"
capability "Button" capability "Button"
capability "Holdable Button"
capability "Configuration" capability "Configuration"
capability "Sensor" capability "Sensor"
capability "Battery" capability "Battery"
@@ -118,3 +119,7 @@ def configure() {
log.debug("Sending configuration: $cmd") log.debug("Sending configuration: $cmd")
return cmd return cmd
} }
def updated() {
sendEvent(name: "numberOfButtons", value: 4)
}

View File

@@ -15,6 +15,7 @@ metadata {
definition (name: "Aeon Minimote", namespace: "smartthings", author: "SmartThings") { definition (name: "Aeon Minimote", namespace: "smartthings", author: "SmartThings") {
capability "Actuator" capability "Actuator"
capability "Button" capability "Button"
capability "Holdable Button"
capability "Configuration" capability "Configuration"
capability "Sensor" capability "Sensor"
@@ -107,3 +108,7 @@ def configure() {
log.debug("Sending configuration: $cmds") log.debug("Sending configuration: $cmds")
return cmds return cmds
} }
def updated() {
sendEvent(name: "numberOfButtons", value: 4)
}

View File

@@ -16,7 +16,7 @@ metadata {
capability "Switch" capability "Switch"
capability "Switch Level" capability "Switch Level"
capability "Button" capability "Button"
capability "Actuator" capability "Actuator"
//fingerprint deviceId: "0x1200", inClusters: "0x77 0x86 0x75 0x73 0x85 0x72 0xEF", outClusters: "0x26" //fingerprint deviceId: "0x1200", inClusters: "0x77 0x86 0x75 0x73 0x85 0x72 0xEF", outClusters: "0x26"
} }
@@ -74,20 +74,20 @@ def off() {
} }
def levelup() { def levelup() {
def curlevel = device.currentValue('level') as Integer def curlevel = device.currentValue('level') as Integer
if (curlevel <= 90) if (curlevel <= 90)
setLevel(curlevel + 10); setLevel(curlevel + 10);
} }
def leveldown() { def leveldown() {
def curlevel = device.currentValue('level') as Integer def curlevel = device.currentValue('level') as Integer
if (curlevel >= 10) if (curlevel >= 10)
setLevel(curlevel - 10) setLevel(curlevel - 10)
} }
def setLevel(value) { def setLevel(value) {
log.trace "setLevel($value)" log.trace "setLevel($value)"
sendEvent(name: "level", value: value) sendEvent(name: "level", value: value)
} }
def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd) { def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd) {
@@ -106,11 +106,11 @@ def zwaveEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelS
if (cmd.upDown == true) { if (cmd.upDown == true) {
Integer buttonid = 2 Integer buttonid = 2
leveldown() leveldown()
checkbuttonEvent(buttonid) checkbuttonEvent(buttonid)
} else if (cmd.upDown == false) { } else if (cmd.upDown == false) {
Integer buttonid = 3 Integer buttonid = 3
levelup() levelup()
checkbuttonEvent(buttonid) checkbuttonEvent(buttonid)
} }
} }
@@ -140,12 +140,12 @@ def buttonEvent(button) {
def result = [] def result = []
if (button == 1) { if (button == 1) {
def mystate = device.currentValue('switch'); def mystate = device.currentValue('switch');
if (mystate == "on") if (mystate == "on")
off() off()
else else
on() on()
} }
updateState("currentButton", "$button") updateState("currentButton", "$button")
// update the device state, recording the button press // update the device state, recording the button press
result << createEvent(name: "button", value: "pushed", data: [buttonNumber: button], descriptionText: "$device.displayName button $button was pushed", isStateChange: true) result << createEvent(name: "button", value: "pushed", data: [buttonNumber: button], descriptionText: "$device.displayName button $button was pushed", isStateChange: true)
result result
@@ -182,3 +182,7 @@ def updateState(String name, String value) {
state[name] = value state[name] = value
device.updateDataValue(name, value) device.updateDataValue(name, value)
} }
def updated() {
sendEvent(name: "numberOfButtons", value: 3)
}

View File

@@ -236,17 +236,17 @@ def refresh() {
} }
void indicatorWhenOn() { void indicatorWhenOn() {
sendEvent(name: "indicatorStatus", value: "when on", display: false) sendEvent(name: "indicatorStatus", value: "when on", displayed: false)
sendHubCommand(new physicalgraph.device.HubAction(zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 3, size: 1).format())) sendHubCommand(new physicalgraph.device.HubAction(zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 3, size: 1).format()))
} }
void indicatorWhenOff() { void indicatorWhenOff() {
sendEvent(name: "indicatorStatus", value: "when off", display: false) sendEvent(name: "indicatorStatus", value: "when off", displayed: false)
sendHubCommand(new physicalgraph.device.HubAction(zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 3, size: 1).format())) sendHubCommand(new physicalgraph.device.HubAction(zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 3, size: 1).format()))
} }
void indicatorNever() { void indicatorNever() {
sendEvent(name: "indicatorStatus", value: "never", display: false) sendEvent(name: "indicatorStatus", value: "never", displayed: false)
sendHubCommand(new physicalgraph.device.HubAction(zwave.configurationV1.configurationSet(configurationValue: [2], parameterNumber: 3, size: 1).format())) sendHubCommand(new physicalgraph.device.HubAction(zwave.configurationV1.configurationSet(configurationValue: [2], parameterNumber: 3, size: 1).format()))
} }

View File

@@ -29,10 +29,10 @@
capability "Polling" capability "Polling"
capability "Refresh" capability "Refresh"
capability "Sensor" capability "Sensor"
capability "Configuration" capability "Configuration"
capability "Color Control" capability "Color Control"
capability "Power Meter" capability "Power Meter"
command "getDeviceData" command "getDeviceData"
command "softwhite" command "softwhite"
command "daylight" command "daylight"
@@ -54,12 +54,12 @@
command "setAdjustedColor" command "setAdjustedColor"
command "setWhiteLevel" command "setWhiteLevel"
command "test" command "test"
attribute "whiteLevel", "string" attribute "whiteLevel", "string"
fingerprint deviceId: "0x1101", inClusters: "0x27,0x72,0x86,0x26,0x60,0x70,0x32,0x31,0x85,0x33" fingerprint deviceId: "0x1101", inClusters: "0x27,0x72,0x86,0x26,0x60,0x70,0x32,0x31,0x85,0x33"
} }
simulator { simulator {
status "on": "command: 2003, payload: FF" status "on": "command: 2003, payload: FF"
status "off": "command: 2003, payload: 00" status "off": "command: 2003, payload: 00"
@@ -84,7 +84,7 @@
} }
controlTile("levelSliderControl", "device.level", "slider", height: 1, width: 2, inactiveLabel: false) { controlTile("levelSliderControl", "device.level", "slider", height: 1, width: 2, inactiveLabel: false) {
state "level", action:"switch level.setLevel" state "level", action:"switch level.setLevel"
} }
controlTile("whiteSliderControl", "device.whiteLevel", "slider", height: 1, width: 3, inactiveLabel: false) { controlTile("whiteSliderControl", "device.whiteLevel", "slider", height: 1, width: 3, inactiveLabel: false) {
state "whiteLevel", action:"setWhiteLevel", label:'White Level' state "whiteLevel", action:"setWhiteLevel", label:'White Level'
} }
@@ -183,24 +183,24 @@
valueTile("hue", "device.hue", inactiveLabel: false, decoration: "flat") { valueTile("hue", "device.hue", inactiveLabel: false, decoration: "flat") {
state "hue", label: 'Hue ${currentValue} ' state "hue", label: 'Hue ${currentValue} '
} }
main(["switch"]) main(["switch"])
details(["switch", details(["switch",
"levelSliderControl", "levelSliderControl",
"rgbSelector", "rgbSelector",
"whiteSliderControl", "whiteSliderControl",
/*"softwhite", /*"softwhite",
"daylight", "daylight",
"warmwhite", "warmwhite",
"red", "red",
"green", "green",
"blue", "blue",
"white", "white",
"cyan", "cyan",
"magenta", "magenta",
"orange", "orange",
"purple", "purple",
"yellow", "yellow",
"fireplace", "fireplace",
"storm", "storm",
"deepfade", "deepfade",
@@ -214,7 +214,7 @@
def setAdjustedColor(value) { def setAdjustedColor(value) {
log.debug "setAdjustedColor: ${value}" log.debug "setAdjustedColor: ${value}"
toggleTiles("off") //turn off the hard color tiles toggleTiles("off") //turn off the hard color tiles
def level = device.latestValue("level") def level = device.latestValue("level")
@@ -223,19 +223,19 @@ def setAdjustedColor(value) {
log.debug "level is: ${level}" log.debug "level is: ${level}"
value.level = level value.level = level
def c = hexToRgb(value.hex) def c = hexToRgb(value.hex)
value.rh = hex(c.r * (level/100)) value.rh = hex(c.r * (level/100))
value.gh = hex(c.g * (level/100)) value.gh = hex(c.g * (level/100))
value.bh = hex(c.b * (level/100)) value.bh = hex(c.b * (level/100))
setColor(value) setColor(value)
} }
def setColor(value) { def setColor(value) {
log.debug "setColor: ${value}" log.debug "setColor: ${value}"
log.debug "hue is: ${value.hue}" log.debug "hue is: ${value.hue}"
log.debug "saturation is: ${value.saturation}" log.debug "saturation is: ${value.saturation}"
if (value.size() < 8) if (value.size() < 8)
toggleTiles("off") toggleTiles("off")
@@ -246,22 +246,22 @@ def setColor(value) {
value.gh = hex(rgb.g) value.gh = hex(rgb.g)
value.bh = hex(rgb.b) value.bh = hex(rgb.b)
} }
if ((value.size() == 3) && (value.hue != null) && (value.saturation != null) && (value.level)) { //user passed in a level value too from outside (App) if ((value.size() == 3) && (value.hue != null) && (value.saturation != null) && (value.level)) { //user passed in a level value too from outside (App)
def rgb = hslToRGB(value.hue, value.saturation, 0.5) def rgb = hslToRGB(value.hue, value.saturation, 0.5)
value.hex = rgbToHex(rgb) value.hex = rgbToHex(rgb)
value.rh = hex(rgb.r * value.level/100) value.rh = hex(rgb.r * value.level/100)
value.gh = hex(rgb.g * value.level/100) value.gh = hex(rgb.g * value.level/100)
value.bh = hex(rgb.b * value.level/100) value.bh = hex(rgb.b * value.level/100)
} }
if (( value.size() == 1) && (value.hex)) { //being called from outside of device (App) with only hex if (( value.size() == 1) && (value.hex)) { //being called from outside of device (App) with only hex
def rgbInt = hexToRgb(value.hex) def rgbInt = hexToRgb(value.hex)
value.rh = hex(rgbInt.r) value.rh = hex(rgbInt.r)
value.gh = hex(rgbInt.g) value.gh = hex(rgbInt.g)
value.bh = hex(rgbInt.b) value.bh = hex(rgbInt.b)
} }
if (( value.size() == 2) && (value.hex) && (value.level)) { //being called from outside of device (App) with only hex and level if (( value.size() == 2) && (value.hex) && (value.level)) { //being called from outside of device (App) with only hex and level
def rgbInt = hexToRgb(value.hex) def rgbInt = hexToRgb(value.hex)
@@ -269,7 +269,7 @@ def setColor(value) {
value.gh = hex(rgbInt.g * value.level/100) value.gh = hex(rgbInt.g * value.level/100)
value.bh = hex(rgbInt.b * value.level/100) value.bh = hex(rgbInt.b * value.level/100)
} }
if (( value.size() == 1) && (value.colorName)) { //being called from outside of device (App) with only color name if (( value.size() == 1) && (value.colorName)) { //being called from outside of device (App) with only color name
def colorData = getColorData(value.colorName) def colorData = getColorData(value.colorName)
value.rh = colorData.rh value.rh = colorData.rh
@@ -277,7 +277,7 @@ def setColor(value) {
value.bh = colorData.bh value.bh = colorData.bh
value.hex = "#${value.rh}${value.gh}${value.bh}" value.hex = "#${value.rh}${value.gh}${value.bh}"
} }
if (( value.size() == 2) && (value.colorName) && (value.level)) { //being called from outside of device (App) with only color name and level if (( value.size() == 2) && (value.colorName) && (value.level)) { //being called from outside of device (App) with only color name and level
def colorData = getColorData(value.colorName) def colorData = getColorData(value.colorName)
value.rh = hex(colorData.r * value.level/100) value.rh = hex(colorData.r * value.level/100)
@@ -285,7 +285,7 @@ def setColor(value) {
value.bh = hex(colorData.b * value.level/100) value.bh = hex(colorData.b * value.level/100)
value.hex = "#${hex(colorData.r)}${hex(colorData.g)}${hex(colorData.b)}" value.hex = "#${hex(colorData.r)}${hex(colorData.g)}${hex(colorData.b)}"
} }
if (( value.size() == 3) && (value.red != null) && (value.green != null) && (value.blue != null)) { //being called from outside of device (App) with only color values (0-255) if (( value.size() == 3) && (value.red != null) && (value.green != null) && (value.blue != null)) { //being called from outside of device (App) with only color values (0-255)
value.rh = hex(value.red) value.rh = hex(value.red)
value.gh = hex(value.green) value.gh = hex(value.green)
@@ -299,7 +299,7 @@ def setColor(value) {
value.bh = hex(value.blue * value.level/100) value.bh = hex(value.blue * value.level/100)
value.hex = "#${hex(value.red)}${hex(value.green)}${hex(value.blue)}" value.hex = "#${hex(value.red)}${hex(value.green)}${hex(value.blue)}"
} }
sendEvent(name: "hue", value: value.hue, displayed: false) sendEvent(name: "hue", value: value.hue, displayed: false)
sendEvent(name: "saturation", value: value.saturation, displayed: false) sendEvent(name: "saturation", value: value.saturation, displayed: false)
sendEvent(name: "color", value: value.hex, displayed: false) sendEvent(name: "color", value: value.hex, displayed: false)
@@ -309,26 +309,26 @@ def setColor(value) {
if (value.switch) { if (value.switch) {
sendEvent(name: "switch", value: value.switch) sendEvent(name: "switch", value: value.switch)
} }
sendRGB(value.rh, value.gh, value.bh) sendRGB(value.rh, value.gh, value.bh)
} }
def setLevel(level) { def setLevel(level) {
log.debug "setLevel($level)" log.debug "setLevel($level)"
if (level == 0) { off() } if (level == 0) { off() }
else if (device.latestValue("switch") == "off") { on() } else if (device.latestValue("switch") == "off") { on() }
def colorHex = device.latestValue("color") def colorHex = device.latestValue("color")
if (colorHex == null) if (colorHex == null)
colorHex = "#FFFFFF" colorHex = "#FFFFFF"
def c = hexToRgb(colorHex) def c = hexToRgb(colorHex)
def r = hex(c.r * (level/100)) def r = hex(c.r * (level/100))
def g = hex(c.g * (level/100)) def g = hex(c.g * (level/100))
def b = hex(c.b * (level/100)) def b = hex(c.b * (level/100))
sendEvent(name: "level", value: level) sendEvent(name: "level", value: level)
sendEvent(name: "setLevel", value: level, displayed: false) sendEvent(name: "setLevel", value: level, displayed: false)
sendRGB(r, g, b) sendRGB(r, g, b)
@@ -337,14 +337,14 @@ def setLevel(level) {
def setWhiteLevel(value) { def setWhiteLevel(value) {
log.debug "setWhiteLevel: ${value}" log.debug "setWhiteLevel: ${value}"
def level = Math.min(value as Integer, 99) def level = Math.min(value as Integer, 99)
level = 255 * level/99 as Integer level = 255 * level/99 as Integer
def channel = 0 def channel = 0
if (device.latestValue("switch") == "off") { on() } if (device.latestValue("switch") == "off") { on() }
sendEvent(name: "whiteLevel", value: value) sendEvent(name: "whiteLevel", value: value)
sendWhite(channel, value) sendWhite(channel, value)
} }
def sendWhite(channel, value) { def sendWhite(channel, value) {
@@ -367,20 +367,20 @@ def sendRGBW(redHex, greenHex, blueHex, whiteHex) {
def configure() { def configure() {
log.debug "Configuring Device For SmartThings Use" log.debug "Configuring Device For SmartThings Use"
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
cmds << zwave.associationV2.associationSet(groupingIdentifier:5, nodeId:[zwaveHubNodeId]).format() cmds << zwave.associationV2.associationSet(groupingIdentifier:5, nodeId:[zwaveHubNodeId]).format()
//cmds << sendEvent(name: "level", value: 50) //cmds << sendEvent(name: "level", value: 50)
//cmds << on() //cmds << on()
//cmds << doColorButton("Green") //cmds << doColorButton("Green")
delayBetween(cmds, 500) delayBetween(cmds, 500)
} }
def parse(String description) { def parse(String description) {
@@ -411,11 +411,11 @@ def parse(String description) {
def getDeviceData() { def getDeviceData() {
def cmd = [] def cmd = []
cmd << response(zwave.manufacturerSpecificV2.manufacturerSpecificGet()) cmd << response(zwave.manufacturerSpecificV2.manufacturerSpecificGet())
cmd << response(zwave.versionV1.versionGet()) cmd << response(zwave.versionV1.versionGet())
cmd << response(zwave.firmwareUpdateMdV1.firmwareMdGet()) cmd << response(zwave.firmwareUpdateMdV1.firmwareMdGet())
delayBetween(cmd, 500) delayBetween(cmd, 500)
} }
@@ -426,7 +426,7 @@ def createEvent(physicalgraph.zwave.commands.manufacturerspecificv2.Manufacturer
log.debug "productTypeId: ${cmd.productTypeId}" log.debug "productTypeId: ${cmd.productTypeId}"
} }
def createEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd, Map item1) { def createEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd, Map item1) {
updateDataValue("applicationVersion", "${cmd.applicationVersion}") updateDataValue("applicationVersion", "${cmd.applicationVersion}")
log.debug "applicationVersion: ${cmd.applicationVersion}" log.debug "applicationVersion: ${cmd.applicationVersion}"
log.debug "applicationSubVersion: ${cmd.applicationSubVersion}" log.debug "applicationSubVersion: ${cmd.applicationSubVersion}"
@@ -435,13 +435,13 @@ def createEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd, Map it
log.debug "zWaveProtocolSubVersion: ${cmd.zWaveProtocolSubVersion}" log.debug "zWaveProtocolSubVersion: ${cmd.zWaveProtocolSubVersion}"
} }
def createEvent(physicalgraph.zwave.commands.firmwareupdatemdv1.FirmwareMdReport cmd, Map item1) { def createEvent(physicalgraph.zwave.commands.firmwareupdatemdv1.FirmwareMdReport cmd, Map item1) {
log.debug "checksum: ${cmd.checksum}" log.debug "checksum: ${cmd.checksum}"
log.debug "firmwareId: ${cmd.firmwareId}" log.debug "firmwareId: ${cmd.firmwareId}"
log.debug "manufacturerId: ${cmd.manufacturerId}" log.debug "manufacturerId: ${cmd.manufacturerId}"
} }
def zwaveEvent(physicalgraph.zwave.commands.colorcontrolv1.CapabilityReport cmd, Map item1) { def zwaveEvent(physicalgraph.zwave.commands.colorcontrolv1.CapabilityReport cmd, Map item1) {
log.debug "In CapabilityReport" log.debug "In CapabilityReport"
} }
@@ -546,7 +546,7 @@ def zwaveEvent(physicalgraph.zwave.commands.configurationv1.ConfigurationReport
def value = "when off" def value = "when off"
if (cmd.configurationValue[0] == 1) {value = "when on"} if (cmd.configurationValue[0] == 1) {value = "when on"}
if (cmd.configurationValue[0] == 2) {value = "never"} if (cmd.configurationValue[0] == 2) {value = "never"}
[name: "indicatorStatus", value: value, display: false] [name: "indicatorStatus", value: value, displayed: false]
} }
*/ */
def createEvent(physicalgraph.zwave.Command cmd, Map map) { def createEvent(physicalgraph.zwave.Command cmd, Map map) {
@@ -557,7 +557,7 @@ def createEvent(physicalgraph.zwave.Command cmd, Map map) {
def on() { def on() {
log.debug "on()" log.debug "on()"
sendEvent(name: "switch", value: "on") sendEvent(name: "switch", value: "on")
delayBetween([zwave.basicV1.basicSet(value: 0xFF).format(), delayBetween([zwave.basicV1.basicSet(value: 0xFF).format(),
zwave.switchMultilevelV1.switchMultilevelGet().format()], 5000) zwave.switchMultilevelV1.switchMultilevelGet().format()], 5000)
} }
@@ -593,7 +593,7 @@ def refresh() {
* @return none * @return none
*/ */
def updateZwaveParam(params) { def updateZwaveParam(params) {
if ( params ) { if ( params ) {
def pNumber = params.paramNumber def pNumber = params.paramNumber
def pSize = params.size def pSize = params.size
def pValue = [params.value] def pValue = [params.value]
@@ -601,9 +601,9 @@ def updateZwaveParam(params) {
def cmds = [] def cmds = []
cmds << zwave.configurationV1.configurationSet(configurationValue: pValue, parameterNumber: pNumber, size: pSize).format() cmds << zwave.configurationV1.configurationSet(configurationValue: pValue, parameterNumber: pNumber, size: pSize).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: pNumber).format() cmds << zwave.configurationV1.configurationGet(parameterNumber: pNumber).format()
delayBetween(cmds, 1500) delayBetween(cmds, 1500)
} }
} }
@@ -612,22 +612,22 @@ def test() {
//value = [hue: 0, saturation: 100, level: 5] //value = [hue: 0, saturation: 100, level: 5]
//value = [red: 255, green: 0, blue: 255, level: 60] //value = [red: 255, green: 0, blue: 255, level: 60]
//setColor(value) //setColor(value)
def cmd = [] def cmd = []
if ( !state.cnt ) { if ( !state.cnt ) {
state.cnt = 6 state.cnt = 6
} else { } else {
state.cnt = state.cnt + 1 state.cnt = state.cnt + 1
} }
if ( state.cnt > 10 ) if ( state.cnt > 10 )
state.cnt = 6 state.cnt = 6
// run programmed light show // run programmed light show
cmd << zwave.configurationV1.configurationSet(configurationValue: [state.cnt], parameterNumber: 72, size: 1).format() cmd << zwave.configurationV1.configurationSet(configurationValue: [state.cnt], parameterNumber: 72, size: 1).format()
cmd << zwave.configurationV1.configurationGet(parameterNumber: 72).format() cmd << zwave.configurationV1.configurationGet(parameterNumber: 72).format()
delayBetween(cmd, 500) delayBetween(cmd, 500)
} }
@@ -638,23 +638,23 @@ def colorNameToRgb(color) {
[name:"Soft White", r: 255, g: 241, b: 224 ], [name:"Soft White", r: 255, g: 241, b: 224 ],
[name:"Daylight", r: 255, g: 255, b: 251 ], [name:"Daylight", r: 255, g: 255, b: 251 ],
[name:"Warm White", r: 255, g: 244, b: 229 ], [name:"Warm White", r: 255, g: 244, b: 229 ],
[name:"Red", r: 255, g: 0, b: 0 ], [name:"Red", r: 255, g: 0, b: 0 ],
[name:"Green", r: 0, g: 255, b: 0 ], [name:"Green", r: 0, g: 255, b: 0 ],
[name:"Blue", r: 0, g: 0, b: 255 ], [name:"Blue", r: 0, g: 0, b: 255 ],
[name:"Cyan", r: 0, g: 255, b: 255 ], [name:"Cyan", r: 0, g: 255, b: 255 ],
[name:"Magenta", r: 255, g: 0, b: 33 ], [name:"Magenta", r: 255, g: 0, b: 33 ],
[name:"Orange", r: 255, g: 102, b: 0 ], [name:"Orange", r: 255, g: 102, b: 0 ],
[name:"Purple", r: 170, g: 0, b: 255 ], [name:"Purple", r: 170, g: 0, b: 255 ],
[name:"Yellow", r: 255, g: 255, b: 0 ], [name:"Yellow", r: 255, g: 255, b: 0 ],
[name:"White", r: 255, g: 255, b: 255 ] [name:"White", r: 255, g: 255, b: 255 ]
] ]
def colorData = [:] def colorData = [:]
colorData = colors.find { it.name == color } colorData = colors.find { it.name == color }
colorData colorData
} }
@@ -670,7 +670,7 @@ def hexToRgb(colorHex) {
def rrInt = Integer.parseInt(colorHex.substring(1,3),16) def rrInt = Integer.parseInt(colorHex.substring(1,3),16)
def ggInt = Integer.parseInt(colorHex.substring(3,5),16) def ggInt = Integer.parseInt(colorHex.substring(3,5),16)
def bbInt = Integer.parseInt(colorHex.substring(5,7),16) def bbInt = Integer.parseInt(colorHex.substring(5,7),16)
def colorData = [:] def colorData = [:]
colorData = [r: rrInt, g: ggInt, b: bbInt] colorData = [r: rrInt, g: ggInt, b: bbInt]
colorData colorData
@@ -681,7 +681,7 @@ def rgbToHex(rgb) {
def g = hex(rgb.g) def g = hex(rgb.g)
def b = hex(rgb.b) def b = hex(rgb.b)
def hexColor = "#${r}${g}${b}" def hexColor = "#${r}${g}${b}"
hexColor hexColor
} }
@@ -689,11 +689,11 @@ def hslToRGB(float var_h, float var_s, float var_l) {
float h = var_h / 100 float h = var_h / 100
float s = var_s / 100 float s = var_s / 100
float l = var_l float l = var_l
def r = 0 def r = 0
def g = 0 def g = 0
def b = 0 def b = 0
if (s == 0) { if (s == 0) {
r = l * 255 r = l * 255
g = l * 255 g = l * 255
@@ -705,26 +705,26 @@ def hslToRGB(float var_h, float var_s, float var_l) {
} else { } else {
var_2 = (l + s) - (s * l) var_2 = (l + s) - (s * l)
} }
float var_1 = 2 * l - var_2 float var_1 = 2 * l - var_2
r = 255 * hueToRgb(var_1, var_2, h + (1 / 3)) r = 255 * hueToRgb(var_1, var_2, h + (1 / 3))
g = 255 * hueToRgb(var_1, var_2, h) g = 255 * hueToRgb(var_1, var_2, h)
b = 255 * hueToRgb(var_1, var_2, h - (1 / 3)) b = 255 * hueToRgb(var_1, var_2, h - (1 / 3))
} }
def rgb = [:] def rgb = [:]
rgb = [r: r, g: g, b: b] rgb = [r: r, g: g, b: b]
rgb rgb
} }
def hueToRgb(v1, v2, vh) { def hueToRgb(v1, v2, vh) {
if (vh < 0) { vh += 1 } if (vh < 0) { vh += 1 }
if (vh > 1) { vh -= 1 } if (vh > 1) { vh -= 1 }
if ((6 * vh) < 1) { return (v1 + (v2 - v1) * 6 * vh) } if ((6 * vh) < 1) { return (v1 + (v2 - v1) * 6 * vh) }
if ((2 * vh) < 1) { return (v2) } if ((2 * vh) < 1) { return (v2) }
if ((3 * vh) < 2) { return (v1 + (v2 - $v1) * ((2 / 3 - vh) * 6)) } if ((3 * vh) < 2) { return (v1 + (v2 - $v1) * ((2 / 3 - vh) * 6)) }
return (v1) return (v1)
} }
@@ -735,49 +735,49 @@ def rgbToHSL(rgb) {
def h = 0 def h = 0
def s = 0 def s = 0
def l = 0 def l = 0
def var_min = [r,g,b].min() def var_min = [r,g,b].min()
def var_max = [r,g,b].max() def var_max = [r,g,b].max()
def del_max = var_max - var_min def del_max = var_max - var_min
l = (var_max + var_min) / 2 l = (var_max + var_min) / 2
if (del_max == 0) { if (del_max == 0) {
h = 0 h = 0
s = 0 s = 0
} else { } else {
if (l < 0.5) { s = del_max / (var_max + var_min) } if (l < 0.5) { s = del_max / (var_max + var_min) }
else { s = del_max / (2 - var_max - var_min) } else { s = del_max / (2 - var_max - var_min) }
def del_r = (((var_max - r) / 6) + (del_max / 2)) / del_max def del_r = (((var_max - r) / 6) + (del_max / 2)) / del_max
def del_g = (((var_max - g) / 6) + (del_max / 2)) / del_max def del_g = (((var_max - g) / 6) + (del_max / 2)) / del_max
def del_b = (((var_max - b) / 6) + (del_max / 2)) / del_max def del_b = (((var_max - b) / 6) + (del_max / 2)) / del_max
if (r == var_max) { h = del_b - del_g } if (r == var_max) { h = del_b - del_g }
else if (g == var_max) { h = (1 / 3) + del_r - del_b } else if (g == var_max) { h = (1 / 3) + del_r - del_b }
else if (b == var_max) { h = (2 / 3) + del_g - del_r } else if (b == var_max) { h = (2 / 3) + del_g - del_r }
if (h < 0) { h += 1 } if (h < 0) { h += 1 }
if (h > 1) { h -= 1 } if (h > 1) { h -= 1 }
} }
def hsl = [:] def hsl = [:]
hsl = [h: h * 100, s: s * 100, l: l] hsl = [h: h * 100, s: s * 100, l: l]
hsl hsl
} }
def getColorData(colorName) { def getColorData(colorName) {
log.debug "getColorData: ${colorName}" log.debug "getColorData: ${colorName}"
def colorRGB = colorNameToRgb(colorName) def colorRGB = colorNameToRgb(colorName)
def colorHex = rgbToHex(colorRGB) def colorHex = rgbToHex(colorRGB)
def colorHSL = rgbToHSL(colorRGB) def colorHSL = rgbToHSL(colorRGB)
def colorData = [:] def colorData = [:]
colorData = [h: colorHSL.h, colorData = [h: colorHSL.h,
s: colorHSL.s, s: colorHSL.s,
l: device.latestValue("level"), l: device.latestValue("level"),
r: colorRGB.r, r: colorRGB.r,
g: colorRGB.g, g: colorRGB.g,
b: colorRGB.b, b: colorRGB.b,
rh: hex(colorRGB.r), rh: hex(colorRGB.r),
@@ -785,8 +785,8 @@ def getColorData(colorName) {
bh: hex(colorRGB.b), bh: hex(colorRGB.b),
hex: colorHex, hex: colorHex,
alpha: 1] alpha: 1]
colorData colorData
} }
def doColorButton(colorName) { def doColorButton(colorName) {
@@ -798,7 +798,7 @@ def doColorButton(colorName) {
def maxLevel = hex(99) def maxLevel = hex(99)
toggleTiles(colorName.toLowerCase().replaceAll("\\s","")) toggleTiles(colorName.toLowerCase().replaceAll("\\s",""))
if ( colorName == "Fire Place" ) { updateZwaveParam([paramNumber:72, value:6, size:1]) } if ( colorName == "Fire Place" ) { updateZwaveParam([paramNumber:72, value:6, size:1]) }
else if ( colorName == "Storm" ) { updateZwaveParam([paramNumber:72, value:7, size:1]) } else if ( colorName == "Storm" ) { updateZwaveParam([paramNumber:72, value:7, size:1]) }
else if ( colorName == "Deep Fade" ) { updateZwaveParam([paramNumber:72, value:8, size:1]) } else if ( colorName == "Deep Fade" ) { updateZwaveParam([paramNumber:72, value:8, size:1]) }
@@ -808,8 +808,8 @@ def doColorButton(colorName) {
else if ( colorName == "Daylight" ) { String.format("33050400${maxLevel}02${maxLevel}03${maxLevel}04${maxLevel}%02X", 100) } else if ( colorName == "Daylight" ) { String.format("33050400${maxLevel}02${maxLevel}03${maxLevel}04${maxLevel}%02X", 100) }
else { else {
def c = getColorData(colorName) def c = getColorData(colorName)
def newValue = ["hue": c.h, "saturation": c.s, "level": level, "red": c.r, "green": c.g, "blue": c.b, "hex": c.hex, "alpha": c.alpha] def newValue = ["hue": c.h, "saturation": c.s, "level": level, "red": c.r, "green": c.g, "blue": c.b, "hex": c.hex, "alpha": c.alpha]
setColor(newValue) setColor(newValue)
def r = hex(c.r * (level/100)) def r = hex(c.r * (level/100))
def g = hex(c.g * (level/100)) def g = hex(c.g * (level/100))
def b = hex(c.b * (level/100)) def b = hex(c.b * (level/100))
@@ -823,19 +823,19 @@ def toggleTiles(color) {
if ( !state.colorTiles ) { if ( !state.colorTiles ) {
state.colorTiles = ["softwhite","daylight","warmwhite","red","green","blue","cyan","magenta","orange","purple","yellow","white","fireplace","storm","deepfade","litefade","police"] state.colorTiles = ["softwhite","daylight","warmwhite","red","green","blue","cyan","magenta","orange","purple","yellow","white","fireplace","storm","deepfade","litefade","police"]
} }
def cmds = [] def cmds = []
state.colorTiles.each({ state.colorTiles.each({
if ( it == color ) { if ( it == color ) {
log.debug "Turning ${it} on" log.debug "Turning ${it} on"
cmds << sendEvent(name: it, value: "on${it}", display: True, descriptionText: "${device.displayName} ${color} is 'ON'", isStateChange: true) cmds << sendEvent(name: it, value: "on${it}", displayed: True, descriptionText: "${device.displayName} ${color} is 'ON'", isStateChange: true)
} else { } else {
//log.debug "Turning ${it} off" //log.debug "Turning ${it} off"
cmds << sendEvent(name: it, value: "off${it}", displayed: false) cmds << sendEvent(name: it, value: "off${it}", displayed: false)
} }
}) })
delayBetween(cmds, 2500) delayBetween(cmds, 2500)
} }

View File

@@ -43,8 +43,8 @@ def parse(String description) {
} }
def push() { def push() {
sendEvent(name: "switch", value: "on", isStateChange: true, display: false) sendEvent(name: "switch", value: "on", isStateChange: true, displayed: false)
sendEvent(name: "switch", value: "off", isStateChange: true, display: false) sendEvent(name: "switch", value: "off", isStateChange: true, displayed: false)
sendEvent(name: "momentary", value: "pushed", isStateChange: true) sendEvent(name: "momentary", value: "pushed", isStateChange: true)
} }

View File

@@ -15,9 +15,10 @@ metadata {
definition (name: "Simulated Minimote", namespace: "smartthings/testing", author: "SmartThings") { definition (name: "Simulated Minimote", namespace: "smartthings/testing", author: "SmartThings") {
capability "Actuator" capability "Actuator"
capability "Button" capability "Button"
capability "Holdable Button"
capability "Configuration" capability "Configuration"
capability "Sensor" capability "Sensor"
command "push1" command "push1"
command "push2" command "push2"
command "push3" command "push3"
@@ -45,42 +46,42 @@ metadata {
} }
standardTile("push1", "device.button", width: 1, height: 1, decoration: "flat") { standardTile("push1", "device.button", width: 1, height: 1, decoration: "flat") {
state "default", label: "Push 1", backgroundColor: "#ffffff", action: "push1" state "default", label: "Push 1", backgroundColor: "#ffffff", action: "push1"
} }
standardTile("push2", "device.button", width: 1, height: 1, decoration: "flat") { standardTile("push2", "device.button", width: 1, height: 1, decoration: "flat") {
state "default", label: "Push 2", backgroundColor: "#ffffff", action: "push2" state "default", label: "Push 2", backgroundColor: "#ffffff", action: "push2"
} }
standardTile("push3", "device.button", width: 1, height: 1, decoration: "flat") { standardTile("push3", "device.button", width: 1, height: 1, decoration: "flat") {
state "default", label: "Push 3", backgroundColor: "#ffffff", action: "push3" state "default", label: "Push 3", backgroundColor: "#ffffff", action: "push3"
} }
standardTile("push4", "device.button", width: 1, height: 1, decoration: "flat") { standardTile("push4", "device.button", width: 1, height: 1, decoration: "flat") {
state "default", label: "Push 4", backgroundColor: "#ffffff", action: "push4" state "default", label: "Push 4", backgroundColor: "#ffffff", action: "push4"
} }
standardTile("dummy1", "device.button", width: 1, height: 1, decoration: "flat") { standardTile("dummy1", "device.button", width: 1, height: 1, decoration: "flat") {
state "default", label: " ", backgroundColor: "#ffffff", action: "push4" state "default", label: " ", backgroundColor: "#ffffff", action: "push4"
} }
standardTile("hold1", "device.button", width: 1, height: 1, decoration: "flat") { standardTile("hold1", "device.button", width: 1, height: 1, decoration: "flat") {
state "default", label: "Hold 1", backgroundColor: "#ffffff", action: "hold1" state "default", label: "Hold 1", backgroundColor: "#ffffff", action: "hold1"
} }
standardTile("hold2", "device.button", width: 1, height: 1, decoration: "flat") { standardTile("hold2", "device.button", width: 1, height: 1, decoration: "flat") {
state "default", label: "Hold 2", backgroundColor: "#ffffff", action: "hold2" state "default", label: "Hold 2", backgroundColor: "#ffffff", action: "hold2"
} }
standardTile("dummy2", "device.button", width: 1, height: 1, decoration: "flat") { standardTile("dummy2", "device.button", width: 1, height: 1, decoration: "flat") {
state "default", label: " ", backgroundColor: "#ffffff", action: "push4" state "default", label: " ", backgroundColor: "#ffffff", action: "push4"
} }
standardTile("hold3", "device.button", width: 1, height: 1, decoration: "flat") { standardTile("hold3", "device.button", width: 1, height: 1, decoration: "flat") {
state "default", label: "Hold 3", backgroundColor: "#ffffff", action: "hold3" state "default", label: "Hold 3", backgroundColor: "#ffffff", action: "hold3"
} }
standardTile("hold4", "device.button", width: 1, height: 1, decoration: "flat") { standardTile("hold4", "device.button", width: 1, height: 1, decoration: "flat") {
state "default", label: "Hold 4", backgroundColor: "#ffffff", action: "hold4" state "default", label: "Hold 4", backgroundColor: "#ffffff", action: "hold4"
} }
main "button" main "button"
details(["push1","push2","button","push3","push4","dummy1","hold1","hold2","dummy2","hold3","hold4"]) details(["push1","push2","button","push3","push4","dummy1","hold1","hold2","dummy2","hold3","hold4"])
} }
} }
def parse(String description) { def parse(String description) {
} }
def push1() { def push1() {
@@ -125,3 +126,6 @@ private hold(button) {
sendEvent(name: "button", value: "held", data: [buttonNumber: button], descriptionText: "$device.displayName button $button was held", isStateChange: true) sendEvent(name: "button", value: "held", data: [buttonNumber: button], descriptionText: "$device.displayName button $button was held", isStateChange: true)
} }
def updated() {
sendEvent(name: "numberOfButtons", value: 4)
}

View File

@@ -19,6 +19,7 @@ metadata {
capability "Actuator" capability "Actuator"
capability "Battery" capability "Battery"
capability "Button" capability "Button"
capability "Holdable Button"
capability "Configuration" capability "Configuration"
capability "Refresh" capability "Refresh"
capability "Sensor" capability "Sensor"

View File

@@ -81,7 +81,7 @@ def zwaveEvent(physicalgraph.zwave.commands.configurationv1.ConfigurationReport
def value = "when off" def value = "when off"
if (cmd.configurationValue[0] == 1) {value = "when on"} if (cmd.configurationValue[0] == 1) {value = "when on"}
if (cmd.configurationValue[0] == 2) {value = "never"} if (cmd.configurationValue[0] == 2) {value = "never"}
[name: "indicatorStatus", value: value, display: false] [name: "indicatorStatus", value: value, displayed: false]
} }
def zwaveEvent(physicalgraph.zwave.commands.hailv1.Hail cmd) { def zwaveEvent(physicalgraph.zwave.commands.hailv1.Hail cmd) {

View File

@@ -114,7 +114,7 @@ def zwaveEvent(physicalgraph.zwave.commands.configurationv1.ConfigurationReport
def value = "when off" def value = "when off"
if (cmd.configurationValue[0] == 1) {value = "when on"} if (cmd.configurationValue[0] == 1) {value = "when on"}
if (cmd.configurationValue[0] == 2) {value = "never"} if (cmd.configurationValue[0] == 2) {value = "never"}
[name: "indicatorStatus", value: value, display: false] [name: "indicatorStatus", value: value, displayed: false]
} }
def zwaveEvent(physicalgraph.zwave.commands.hailv1.Hail cmd) { def zwaveEvent(physicalgraph.zwave.commands.hailv1.Hail cmd) {
@@ -174,17 +174,17 @@ def refresh() {
} }
void indicatorWhenOn() { void indicatorWhenOn() {
sendEvent(name: "indicatorStatus", value: "when on", display: false) sendEvent(name: "indicatorStatus", value: "when on", displayed: false)
sendHubCommand(new physicalgraph.device.HubAction(zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 3, size: 1).format())) sendHubCommand(new physicalgraph.device.HubAction(zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 3, size: 1).format()))
} }
void indicatorWhenOff() { void indicatorWhenOff() {
sendEvent(name: "indicatorStatus", value: "when off", display: false) sendEvent(name: "indicatorStatus", value: "when off", displayed: false)
sendHubCommand(new physicalgraph.device.HubAction(zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 3, size: 1).format())) sendHubCommand(new physicalgraph.device.HubAction(zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 3, size: 1).format()))
} }
void indicatorNever() { void indicatorNever() {
sendEvent(name: "indicatorStatus", value: "never", display: false) sendEvent(name: "indicatorStatus", value: "never", displayed: false)
sendHubCommand(new physicalgraph.device.HubAction(zwave.configurationV1.configurationSet(configurationValue: [2], parameterNumber: 3, size: 1).format())) sendHubCommand(new physicalgraph.device.HubAction(zwave.configurationV1.configurationSet(configurationValue: [2], parameterNumber: 3, size: 1).format()))
} }

View File

@@ -1,9 +1,10 @@
/** /**
* Color Coordinator * Color Coordinator
* Version 1.0.0 - 7/4/15 * Version 1.1.0 - 11/9/16
* By Michael Struck * By Michael Struck
* *
* 1.0.0 - Initial release * 1.0.0 - Initial release
* 1.1.0 - Fixed issue where master can be part of slaves. This causes a loop that impacts SmartThings.
* *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
@@ -31,27 +32,35 @@ preferences {
} }
def mainPage() { def mainPage() {
dynamicPage(name: "mainPage", title: "", install: true, uninstall: true) { dynamicPage(name: "mainPage", title: "", install: true, uninstall: false) {
section("Master Light") { def masterInList = slaves.id.find{it==master.id}
if (masterInList) {
section ("**WARNING**"){
paragraph "You have included the Master Light in the Slave Group. This will cause a loop in execution. Please remove this device from the Slave Group.", image: "https://raw.githubusercontent.com/MichaelStruck/SmartThingsPublic/master/img/caution.png"
}
}
section("Master Light") {
input "master", "capability.colorControl", title: "Colored Light" input "master", "capability.colorControl", title: "Colored Light"
} }
section("Lights that follow the master settings") { section("Lights that follow the master settings") {
input "slaves", "capability.colorControl", title: "Colored Lights", multiple: true, required: false input "slaves", "capability.colorControl", title: "Colored Lights", multiple: true, required: false, submitOnChange: true
} }
section([mobileOnly:true], "Options") { section([mobileOnly:true], "Options") {
label(title: "Assign a name", required: false) input "randomYes", "bool",title: "When Master Turned On, Randomize Color", defaultValue: false
href "pageAbout", title: "About ${textAppName()}", description: "Tap to get application version, license and instructions" href "pageAbout", title: "About ${textAppName()}", description: "Tap to get application version, license and instructions"
} }
} }
} }
page(name: "pageAbout", title: "About ${textAppName()}") { page(name: "pageAbout", title: "About ${textAppName()}", uninstall: true) {
section { section {
paragraph "${textVersion()}\n${textCopyright()}\n\n${textLicense()}\n" paragraph "${textVersion()}\n${textCopyright()}\n\n${textLicense()}\n"
} }
section("Instructions") { section("Instructions") {
paragraph textHelp() paragraph textHelp()
} }
section("Tap button below to remove application"){
}
} }
def installed() { def installed() {
@@ -72,27 +81,55 @@ def init() {
} }
//----------------------------------- //-----------------------------------
def onOffHandler(evt){ def onOffHandler(evt){
if (master.currentValue("switch") == "on"){ if (!slaves.id.find{it==master.id}){
slaves?.on() if (master.currentValue("switch") == "on"){
} if (randomYes) getRandomColorMaster()
else { else slaves?.on()
slaves?.off() }
} else {
slaves?.off()
}
}
} }
def colorHandler(evt) { def colorHandler(evt) {
def dimLevel = master.currentValue("level") if (!slaves.id.find{it==master.id} && master.currentValue("switch") == "on"){
def hueLevel = master.currentValue("hue") log.debug "Changing Slave units H,S,L"
def saturationLevel = master.currentValue("saturation") def dimLevel = master.currentValue("level")
def hueLevel = master.currentValue("hue")
def saturationLevel = master.currentValue("saturation")
def newValue = [hue: hueLevel, saturation: saturationLevel, level: dimLevel as Integer]
slaves?.setColor(newValue)
try {
log.debug "Changing Slave color temp"
def tempLevel = master.currentValue("colorTemperature")
slaves?.setColorTemperature(tempLevel)
}
catch (e){
log.debug "Color temp for master --"
}
}
}
def getRandomColorMaster(){
def hueLevel = Math.floor(Math.random() *1000)
def saturationLevel = Math.floor(Math.random() * 100)
def dimLevel = master.currentValue("level")
def newValue = [hue: hueLevel, saturation: saturationLevel, level: dimLevel as Integer] def newValue = [hue: hueLevel, saturation: saturationLevel, level: dimLevel as Integer]
slaves?.setColor(newValue) log.debug hueLevel
log.debug saturationLevel
master.setColor(newValue)
slaves?.setColor(newValue)
} }
def tempHandler(evt){ def tempHandler(evt){
if (evt.value != "--") { if (!slaves.id.find{it==master.id} && master.currentValue("switch") == "on"){
def tempLevel = master.currentValue("colorTemperature") if (evt.value != "--") {
slaves?.setColorTemperature(tempLevel) log.debug "Changing Slave color temp based on Master change"
} def tempLevel = master.currentValue("colorTemperature")
slaves?.setColorTemperature(tempLevel)
}
}
} }
//Version/Copyright/Information/Help //Version/Copyright/Information/Help
@@ -102,11 +139,11 @@ private def textAppName() {
} }
private def textVersion() { private def textVersion() {
def text = "Version 1.0.0 (07/04/2015)" def text = "Version 1.1.0 (11/09/2016)"
} }
private def textCopyright() { private def textCopyright() {
def text = "Copyright © 2015 Michael Struck" def text = "Copyright © 2016 Michael Struck"
} }
private def textLicense() { private def textLicense() {
@@ -128,5 +165,5 @@ private def textHelp() {
def text = def text =
"This application will allow you to control the settings of multiple colored lights with one control. " + "This application will allow you to control the settings of multiple colored lights with one control. " +
"Simply choose a master control light, and then choose the lights that will follow the settings of the master, "+ "Simply choose a master control light, and then choose the lights that will follow the settings of the master, "+
"including on/off conditions, hue, saturation, level and color temperature." "including on/off conditions, hue, saturation, level and color temperature. Also includes a random color feature."
} }

View File

@@ -0,0 +1,662 @@
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
/**
* OpenT2T SmartApp Test
*
* Copyright 2016 OpenT2T
*
* 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: "OpenT2T SmartApp Test",
namespace: "opent2t",
author: "OpenT2T",
description: "Test app to test end to end SmartThings scenarios via OpenT2T",
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")
/** --------------------+---------------+-----------------------+------------------------------------
* Device Type | Attribute Name| Commands | Attribute Values
* --------------------+---------------+-----------------------+------------------------------------
* switches | switch | on, off | on, off
* motionSensors | motion | | active, inactive
* contactSensors | contact | | open, closed
* presenceSensors | presence | | present, 'not present'
* temperatureSensors | temperature | | <numeric, F or C according to unit>
* accelerationSensors | acceleration | | active, inactive
* waterSensors | water | | wet, dry
* lightSensors | illuminance | | <numeric, lux>
* humiditySensors | humidity | | <numeric, percent>
* locks | lock | lock, unlock | locked, unlocked
* garageDoors | door | open, close | unknown, closed, open, closing, opening
* cameras | image | take | <String>
* thermostats | thermostat | setHeatingSetpoint, | temperature, heatingSetpoint, coolingSetpoint,
* | | setCoolingSetpoint, | thermostatSetpoint, thermostatMode,
* | | off, heat, cool, auto,| thermostatFanMode, thermostatOperatingState
* | | emergencyHeat, |
* | | setThermostatMode, |
* | | fanOn, fanAuto, |
* | | fanCirculate, |
* | | setThermostatFanMode |
* --------------------+---------------+-----------------------+------------------------------------
*/
//Device Inputs
preferences {
section("Allow OpenT2T to control these things...") {
input "contactSensors", "capability.contactSensor", title: "Which Contact Sensors", multiple: true, required: false, hideWhenEmpty: true
input "garageDoors", "capability.garageDoorControl", title: "Which Garage Doors?", multiple: true, required: false, hideWhenEmpty: true
input "locks", "capability.lock", title: "Which Locks?", multiple: true, required: false, hideWhenEmpty: true
input "cameras", "capability.videoCapture", title: "Which Cameras?", multiple: true, required: false, hideWhenEmpty: true
input "motionSensors", "capability.motionSensor", title: "Which Motion Sensors?", multiple: true, required: false, hideWhenEmpty: true
input "presenceSensors", "capability.presenceSensor", title: "Which Presence Sensors", multiple: true, required: false, hideWhenEmpty: true
input "switches", "capability.switch", title: "Which Switches and Lights?", multiple: true, required: false, hideWhenEmpty: true
input "thermostats", "capability.thermostat", title: "Which Thermostat?", multiple: true, required: false, hideWhenEmpty: true
input "waterSensors", "capability.waterSensor", title: "Which Water Leak Sensors?", multiple: true, required: false, hideWhenEmpty: true
}
}
def getInputs() {
def inputList = []
inputList += contactSensors?: []
inputList += garageDoors?: []
inputList += locks?: []
inputList += cameras?: []
inputList += motionSensors?: []
inputList += presenceSensors?: []
inputList += switches?: []
inputList += thermostats?: []
inputList += waterSensors?: []
return inputList
}
//API external Endpoints
mappings {
path("/devices") {
action: [
GET: "getDevices"
]
}
path("/devices/:id") {
action: [
GET: "getDevice"
]
}
path("/update/:id") {
action: [
PUT: "updateDevice"
]
}
path("/deviceSubscription") {
action: [
POST: "registerDeviceChange",
DELETE: "unregisterDeviceChange"
]
}
path("/locationSubscription") {
action: [
POST: "registerDeviceGraph",
DELETE: "unregisterDeviceGraph"
]
}
}
def installed() {
log.debug "Installing with settings: ${settings}"
initialize()
}
def updated() {
log.debug "Updating with settings: ${settings}"
//Initialize state variables if didn't exist.
if( state.deviceSubscriptionMap == null ){
state.deviceSubscriptionMap = [:]
log.debug "deviceSubscriptionMap created."
}
if( state.locationSubscriptionMap == null ){
state.locationSubscriptionMap = [:]
log.debug "locationSubscriptionMap created."
}
if(state.verificationKeyMap == null){
state.verificationKeyMap = [:]
log.debug "verificationKeyMap created."
}
unsubscribe()
registerAllDeviceSubscriptions()
}
def initialize() {
log.debug "Initializing with settings: ${settings}"
state.deviceSubscriptionMap = [:]
log.debug "deviceSubscriptionMap created."
state.locationSubscriptionMap = [:]
log.debug "locationSubscriptionMap created."
state.verificationKeyMap = [:]
log.debug "verificationKeyMap created."
registerAllDeviceSubscriptions()
}
/*** Subscription Functions ***/
//Subscribe events for all devices
def registerAllDeviceSubscriptions() {
registerChangeHandler(inputs)
}
//Subscribe to events from a list of devices
def registerChangeHandler(myList) {
myList.each { myDevice ->
def theAtts = myDevice.supportedAttributes
theAtts.each {att ->
subscribe(myDevice, att.name, deviceEventHandler)
log.info "Registering for ${myDevice.displayName}.${att.name}"
}
}
}
//Endpoints function: Subscribe to events from a specific device
def registerDeviceChange() {
def subscriptionEndpt = params.subscriptionURL
def deviceId = params.deviceId
def myDevice = findDevice(deviceId)
if( myDevice == null ){
httpError(404, "Cannot find device with device ID ${deviceId}.")
}
def theAtts = myDevice.supportedAttributes
try {
theAtts.each {att ->
subscribe(myDevice, att.name, deviceEventHandler)
}
log.info "Subscribing for ${myDevice.displayName}"
if(subscriptionEndpt != null){
if(state.deviceSubscriptionMap[deviceId] == null){
state.deviceSubscriptionMap.put(deviceId, [subscriptionEndpt])
log.info "Added subscription URL: ${subscriptionEndpt} for ${myDevice.displayName}"
} else if (!state.deviceSubscriptionMap[deviceId].contains(subscriptionEndpt)){
// state.deviceSubscriptionMap[deviceId] << subscriptionEndpt
// For now, we will only have one subscription endpoint per device
state.deviceSubscriptionMap.remove(deviceId)
state.deviceSubscriptionMap.put(deviceId, [subscriptionEndpt])
log.info "Added subscription URL: ${subscriptionEndpt} for ${myDevice.displayName}"
}
if(params.key != null){
state.verificationKeyMap[subscriptionEndpt] = params.key
log.info "Added verification key: ${params.key} for ${subscriptionEndpt}"
}
}
} catch (e) {
httpError(500, "something went wrong: $e")
}
log.info "Current subscription map is ${state.deviceSubscriptionMap}"
log.info "Current verification key map is ${state.verificationKeyMap}"
return ["succeed"]
}
//Endpoints function: Unsubscribe to events from a specific device
def unregisterDeviceChange() {
def subscriptionEndpt = params.subscriptionURL
def deviceId = params.deviceId
def myDevice = findDevice(deviceId)
if( myDevice == null ){
httpError(404, "Cannot find device with device ID ${deviceId}.")
}
try {
if(subscriptionEndpt != null && subscriptionEndpt != "undefined"){
if (state.deviceSubscriptionMap[deviceId]?.contains(subscriptionEndpt)){
if(state.deviceSubscriptionMap[deviceId].size() == 1){
state.deviceSubscriptionMap.remove(deviceId)
} else {
state.deviceSubscriptionMap[deviceId].remove(subscriptionEndpt)
}
state.verificationKeyMap.remove(subscriptionEndpt)
log.info "Removed subscription URL: ${subscriptionEndpt} for ${myDevice.displayName}"
}
} else {
state.deviceSubscriptionMap.remove(deviceId)
log.info "Unsubscriping for ${myDevice.displayName}"
}
} catch (e) {
httpError(500, "something went wrong: $e")
}
log.info "Current subscription map is ${state.deviceSubscriptionMap}"
log.info "Current verification key map is ${state.verificationKeyMap}"
}
//Endpoints function: Subscribe to device additiona/removal updated in a location
def registerDeviceGraph() {
def subscriptionEndpt = params.subscriptionURL
if (subscriptionEndpt != null && subscriptionEndpt != "undefined"){
subscribe(location, "DeviceCreated", locationEventHandler, [filterEvents: false])
subscribe(location, "DeviceUpdated", locationEventHandler, [filterEvents: false])
subscribe(location, "DeviceDeleted", locationEventHandler, [filterEvents: false])
if(state.locationSubscriptionMap[location.id] == null){
state.locationSubscriptionMap.put(location.id, [subscriptionEndpt])
log.info "Added subscription URL: ${subscriptionEndpt} for Location ${location.name}"
}else if (!state.locationSubscriptionMap[location.id].contains(subscriptionEndpt)){
state.locationSubscriptionMap[location.id] << subscriptionEndpt
log.info "Added subscription URL: ${subscriptionEndpt} for Location ${location.name}"
}
if(params.key != null){
state.verificationKeyMap[subscriptionEndpt] = params.key
log.info "Added verification key: ${params.key} for ${subscriptionEndpt}"
}
log.info "Current location subscription map is ${state.locationSubscriptionMap}"
log.info "Current verification key map is ${state.verificationKeyMap}"
return ["succeed"]
} else {
httpError(400, "missing input parameter: subscriptionURL")
}
}
//Endpoints function: Unsubscribe to events from a specific device
def unregisterDeviceGraph() {
def subscriptionEndpt = params.subscriptionURL
try {
if(subscriptionEndpt != null && subscriptionEndpt != "undefined"){
if (state.locationSubscriptionMap[location.id]?.contains(subscriptionEndpt)){
if(state.locationSubscriptionMap[location.id].size() == 1){
state.locationSubscriptionMap.remove(location.id)
} else {
state.locationSubscriptionMap[location.id].remove(subscriptionEndpt)
}
state.verificationKeyMap.remove(subscriptionEndpt)
log.info "Removed subscription URL: ${subscriptionEndpt} for Location ${location.name}"
}
}else{
httpError(400, "missing input parameter: subscriptionURL")
}
} catch (e) {
httpError(500, "something went wrong: $e")
}
log.info "Current location subscription map is ${state.locationSubscriptionMap}"
log.info "Current verification key map is ${state.verificationKeyMap}"
}
//When events are triggered, send HTTP post to web socket servers
def deviceEventHandler(evt) {
def evtDevice = evt.device
def evtDeviceType = getDeviceType(evtDevice)
def deviceData = [];
if(evt.data != null){
def evtData = parseJson(evt.data)
log.info "Received event for ${evtDevice.displayName}, data: ${evtData}, description: ${evt.descriptionText}"
}
if(evtDeviceType == "thermostat") {
deviceData = [name: evtDevice.displayName, id: evtDevice.id, status:evtDevice.status, deviceType:evtDeviceType, manufacturer:evtDevice.manufacturerName, model:evtDevice.modelName, attributes: deviceAttributeList(evtDevice, evtDeviceType), locationMode: getLocationModeInfo(), locationId: location.id ]
} else {
deviceData = [name: evtDevice.displayName, id: evtDevice.id, status:evtDevice.status, deviceType:evtDeviceType, manufacturer:evtDevice.manufacturerName, model:evtDevice.modelName, attributes: deviceAttributeList(evtDevice, evtDeviceType), locationId: location.id ]
}
def params = [ body: deviceData ]
//send event to all subscriptions urls
log.debug "Current subscription urls for ${evtDevice.displayName} is ${state.deviceSubscriptionMap[evtDevice.id]}"
state.deviceSubscriptionMap[evtDevice.id].each {
params.uri = "${it}"
if(state.verificationKeyMap[it] != null ){
def key = state.verificationKeyMap[it]
params.header = [Signature: ComputHMACValue(key, groovy.json.JsonOutput.toJson(params.body))]
}
log.trace "POST URI: ${params.uri}"
log.trace "Header: ${params.header}"
log.trace "Payload: ${params.body}"
try{
httpPostJson(params) { resp ->
log.trace "response status code: ${resp.status}"
log.trace "response data: ${resp.data}"
}
} catch (e) {
log.error "something went wrong: $e"
}
}
}
def locationEventHandler(evt) {
log.info "Received event for location ${location.name}/${location.id}, Event: ${evt.name}, description: ${evt.descriptionText}, apiServerUrl: ${apiServerUrl("")}"
switch(evt.name){
case "DeviceCreated":
case "DeviceDeleted":
def evtDevice = evt.device
def evtDeviceType = getDeviceType(evtDevice)
def params = [ body: [ eventType:evt.name, deviceId: evtDevice.id, locationId: location.id ] ]
if (evt.name == "DeviceDeleted" && state.deviceSubscriptionMap[deviceId] != null){
state.deviceSubscriptionMap.remove(evtDevice.id)
}
state.locationSubscriptionMap[location.id].each {
params.uri = "${it}"
if(state.verificationKeyMap[it] != null ){
def key = state.verificationKeyMap[it]
params.header = [Signature: ComputHMACValue(key, groovy.json.JsonOutput.toJson(params.body))]
}
log.trace "POST URI: ${params.uri}"
log.trace "Header: ${params.header}"
log.trace "Payload: ${params.body}"
try{
httpPostJson(params) { resp ->
log.trace "response status code: ${resp.status}"
log.trace "response data: ${resp.data}"
}
} catch (e) {
log.error "something went wrong: $e"
}
}
case "DeviceUpdated":
default:
break
}
}
private ComputHMACValue(key, data){
try {
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA1")
Mac mac = Mac.getInstance("HmacSHA1")
mac.init(secretKeySpec)
byte[] digest = mac.doFinal(data.getBytes("UTF-8"))
return byteArrayToString(digest)
} catch (InvalidKeyException e) {
log.error "Invalid key exception while converting to HMac SHA1"
}
}
private def byteArrayToString(byte[] data) {
BigInteger bigInteger = new BigInteger(1, data)
String hash = bigInteger.toString(16)
return hash
}
/*** Device Query/Update Functions ***/
//Endpoints function: return all device data in json format
def getDevices() {
def deviceData = []
inputs?.each {
def deviceType = getDeviceType(it)
if(deviceType == "thermostat") {
deviceData << [name: it.displayName, id: it.id, status:it.status, deviceType:deviceType, manufacturer:it.manufacturerName, model:it.modelName, attributes: deviceAttributeList(it, deviceType), locationMode: getLocationModeInfo()]
} else {
deviceData << [name: it.displayName, id: it.id, status:it.status, deviceType:deviceType, manufacturer:it.manufacturerName, model:it.modelName, attributes: deviceAttributeList(it, deviceType)]
}
}
log.debug "getDevices, return: ${deviceData}"
return deviceData
}
//Endpoints function: get device data
def getDevice() {
def it = findDevice(params.id)
def deviceType = getDeviceType(it)
def device
if(deviceType == "thermostat") {
device = [name: it.displayName, id: it.id, status:it.status, deviceType:deviceType, manufacturer:it.manufacturerName, model:it.modelName, attributes: deviceAttributeList(it,deviceType), locationMode: getLocationModeInfo()]
} else {
device = [name: it.displayName, id: it.id, status:it.status, deviceType:deviceType, manufacturer:it.manufacturerName, model:it.modelName, attributes: deviceAttributeList(it, deviceType)]
}
log.debug "getDevice, return: ${device}"
return device
}
//Endpoints function: update device data
void updateDevice() {
def device = findDevice(params.id)
request.JSON.each {
def command = it.key
def value = it.value
if (command){
def commandList = mapDeviceCommands(command, value)
command = commandList[0]
value = commandList[1]
if (command == "setAwayMode") {
log.info "Setting away mode to ${value}"
if (location.modes?.find {it.name == value}) {
location.setMode(value)
}
}else if (command == "thermostatSetpoint"){
switch(device.currentThermostatMode){
case "cool":
log.info "Update: ${device.displayName}, [${command}, ${value}]"
device.setCoolingSetpoint(value)
break
case "heat":
case "emergency heat":
log.info "Update: ${device.displayName}, [${command}, ${value}]"
device.setHeatingSetpoint(value)
break
default:
httpError(501, "this mode: ${device.currentThermostatMode} does not allow changing thermostat setpoint.")
break
}
}else if (!device) {
log.error "updateDevice, Device not found"
httpError(404, "Device not found")
} else if (!device.hasCommand(command)) {
log.error "updateDevice, Device does not have the command"
httpError(404, "Device does not have such command")
} else {
if (command == "setColor") {
log.info "Update: ${device.displayName}, [${command}, ${value}]"
device."$command"(hex: value)
} else if(value.isNumber()) {
def intValue = value as Integer
log.info "Update: ${device.displayName}, [${command}, ${intValue}(int)]"
device."$command"(intValue)
} else if (value){
log.info "Update: ${device.displayName}, [${command}, ${value}]"
device."$command"(value)
} else {
log.info "Update: ${device.displayName}, [${command}]"
device."$command"()
}
}
}
}
}
/*** Private Functions ***/
//Return current location mode info
private getLocationModeInfo() {
return [mode: location.mode, supported: location.modes.name]
}
//Map each device to a type given it's capabilities
private getDeviceType(device) {
def deviceType
def capabilities = device.capabilities
log.debug "capabilities: [${device}, ${capabilities}]"
log.debug "supported commands: [${device}, ${device.supportedCommands}]"
//Loop through the device capability list to determine the device type.
capabilities.each {capability ->
switch(capability.name.toLowerCase())
{
case "switch":
deviceType = "switch"
//If the device also contains "Switch Level" capability, identify it as a "light" device.
if (capabilities.any{it.name.toLowerCase() == "switch level"}){
//If the device also contains "Power Meter" capability, identify it as a "dimmerSwitch" device.
if (capabilities.any{it.name.toLowerCase() == "power meter"}){
deviceType = "dimmerSwitch"
return deviceType
} else {
deviceType = "light"
return deviceType
}
}
break
case "garageDoorControl":
deviceType = "garageDoor"
return deviceType
case "lock":
deviceType = "lock"
return deviceType
case "video camera":
deviceType = "camera"
return deviceType
case "thermostat":
deviceType = "thermostat"
return deviceType
case "acceleration sensor":
case "contact sensor":
case "motion sensor":
case "presence sensor":
case "water sensor":
deviceType = "genericSensor"
return deviceType
default:
break
}
}
return deviceType
}
//Return a specific device give the device ID.
private findDevice(deviceId) {
return inputs?.find { it.id == deviceId }
}
//Return a list of device attributes
private deviceAttributeList(device, deviceType) {
def attributeList = [:]
def allAttributes = device.supportedAttributes
allAttributes.each { attribute ->
try {
def currentState = device.currentState(attribute.name)
if(currentState != null ){
switch(attribute.name){
case 'temperature':
attributeList.putAll([ (attribute.name): currentState.value, 'temperatureScale':location.temperatureScale ])
break;
default:
attributeList.putAll([(attribute.name): currentState.value ])
break;
}
if( deviceType == "genericSensor" ){
def key = attribute.name + "_lastUpdated"
attributeList.putAll([ (key): currentState.isoDate ])
}
} else {
attributeList.putAll([ (attribute.name): null ]);
}
} catch(e) {
attributeList.putAll([ (attribute.name): null ]);
}
}
return attributeList
}
//Map device command and value.
//input command and value are from UWP,
//returns resultCommand and resultValue that corresponds with function and value in SmartApps
private mapDeviceCommands(command, value) {
log.debug "mapDeviceCommands: [${command}, ${value}]"
def resultCommand = command
def resultValue = value
switch (command) {
case "switch":
if (value == 1 || value == "1" || value == "on") {
resultCommand = "on"
resultValue = ""
} else if (value == 0 || value == "0" || value == "off") {
resultCommand = "off"
resultValue = ""
}
break
// light attributes
case "level":
resultCommand = "setLevel"
resultValue = value
break
case "hue":
resultCommand = "setHue"
resultValue = value
break
case "saturation":
resultCommand = "setSaturation"
resultValue = value
break
case "colorTemperature":
resultCommand = "setColorTemperature"
resultValue = value
break
case "color":
resultCommand = "setColor"
resultValue = value
// thermostat attributes
case "hvacMode":
resultCommand = "setThermostatMode"
resultValue = value
break
case "fanMode":
resultCommand = "setThermostatFanMode"
resultValue = value
break
case "awayMode":
resultCommand = "setAwayMode"
resultValue = value
break
case "coolingSetpoint":
resultCommand = "setCoolingSetpoint"
resultValue = value
break
case "heatingSetpoint":
resultCommand = "setHeatingSetpoint"
resultValue = value
break
case "thermostatSetpoint":
resultCommand = "thermostatSetpoint"
resultValue = value
break
// lock attributes
case "locked":
if (value == 1 || value == "1" || value == "lock") {
resultCommand = "lock"
resultValue = ""
}
else if (value == 0 || value == "0" || value == "unlock") {
resultCommand = "unlock"
resultValue = ""
}
break
default:
break
}
return [resultCommand,resultValue]
}

View File

@@ -516,7 +516,7 @@ def pollResponse(response, data) {
def hub = getChildDevice("harmony-${it.key}") def hub = getChildDevice("harmony-${it.key}")
if (hub) { if (hub) {
if (it.value.response.data.currentAvActivity == "-1") { if (it.value.response.data.currentAvActivity == "-1") {
hub.sendEvent(name: "currentActivity", value: "--", descriptionText: "There isn't any activity running", display: false) hub.sendEvent(name: "currentActivity", value: "--", descriptionText: "There isn't any activity running", displayed: false)
} else { } else {
def currentActivity def currentActivity
def activityDTH = getChildDevice("harmony-${it.key}-${it.value.response.data.currentAvActivity}") def activityDTH = getChildDevice("harmony-${it.key}-${it.value.response.data.currentAvActivity}")
@@ -524,7 +524,7 @@ def pollResponse(response, data) {
currentActivity = activityDTH.device.displayName currentActivity = activityDTH.device.displayName
else else
currentActivity = getActivityName(it.value.response.data.currentAvActivity,it.key) currentActivity = getActivityName(it.value.response.data.currentAvActivity,it.key)
hub.sendEvent(name: "currentActivity", value: currentActivity, descriptionText: "Current activity is ${currentActivity}", display: false) hub.sendEvent(name: "currentActivity", value: currentActivity, descriptionText: "Current activity is ${currentActivity}", displayed: false)
} }
} }
} else { } else {
@@ -576,7 +576,7 @@ def getActivityList() {
} }
activities += [id: "off", name: "Activity OFF", type: "0"] activities += [id: "off", name: "Activity OFF", type: "0"]
} }
hub.sendEvent(name: "activities", value: new groovy.json.JsonBuilder(activities).toString(), descriptionText: "Activities are ${activities.collect { it.name }?.join(', ')}", display: false) hub.sendEvent(name: "activities", value: new groovy.json.JsonBuilder(activities).toString(), descriptionText: "Activities are ${activities.collect { it.name }?.join(', ')}", displayed: false)
} }
} }
} }