Compare commits

..

1 Commits

Author SHA1 Message Date
Marco
0a5c8c75a3 MSA-1947: . 2017-05-02 13:45:01 -07:00
9 changed files with 114 additions and 506 deletions

View File

@@ -1,5 +1,5 @@
/**
* Copyright 2017 SmartThings
* Copyright 2016 SmartThings
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at:
@@ -64,7 +64,6 @@ private getATTRIBUTE_HUE() { 0x0000 }
private getATTRIBUTE_SATURATION() { 0x0001 }
private getHUE_COMMAND() { 0x00 }
private getSATURATION_COMMAND() { 0x03 }
private getMOVE_TO_HUE_AND_SATURATION_COMMAND() { 0x06 }
private getCOLOR_CONTROL_CLUSTER() { 0x0300 }
// Parse incoming device messages to generate events
@@ -85,11 +84,11 @@ def parse(String description) {
if (zigbeeMap?.clusterInt == COLOR_CONTROL_CLUSTER) {
if(zigbeeMap.attrInt == ATTRIBUTE_HUE){ //Hue Attribute
def hueValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 0xfe * 100)
def hueValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 255 * 100)
sendEvent(name: "hue", value: hueValue, descriptionText: "Color has changed")
}
else if(zigbeeMap.attrInt == ATTRIBUTE_SATURATION){ //Saturation Attribute
def saturationValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 0xfe * 100)
def saturationValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 255 * 100)
sendEvent(name: "saturation", value: saturationValue, descriptionText: "Color has changed", displayed: false)
}
}
@@ -124,12 +123,7 @@ def ping() {
}
def refresh() {
zigbee.onOffRefresh() +
zigbee.levelRefresh() +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION) +
zigbee.onOffConfig(0, 300) +
zigbee.levelConfig()
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION) + zigbee.onOffConfig(0, 300) + zigbee.levelConfig() + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE, DataType.UINT8, 1, 3600, 0x01) + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION, DataType.UINT8, 1, 3600, 0x01)
}
def configure() {
@@ -139,38 +133,26 @@ def configure() {
sendEvent(name: "checkInterval", value: 3 * 10 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
// OnOff minReportTime 0 seconds, maxReportTime 5 min. Reporting interval if no activity
refresh()
zigbee.onOffConfig(0, 300) + zigbee.levelConfig() + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE, DataType.UINT8, 1, 3600, 0x01) + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION, DataType.UINT8, 1, 3600, 0x01) + zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
}
def setLevel(value) {
zigbee.setLevel(value)
}
private getScaledHue(value) {
zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
}
private getScaledSaturation(value) {
zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
}
def setColor(value){
log.trace "setColor($value)"
zigbee.on() +
zigbee.command(COLOR_CONTROL_CLUSTER, MOVE_TO_HUE_AND_SATURATION_COMMAND,
getScaledHue(value.hue), getScaledSaturation(value.saturation), "0000") +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
zigbee.on() + setHue(value.hue) + "delay 500" + setSaturation(value.saturation)
}
def setHue(value) {
zigbee.command(COLOR_CONTROL_CLUSTER, HUE_COMMAND, getScaledHue(value), "00", "0000") +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE)
def scaledHueValue = zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
zigbee.command(COLOR_CONTROL_CLUSTER, HUE_COMMAND, scaledHueValue, "00", "0500") //payload-> hue value, direction (00-> shortest distance), transition time (1/10th second) (0500 in U16 reads 5)
}
def setSaturation(value) {
zigbee.command(COLOR_CONTROL_CLUSTER, SATURATION_COMMAND, getScaledSaturation(value), "0000") +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
def scaledSatValue = zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
zigbee.command(COLOR_CONTROL_CLUSTER, SATURATION_COMMAND, scaledSatValue, "0500") + "delay 1000" + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
}
def installed() {
@@ -179,4 +161,4 @@ def installed() {
sendEvent(name: "level", value: 100)
}
}
}
}

View File

@@ -1,5 +1,5 @@
/**
* Copyright 2017 SmartThings
* Copyright 2016 SmartThings
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at:
@@ -78,7 +78,6 @@ private getATTRIBUTE_HUE() { 0x0000 }
private getATTRIBUTE_SATURATION() { 0x0001 }
private getHUE_COMMAND() { 0x00 }
private getSATURATION_COMMAND() { 0x03 }
private getMOVE_TO_HUE_AND_SATURATION_COMMAND() { 0x06 }
private getCOLOR_CONTROL_CLUSTER() { 0x0300 }
private getATTRIBUTE_COLOR_TEMPERATURE() { 0x0007 }
@@ -103,11 +102,11 @@ def parse(String description) {
if (zigbeeMap?.clusterInt == COLOR_CONTROL_CLUSTER) {
if(zigbeeMap.attrInt == ATTRIBUTE_HUE){ //Hue Attribute
def hueValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 0xfe * 100)
def hueValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 255 * 100)
sendEvent(name: "hue", value: hueValue, descriptionText: "Color has changed")
}
else if(zigbeeMap.attrInt == ATTRIBUTE_SATURATION){ //Saturation Attribute
def saturationValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 0xfe * 100)
def saturationValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 255 * 100)
sendEvent(name: "saturation", value: saturationValue, descriptionText: "Color has changed", displayed: false)
}
}
@@ -142,13 +141,7 @@ def ping() {
}
def refresh() {
zigbee.onOffRefresh() +
zigbee.levelRefresh() +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_COLOR_TEMPERATURE) +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION) +
zigbee.onOffConfig(0, 300) +
zigbee.levelConfig()
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_COLOR_TEMPERATURE) + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION) + zigbee.onOffConfig(0, 300) + zigbee.levelConfig() + zigbee.colorTemperatureConfig() + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE, DataType.UINT8, 1, 3600, 0x01) + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION, DataType.UINT8, 1, 3600, 0x01)
}
def configure() {
@@ -163,12 +156,7 @@ def configure() {
def setColorTemperature(value) {
setGenericName(value)
value = value as Integer
def tempInMired = (1000000 / value) as Integer
def finalHex = zigbee.swapEndianHex(zigbee.convertToHexString(tempInMired, 4))
zigbee.command(COLOR_CONTROL_CLUSTER, 0x0A, "$finalHex 0000") +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_COLOR_TEMPERATURE)
zigbee.setColorTemperature(value)
}
//Naming based on the wiki article here: http://en.wikipedia.org/wiki/Color_temperature
@@ -192,31 +180,19 @@ def setLevel(value) {
zigbee.setLevel(value)
}
private getScaledHue(value) {
zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
}
private getScaledSaturation(value) {
zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
}
def setColor(value){
log.trace "setColor($value)"
zigbee.on() +
zigbee.command(COLOR_CONTROL_CLUSTER, MOVE_TO_HUE_AND_SATURATION_COMMAND,
getScaledHue(value.hue), getScaledSaturation(value.saturation), "0000") +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
zigbee.on() + setHue(value.hue) + "delay 300" + setSaturation(value.saturation)
}
def setHue(value) {
zigbee.command(COLOR_CONTROL_CLUSTER, HUE_COMMAND, getScaledHue(value), "00", "0000") +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE)
def scaledHueValue = zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
zigbee.command(COLOR_CONTROL_CLUSTER, HUE_COMMAND, scaledHueValue, "00", "0500") //payload-> hue value, direction (00-> shortest distance), transition time (1/10th second) (0500 in U16 reads 5)
}
def setSaturation(value) {
zigbee.command(COLOR_CONTROL_CLUSTER, SATURATION_COMMAND, getScaledSaturation(value), "0000") +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
def scaledSatValue = zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
zigbee.command(COLOR_CONTROL_CLUSTER, SATURATION_COMMAND, scaledSatValue, "0500") + "delay 1000" + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
}
def installed() {
@@ -225,4 +201,4 @@ def installed() {
sendEvent(name: "level", value: 100)
}
}
}
}

View File

@@ -1,5 +1,5 @@
/**
* Copyright 2017 SmartThings
* Copyright 2015 SmartThings
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at:
@@ -71,11 +71,6 @@ metadata {
}
}
// Globals
private getMOVE_TO_COLOR_TEMPERATURE_COMMAND() { 0x0A }
private getCOLOR_CONTROL_CLUSTER() { 0x0300 }
private getATTRIBUTE_COLOR_TEMPERATURE() { 0x0007 }
// Parse incoming device messages to generate events
def parse(String description) {
log.debug "description is $description"
@@ -128,11 +123,7 @@ def ping() {
}
def refresh() {
zigbee.onOffRefresh() +
zigbee.levelRefresh() +
zigbee.colorTemperatureRefresh() +
zigbee.onOffConfig(0, 300) +
zigbee.levelConfig()
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh() + zigbee.onOffConfig(0, 300) + zigbee.levelConfig() + zigbee.colorTemperatureConfig()
}
def configure() {
@@ -147,12 +138,7 @@ def configure() {
def setColorTemperature(value) {
setGenericName(value)
value = value as Integer
def tempInMired = (1000000 / value) as Integer
def finalHex = zigbee.swapEndianHex(zigbee.convertToHexString(tempInMired, 4))
zigbee.command(COLOR_CONTROL_CLUSTER, MOVE_TO_COLOR_TEMPERATURE_COMMAND, "$finalHex 0000") +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_COLOR_TEMPERATURE)
zigbee.setColorTemperature(value)
}
//Naming based on the wiki article here: http://en.wikipedia.org/wiki/Color_temperature

View File

@@ -1,5 +1,5 @@
/**
* Copyright 2017 SmartThings
* Copyright 2016 SmartThings
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at:
@@ -55,7 +55,6 @@ private getATTRIBUTE_HUE() { 0x0000 }
private getATTRIBUTE_SATURATION() { 0x0001 }
private getHUE_COMMAND() { 0x00 }
private getSATURATION_COMMAND() { 0x03 }
private getMOVE_TO_HUE_AND_SATURATION_COMMAND() { 0x06 }
private getCOLOR_CONTROL_CLUSTER() { 0x0300 }
// Parse incoming device messages to generate events
@@ -73,11 +72,11 @@ def parse(String description) {
if (zigbeeMap?.clusterInt == COLOR_CONTROL_CLUSTER) {
if(zigbeeMap.attrInt == ATTRIBUTE_HUE){ //Hue Attribute
def hueValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 0xfe * 100)
def hueValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 255 * 360)
sendEvent(name: "hue", value: hueValue, displayed:false)
}
else if(zigbeeMap.attrInt == ATTRIBUTE_SATURATION){ //Saturation Attribute
def saturationValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 0xfe * 100)
def saturationValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 255 * 100)
sendEvent(name: "saturation", value: saturationValue, displayed:false)
}
}
@@ -109,46 +108,28 @@ def configure() {
}
def configureAttributes() {
zigbee.onOffConfig() +
zigbee.levelConfig()
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE, DataType.UINT8, 1, 3600, 0x01) + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION, DataType.UINT8, 1, 3600, 0x01)
}
def refreshAttributes() {
zigbee.onOffRefresh() +
zigbee.levelRefresh() +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
}
def setLevel(value) {
zigbee.setLevel(value) + zigbee.onOffRefresh() + zigbee.levelRefresh() //adding refresh because of ZLL bulb not conforming to send-me-a-report
}
private getScaledHue(value) {
zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
}
private getScaledSaturation(value) {
zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
}
def setColor(value){
log.trace "setColor($value)"
zigbee.on() +
zigbee.command(COLOR_CONTROL_CLUSTER, MOVE_TO_HUE_AND_SATURATION_COMMAND,
getScaledHue(value.hue), getScaledSaturation(value.saturation), "0000") +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
zigbee.on() + setHue(value.hue) + ["delay 300"] + setSaturation(value.saturation) + ["delay 2000"] + refreshAttributes()
}
def setHue(value) {
//payload-> hue value, direction (00-> shortest distance), transition time (1/10th second)
zigbee.command(COLOR_CONTROL_CLUSTER, HUE_COMMAND, getScaledHue(value), "00", "0000") +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE)
def scaledHueValue = zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
zigbee.command(COLOR_CONTROL_CLUSTER, HUE_COMMAND, scaledHueValue, "00", "0500") + ["delay 1500"] + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) //payload-> hue value, direction (00-> shortest distance), transition time (1/10th second) (0500 in U16 reads 5)
}
def setSaturation(value) {
//payload-> sat value, transition time
zigbee.command(COLOR_CONTROL_CLUSTER, SATURATION_COMMAND, getScaledSaturation(value), "0000") +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
def scaledSatValue = zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
zigbee.command(COLOR_CONTROL_CLUSTER, SATURATION_COMMAND, scaledSatValue, "0500") + ["delay 1500"] + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION) //payload-> sat value, transition time
}

View File

@@ -1,5 +1,5 @@
/**
* Copyright 2017 SmartThings
* Copyright 2016 SmartThings
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at:
@@ -70,7 +70,6 @@ private getATTRIBUTE_HUE() { 0x0000 }
private getATTRIBUTE_SATURATION() { 0x0001 }
private getHUE_COMMAND() { 0x00 }
private getSATURATION_COMMAND() { 0x03 }
private getMOVE_TO_HUE_AND_SATURATION_COMMAND() { 0x06 }
private getCOLOR_CONTROL_CLUSTER() { 0x0300 }
private getATTRIBUTE_COLOR_TEMPERATURE() { 0x0007 }
@@ -89,11 +88,11 @@ def parse(String description) {
if (zigbeeMap?.clusterInt == COLOR_CONTROL_CLUSTER) {
if(zigbeeMap.attrInt == ATTRIBUTE_HUE){ //Hue Attribute
def hueValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 0xfe * 100)
def hueValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 255 * 360)
sendEvent(name: "hue", value: hueValue, displayed:false)
}
else if(zigbeeMap.attrInt == ATTRIBUTE_SATURATION){ //Saturation Attribute
def saturationValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 0xfe * 100)
def saturationValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 255 * 100)
sendEvent(name: "saturation", value: saturationValue, displayed:false)
}
}
@@ -125,16 +124,11 @@ def configure() {
}
def configureAttributes() {
zigbee.onOffConfig() +
zigbee.levelConfig()
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig() + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE, DataType.UINT8, 1, 3600, 0x01) + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION, DataType.UINT8, 1, 3600, 0x01)
}
def refreshAttributes() {
zigbee.onOffRefresh() +
zigbee.levelRefresh() +
zigbee.colorTemperatureRefresh() +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh() + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
}
def setColorTemperature(value) {
@@ -145,32 +139,17 @@ def setLevel(value) {
zigbee.setLevel(value) + zigbee.onOffRefresh() + zigbee.levelRefresh() //adding refresh because of ZLL bulb not conforming to send-me-a-report
}
private getScaledHue(value) {
zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
}
private getScaledSaturation(value) {
zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
}
def setColor(value){
log.trace "setColor($value)"
zigbee.on() +
zigbee.command(COLOR_CONTROL_CLUSTER, MOVE_TO_HUE_AND_SATURATION_COMMAND,
getScaledHue(value.hue), getScaledSaturation(value.saturation), "0000") +
zigbee.onOffRefresh() +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
zigbee.on() + setHue(value.hue) + ["delay 300"] + setSaturation(value.saturation) + ["delay 2000"] + refreshAttributes()
}
def setHue(value) {
//payload-> hue value, direction (00-> shortest distance), transition time (1/10th second)
zigbee.command(COLOR_CONTROL_CLUSTER, HUE_COMMAND, getScaledHue(value), "00", "0000") +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE)
def scaledHueValue = zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
zigbee.command(COLOR_CONTROL_CLUSTER, HUE_COMMAND, scaledHueValue, "00", "0500") + ["delay 1500"] + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE) //payload-> hue value, direction (00-> shortest distance), transition time (1/10th second) (0500 in U16 reads 5)
}
def setSaturation(value) {
//payload-> sat value, transition time
zigbee.command(COLOR_CONTROL_CLUSTER, SATURATION_COMMAND, getScaledSaturation(value), "0000") +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION)
def scaledSatValue = zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
zigbee.command(COLOR_CONTROL_CLUSTER, SATURATION_COMMAND, scaledSatValue, "0500") + ["delay 1500"] + zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION) //payload-> sat value, transition time
}

View File

@@ -1,5 +1,5 @@
/**
* Copyright 2017 SmartThings
* Copyright 2016 SmartThings
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at:
@@ -66,11 +66,6 @@ metadata {
}
}
// Globals
private getMOVE_TO_COLOR_TEMPERATURE_COMMAND() { 0x0A }
private getCOLOR_CONTROL_CLUSTER() { 0x0300 }
private getATTRIBUTE_COLOR_TEMPERATURE() { 0x0007 }
// Parse incoming device messages to generate events
def parse(String description) {
log.debug "description is $description"
@@ -100,14 +95,14 @@ def setLevel(value) {
}
def refresh() {
def cmds = zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh()
def cmds = zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh()
// Do NOT config if the device is the Eaton Halo_LT01, it responds with "switch:off" to onOffConfig, and maybe other weird things with the others
// Do NOT config if the device is the Eaton Halo_LT01, it responds with "switch:off" to onOffConfig, and maybe other weird things with the others
if (!((device.getDataValue("manufacturer") == "Eaton") && (device.getDataValue("model") == "Halo_LT01"))) {
cmds += zigbee.onOffConfig() + zigbee.levelConfig()
cmds = cmds + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig()
}
cmds
cmds
}
def poll() {
@@ -143,7 +138,7 @@ def configure() {
log.debug "configure()"
configureHealthCheck()
// Implementation note: for the Eaton Halo_LT01, it responds with "switch:off" to onOffConfig, so be sure this is before the call to onOffRefresh
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh()
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh()
}
def updated() {
@@ -153,12 +148,7 @@ def updated() {
def setColorTemperature(value) {
setGenericName(value)
value = value as Integer
def tempInMired = (1000000 / value) as Integer
def finalHex = zigbee.swapEndianHex(zigbee.convertToHexString(tempInMired, 4))
zigbee.command(COLOR_CONTROL_CLUSTER, MOVE_TO_COLOR_TEMPERATURE_COMMAND, "$finalHex 0000") +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_COLOR_TEMPERATURE)
zigbee.setColorTemperature(value) + ["delay 1500"] + zigbee.colorTemperatureRefresh()
}
//Naming based on the wiki article here: http://en.wikipedia.org/wiki/Color_temperature

View File

@@ -1,5 +1,5 @@
/**
* Copyright 2017 SmartThings
* Copyright 2016 SmartThings
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at:
@@ -68,11 +68,6 @@ metadata {
}
}
// Globals
private getMOVE_TO_COLOR_TEMPERATURE_COMMAND() { 0x0A }
private getCOLOR_CONTROL_CLUSTER() { 0x0300 }
private getATTRIBUTE_COLOR_TEMPERATURE() { 0x0007 }
// Parse incoming device messages to generate events
def parse(String description) {
log.debug "description is $description"
@@ -99,11 +94,7 @@ def setLevel(value) {
}
def refresh() {
zigbee.onOffRefresh() +
zigbee.levelRefresh() +
zigbee.colorTemperatureRefresh() +
zigbee.onOffConfig() +
zigbee.levelConfig()
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh() + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig()
}
def poll() {
@@ -138,7 +129,8 @@ def configureHealthCheck() {
def configure() {
log.debug "configure()"
configureHealthCheck()
refresh()
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh()
}
def updated() {
@@ -148,12 +140,7 @@ def updated() {
def setColorTemperature(value) {
setGenericName(value)
value = value as Integer
def tempInMired = (1000000 / value) as Integer
def finalHex = zigbee.swapEndianHex(zigbee.convertToHexString(tempInMired, 4))
zigbee.command(COLOR_CONTROL_CLUSTER, MOVE_TO_COLOR_TEMPERATURE_COMMAND, "$finalHex 0000") +
zigbee.readAttribute(COLOR_CONTROL_CLUSTER, ATTRIBUTE_COLOR_TEMPERATURE)
zigbee.setColorTemperature(value) + ["delay 1500"] + zigbee.colorTemperatureRefresh()
}
//Naming based on the wiki article here: http://en.wikipedia.org/wiki/Color_temperature

View File

@@ -1,273 +0,0 @@
/**
* Lloyds Banking Group Connect & Protect
*
* Copyright 2016 Domotz
*
* 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: "Lloyds Banking Group Connect & Protect",
namespace: "domotz.dev",
author: "Domotz",
description: "The Lloyds Connect & Protect SmartApp is a bridge between SmartThings Cloud and Lloyds Banking Group to enable advanced connected device monitoring and alerting features to be included in the offering to their customers for the connected home service",
category: "Convenience",
singleInstance: true,
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",
oauth: [displayName: "Lloyds Banking Group Connect & Protect", displayLink: ""]) {
appSetting "endpointRetrievalUrl"
appSetting "xApiKey"
}
def getSupportedTypes() {
return [
[obj: switches, name: "switches", attribute: "switch", capability: "switch", title: "Switches"],
[obj: motions, name: "motions", attribute: "motion", capability: "motionSensor", title: "Motion Sensors"],
[obj: temperature, name: "temperature", attribute: "temperature", capability: "temperatureMeasurement", title: "Temperature Sensors"],
[obj: contact, name: "contact", attribute: "contact", capability: "contactSensor", title: "Contact Sensors"],
[obj: presence, name: "presence", attribute: "presence", capability: "presenceSensor", title: "Presence Sensors"],
[obj: water, name: "water", attribute: "water", capability: "waterSensor", title: "Water Sensors"],
[obj: smoke, name: "smoke", attribute: "smoke", capability: "smokeDetector", title: "Smoke Sensors"],
[obj: battery, name: "battery", attribute: "battery", capability: "battery", title: "Batteries"]
]
}
preferences {
section("Allow Lloyds Banking Group Connect & Protect service to monitor these devices") {
for (type in getSupportedTypes()) {
input type.get("name"), "capability.${type.get('capability')}", title: type.get('title'), multiple: true
}
}
}
def installed() {
initialize()
}
def updated() {
unsubscribe()
initialize()
hubUpdateHandler()
}
def getRequestHeaders() {
return ['Accept': '*/*', 'X-API-KEY': appSettings.xApiKey]
}
def subscribeToDeviceEvents() {
for (type in getSupportedTypes()) {
subscribe(type.get("obj"), "${type.get("attribute")}", genericDeviceEventHandler)
}
}
def initialize() {
if (atomicState.endpoint != null) {
log.debug "Detected endpoint: ${atomicState.endpoint}"
subscribeToDeviceEvents()
subscribe(location, "routineExecuted", modeChangeHandler)
subscribe(location, "mode", modeChangeHandler)
} else {
log.debug "There is no endpoint, requesting domotz for a new one"
requestNewEndpoint()
}
}
def getHubLocation() {
def location_info = [:]
location_info['uid'] = location.id
//location_info['hubs'] = location.hubs
location_info['latitude'] = location.latitude
location_info['longitude'] = location.longitude
location_info['current_mode'] = location.mode
//location_info['modes'] = location.modes
location_info['name'] = location.name
location_info['temperature_scale'] = location.temperatureScale
location_info['version'] = location.version
location_info['channel_name'] = location.channelName
location_info['zip_code'] = location.zipCode
log.debug "Triggered getHubLocation with properties: ${location_info}"
return location_info
}
def modeChangeHandler(evt) {
log.debug "mode changed to ${evt.value}"
def url = null
if (atomicState.endpoint != null) {
url = atomicState.endpoint + '/hub-change'
httpPutJson(
uri: url,
body: getHubLocation(),
headers: getRequestHeaders()
)
} else {
log.debug "There is no endpoint, requesting domotz for a new one"
requestNewEndpoint()
}
}
def genericDeviceEventHandler(event) {
log.debug "Device Event Handler, event properties: ${event.getProperties().toString()}"
log.debug "Device Event Handler, value: ${event.value}"
def resp = [:]
def url = null
def device = null
device = getDevice(event.device, resp)
url = atomicState.endpoint + "/device/" + device.provider_uid + "/${event.name}"
log.debug "Device Event Handler, put url: ${url}"
log.debug "Device Event Handler, put body: value: ${event.value}\ndate: ${event.isoDate}"
httpPutJson(
uri: url,
body: [
"value": event.value,
"time" : event.isoDate
],
headers: getRequestHeaders()
)
}
def hubUpdateHandler() {
log.debug "Hub Update Handler, with settings: ${settings}"
def url = null
def deviceList = [:]
if (atomicState.endpoint != null) {
url = atomicState.endpoint + '/device-list'
log.debug "Hub Update Event Handler, put url: ${url}"
deviceList = getDeviceList()
httpPutJson(
uri: url,
body: deviceList,
headers: getRequestHeaders()
)
} else {
log.debug "There is no endpoint, requesting domotz for a new one"
requestNewEndpoint()
}
}
def getDeviceList() {
try {
def resp = [:]
def attribute = null
for (type in getSupportedTypes()) {
type.get("obj").each {
device = getDevice(it, resp)
attribute = type.get("attribute")
if (it.currentState(attribute)) {
device['attributes'][attribute] = [
"value": it.currentState(attribute).value,
"time" : it.currentState(attribute).getIsoDate(),
"unit" : it.currentState(attribute).unit
]
}
}
}
return resp
} catch (e) {
log.debug("caught exception", e)
return [:]
}
}
def getDevice(it, resp) {
if (resp[it.id]) {
return resp[it.id]
}
resp[it.id] = [name: it.name, display_name: it.displayName, provider_uid: it.id, type: it.typeName, label: it.label, manufacturer_name: it.manufacturerName, model: it.modelName, attributes: [:]]
}
def activateMonitoring(resp) {
unsubscribe()
log.debug "Event monitoring activated for endpoint: ${request.JSON.endpoint}"
atomicState.endpoint = request.JSON.endpoint
log.debug "Event monitoring activated for endpoint: ${atomicState.endpoint}"
initialize()
}
def deactivateMonitoring() {
log.debug "Event monitoring deactivated."
atomicState.endpoint = null
unsubscribe()
}
def requestNewEndpoint() {
log.debug "Requesting a new endpoint."
def hubId = location.id
def params = [
uri : "${appSettings.endpointRetrievalUrl}/${hubId}/endpoint",
headers: getRequestHeaders()
]
try {
httpGet(params) { response ->
log.debug "Request was successful, received endpoint: ${response.data.endpoint}"
atomicState.endpoint = response.data.endpoint
subscribeToDeviceEvents()
}
}
catch (e) {
log.debug "Unable to retrieve the endpoint"
}
}
def handleClientUninstall() {
log.info("Deactivated from client")
try {
app.delete()
} catch (e) {
unschedule()
unsubscribe()
httpError(500, "An error occurred during deleting SmartApp: ${e}")
}
}
mappings {
path("/device") {
action:
[
GET: getDeviceList
]
}
path("/location") {
action:
[
GET: getHubLocation
]
}
path("/monitoring") {
action:
[
POST : activateMonitoring,
DELETE: deactivateMonitoring
]
}
path("/uninstall") {
action
[GET: handleClientUninstall]
}
}

View File

@@ -1,57 +1,57 @@
/**
* Copyright 2015 SmartThings
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
* for the specific language governing permissions and limitations under the License.
*
* Power Allowance
*
* Author: SmartThings
*/
definition(
name: "Power Allowance",
namespace: "smartthings",
author: "SmartThings",
description: "Save energy or restrict total time an appliance (like a curling iron or TV) can be in use. When a switch turns on, automatically turn it back off after a set number of minutes you specify.",
category: "Green Living",
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Meta/light_outlet.png",
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Meta/light_outlet@2x.png"
)
preferences {
section("When a switch turns on...") {
input "theSwitch", "capability.switch"
}
section("Turn it off how many minutes later?") {
input "minutesLater", "number", title: "When?"
}
}
def installed() {
log.debug "Installed with settings: ${settings}"
subscribe(theSwitch, "switch.on", switchOnHandler, [filterEvents: false])
}
def updated() {
log.debug "Updated with settings: ${settings}"
unsubscribe()
subscribe(theSwitch, "switch.on", switchOnHandler, [filterEvents: false])
}
def switchOnHandler(evt) {
log.debug "Switch ${theSwitch} turned: ${evt.value}"
def delay = minutesLater * 60
log.debug "Turning off in ${minutesLater} minutes (${delay}seconds)"
runIn(delay, turnOffSwitch)
}
def turnOffSwitch() {
theSwitch.off()
}
/**
* Copyright 2015 SmartThings
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
* for the specific language governing permissions and limitations under the License.
*
* Power Allowance
*
* Author: SmartThings
*/
definition(
name: "Power Allowance",
namespace: "smartthings",
author: "SmartThings",
description: "Save energy or restrict total time an appliance (like a curling iron or TV) can be in use. When a switch turns on, automatically turn it back off after a set number of minutes you specify.",
category: "Green Living",
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Meta/light_outlet.png",
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Meta/light_outlet@2x.png"
)
preferences {
section("When a switch turns on...") {
input "theSwitch", "capability.switch"
}
section("Turn it off how many minutes later?") {
input "minutesLater", "number", title: "When?"
}
}
def installed() {
log.debug "Installed with settings: ${settings}"
subscribe(theSwitch, "switch.on", switchOnHandler, [filterEvents: false])
}
def updated() {
log.debug "Updated with settings: ${settings}"
unsubscribe()
subscribe(theSwitch, "switch.on", switchOnHandler, [filterEvents: false])
}
def switchOnHandler(evt) {
log.debug "Switch ${theSwitch} turned: ${evt.value}"
def delay = minutesLater * 60
log.debug "Turning off in ${minutesLater} minutes (${delay}seconds)"
runIn(delay, turnOffSwitch)
}
def turnOffSwitch() {
theSwitch.off()
}