Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 119 additions & 9 deletions Improved OSRAM Lightify Gardenspot RGB MA.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,15 @@ metadata {

attribute "colorName", "string"
attribute "switchColor", "string"
attribute "loopActive", "string"
attribute "loopDirection", "string"
attribute "loopTime", "number"

command "setAdjustedColor"
command "startLoop"
command "stopLoop"
command "setLoopTime"
command "setDirection"


fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0008,0300,0B04,FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "Gardenspot RGB"
Expand Down Expand Up @@ -71,6 +78,7 @@ tiles (scale: 2){
attributeState "Deep Pink", label: '${currentValue}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#ff007b"
attributeState "Raspberry", label: '${currentValue}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#ff0061"
attributeState "Crimson", label: '${currentValue}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#ff003b"
attributeState "Color Loop", label: '${currentValue}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821"
}
tileAttribute ("device.color", key: "COLOR_CONTROL") {
attributeState "color", action: "setAdjustedColor"
Expand All @@ -80,24 +88,37 @@ tiles (scale: 2){
}
}
standardTile("refresh", "device.switch", height: 2, width: 2, inactiveLabel: false, decoration: "flat") {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
}
controlTile("levelSliderControl", "device.level", "slider", height: 1, width: 6, inactiveLabel: false) {
state "level", action:"switch level.setLevel"
}
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
}
standardTile("loop", "device.loopActive", height: 2, width: 2, inactiveLabel: false, decoration: "flat") {
state "Active", label:'${currentValue}', action: "stopLoop"
state "Inactive", label:'${currentValue}', action: "startLoop"
}
controlTile("levelSliderControl", "device.level", "slider", height: 1, width: 6, inactiveLabel: false) {
state "level", action:"switch level.setLevel"
}
valueTile("colorName", "device.colorName", height: 2, width: 2, inactiveLabel: false, decoration: "flat") {
state "colorName", label: '${currentValue}'
state "colorName", label: '${currentValue}'
}
controlTile("loopTimeControl", "device.loopTime", "slider", height: 2, width: 4, range: "(1..60)", inactiveLabel: false) {
state "loopTime", action: "setLoopTime"
}
standardTile("loopDir", "device.loopDirection", height: 2, width: 2, inactiveLabel: false, decoration: "flat") {
state "default", label: '${currentValue}', action: "setDirection"
}

main(["switch"])
details(["switch", "levelSliderControl", "colorName", "refresh"])
details(["switch", "levelSliderControl", "colorName", "loop", "refresh", "loopTimeControl", "loopDir"])
}
}

// Parse incoming device messages to generate events
def parse(String description) {
//log.info "description is $description"
if (description?.startsWith("catchall:")) {
if (device.currentValue("loopActive") == "Active") {

}
else if (description?.startsWith("catchall:")) {
if(description?.endsWith("0100") ||description?.endsWith("1001") || description?.matches("on/off\\s*:\\s*1"))
{
def result = createEvent(name: "switch", value: "on")
Expand All @@ -121,7 +142,7 @@ def parse(String description) {

if (descMap.cluster == "0300") {
if(descMap.attrId == "0000"){ //Hue Attribute
def hueValue = Math.round(convertHexToInt(descMap.value) / 255 * 360)
def hueValue = Math.round(convertHexToInt(descMap.value) / 255 * 100)
log.debug "Hue value returned is $hueValue"
def colorName = getColorName(hueValue)
sendEvent(name: "colorName", value: colorName)
Expand Down Expand Up @@ -156,6 +177,87 @@ def parse(String description) {

}

def setDirection() {
def direction = (device.currentValue("loopDirection") == "Down" ? "Up" : "Down")
log.trace direction
sendEvent(name: "loopDirection", value: direction)
if (device.currentValue("loopActive") == "Active") {
def dirHex = (direction == "Down" ? "00" : "01")
log.trace dirHex
"st cmd 0x${device.deviceNetworkId} ${endpointId} 0x300 0x44 {02 01 ${dirHex} 0000 0000}"
}
}

def setLoopTime(value) {
sendEvent(name:"loopTime", value: value)
if (device.currentValue("loopActive") == "Active") {
def finTime = swapEndianHex(hexF(value, 4))
"st cmd 0x${device.deviceNetworkId} ${endpointId} 0x300 0x44 {04 01 00 ${finTime} 0000}"
}
}

def startLoop(Map params) {
// direction either increments or decrements the hue value: "Up" will increment, "Down" will decrement
def direction = (device.currentValue("loopDirection") != null ? (device.currentValue("loopDirection") == "Down" ? "00" : "01") : "00")
log.trace direction
if (params?.direction != null) {
direction = (params.direction == "Down" ? "00" : "01")
sendEvent(name: "loopDirection", value: params.direction )
}
log.trace direction

// time parameter is the time in seconds for a full loop
def cycle = (device.currentValue("loopTime") != null ? device.currentValue("loopTime") : 2)
log.trace cycle
if (params?.time != null) {
cycle = params.time
sendEvent(name:"loopTime", value: cycle)
}
log.trace cycle
def finTime = swapEndianHex(hexF(cycle, 4))
log.trace finTime

def cmds = []
cmds << "st cmd 0x${device.deviceNetworkId} ${endpointId} 6 1 {}"
cmds << "delay 200"

sendEvent(name: "switchColor", value: "Color Loop", displayed: false)
sendEvent(name: "loopActive", value: "Active")

if (params?.hue != null) {

// start hue was specified, so convert to enhanced hue and start loop from there
def sHue = Math.min(Math.round(params.hue * 255 / 100), 255)
finHue = swapEndianHex(hexF(sHue, 4))
log.debug "activating color loop from specified hue"
cmds << "st cmd 0x${device.deviceNetworkId} ${endpointId} 0x300 0x44 {0F 01 ${direction} ${finTime} ${sHue}}"

}
else {

// start hue was not specified, so start loop from current hue updating direction and time
log.debug "activating color loop from current hue"
cmds << "st cmd 0x${device.deviceNetworkId} ${endpointId} 0x300 0x44 {07 02 ${direction} ${finTime} 0000}"

}
cmds
}

def stopLoop() {

log.debug "deactivating color loop"
def cmds = [
"st cmd 0x${device.deviceNetworkId} ${endpointId} 0x300 0x44 {01 00 00 0000 0000}", "delay 200",
"st rattr 0x${device.deviceNetworkId} ${endpointId} 0x0300 0", "delay 200",
"st rattr 0x${device.deviceNetworkId} ${endpointId} 0x0300 1", "delay 200",
"st rattr 0x${device.deviceNetworkId} ${endpointId} 8 0"
]
sendEvent(name: "loopActive", value: "Inactive")

cmds

}

def on() {
log.debug "on()"
setLevel(state?.levelValue)
Expand Down Expand Up @@ -352,6 +454,14 @@ private hex(value, width=2) {
s
}

private hexF(value, width) {
def s = new BigInteger(Math.round(value).toString()).toString(16)
while (s.size() < width) {
s = "0" + s
}
s
}

private evenHex(value){
def s = new BigInteger(Math.round(value).toString()).toString(16)
while (s.size() % 2 != 0) {
Expand Down