From 9880ced8517e330dfb0f0cd105f04ea24d23d0f2 Mon Sep 17 00:00:00 2001 From: juano2310 Date: Mon, 7 Mar 2016 17:05:06 -0800 Subject: [PATCH] Fix wrong DT for Hue bulb --- .../smartthings/hue-bulb.src/hue-bulb.groovy | 147 ++++++++++++++---- 1 file changed, 118 insertions(+), 29 deletions(-) diff --git a/devicetypes/smartthings/hue-bulb.src/hue-bulb.groovy b/devicetypes/smartthings/hue-bulb.src/hue-bulb.groovy index 47f2971..f49ec95 100644 --- a/devicetypes/smartthings/hue-bulb.src/hue-bulb.groovy +++ b/devicetypes/smartthings/hue-bulb.src/hue-bulb.groovy @@ -1,52 +1,54 @@ /** - * Hue Lux Bulb + * Hue Bulb * * Author: SmartThings */ // for the UI metadata { // Automatically generated. Make future change here. - definition (name: "Hue Lux Bulb", namespace: "smartthings", author: "SmartThings") { + definition (name: "Hue Bulb", namespace: "smartthings", author: "SmartThings") { capability "Switch Level" capability "Actuator" + capability "Color Control" capability "Color Temperature" capability "Switch" capability "Refresh" capability "Sensor" - command "refresh" + command "setAdjustedColor" + command "reset" + command "refresh" } simulator { // TODO: define status and reply messages here } - tiles(scale: 2) { - multiAttributeTile(name:"rich-control", type: "lighting", canChangeIcon: true){ - tileAttribute ("device.switch", key: "PRIMARY_CONTROL") { - attributeState "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff" - attributeState "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn" - attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff" - attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn" - } - tileAttribute ("device.level", key: "SLIDER_CONTROL") { - attributeState "level", action:"switch level.setLevel", range:"(0..100)" + tiles (scale: 2){ + multiAttributeTile(name:"rich-control", type: "lighting", width: 6, height: 4, canChangeIcon: true){ + tileAttribute ("device.switch", key: "PRIMARY_CONTROL") { + attributeState "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff" + attributeState "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn" + attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff" + attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn" + } + tileAttribute ("device.level", key: "SLIDER_CONTROL") { + attributeState "level", action:"switch level.setLevel", range:"(0..100)" } tileAttribute ("device.level", key: "SECONDARY_CONTROL") { attributeState "level", label: 'Level ${currentValue}%' } - } + tileAttribute ("device.color", key: "COLOR_CONTROL") { + attributeState "color", action:"setAdjustedColor" + } + } standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) { state "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff" state "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn" state "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff" state "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn" - } - - controlTile("levelSliderControl", "device.level", "slider", height: 1, width: 2, inactiveLabel: false, range:"(0..100)") { - state "level", action:"switch level.setLevel" - } + } controlTile("colorTempSliderControl", "device.colorTemperature", "slider", width: 4, height: 2, inactiveLabel: false, range:"(2000..6500)") { state "colorTemperature", action:"color temperature.setColorTemperature" @@ -55,26 +57,45 @@ metadata { state "colorTemperature", label: '${currentValue} K' } - standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") { - state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh" - } + standardTile("reset", "device.reset", height: 2, width: 2, inactiveLabel: false, decoration: "flat") { + state "default", label:"Reset Color", action:"reset", icon:"st.lights.philips.hue-single" + } + 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: 2, inactiveLabel: false, range:"(0..100)") { + state "level", action:"switch level.setLevel" + } + valueTile("level", "device.level", inactiveLabel: false, decoration: "flat") { + state "level", label: 'Level ${currentValue}%' + } + controlTile("saturationSliderControl", "device.saturation", "slider", height: 1, width: 2, inactiveLabel: false) { + state "saturation", action:"color control.setSaturation" + } + valueTile("saturation", "device.saturation", inactiveLabel: false, decoration: "flat") { + state "saturation", label: 'Sat ${currentValue} ' + } + controlTile("hueSliderControl", "device.hue", "slider", height: 1, width: 2, inactiveLabel: false) { + state "hue", action:"color control.setHue" + } + valueTile("hue", "device.hue", inactiveLabel: false, decoration: "flat") { + state "hue", label: 'Hue ${currentValue} ' + } - main(["switch"]) - details(["rich-control", "colorTempSliderControl", "colorTemp", "refresh"]) - } + main(["switch"]) + details(["rich-control", "colorTempSliderControl", "colorTemp", "reset", "refresh"]) + } } // parse events into attributes def parse(description) { log.debug "parse() - $description" def results = [] - def map = description if (description instanceof String) { log.debug "Hue Bulb stringToMap - ${map}" map = stringToMap(description) } - if (map?.name && map?.value) { results << createEvent(name: "${map?.name}", value: "${map?.value}") } @@ -83,21 +104,72 @@ def parse(description) { // handle commands void on() { - parent.on(this) + log.trace parent.on(this) sendEvent(name: "switch", value: "on") } void off() { - parent.off(this) + log.trace parent.off(this) sendEvent(name: "switch", value: "off") } +void nextLevel() { + def level = device.latestValue("level") as Integer ?: 0 + if (level <= 100) { + level = Math.min(25 * (Math.round(level / 25) + 1), 100) as Integer + } + else { + level = 25 + } + setLevel(level) +} + void setLevel(percent) { log.debug "Executing 'setLevel'" parent.setLevel(this, percent) sendEvent(name: "level", value: percent) } +void setSaturation(percent) { + log.debug "Executing 'setSaturation'" + parent.setSaturation(this, percent) + sendEvent(name: "saturation", value: percent) +} + +void setHue(percent) { + log.debug "Executing 'setHue'" + parent.setHue(this, percent) + sendEvent(name: "hue", value: percent) +} + +void setColor(value) { + log.debug "setColor: ${value}, $this" + parent.setColor(this, value) + if (value.hue) { sendEvent(name: "hue", value: value.hue)} + if (value.saturation) { sendEvent(name: "saturation", value: value.saturation)} + if (value.hex) { sendEvent(name: "color", value: value.hex)} + if (value.level) { sendEvent(name: "level", value: value.level)} + if (value.switch) { sendEvent(name: "switch", value: value.switch)} +} + +void reset() { + log.debug "Executing 'reset'" + def value = [level:100, hex:"#90C638", saturation:56, hue:23] + setAdjustedColor(value) + parent.poll() +} + +void setAdjustedColor(value) { + if (value) { + log.trace "setAdjustedColor: ${value}" + def adjusted = value + [:] + adjusted.hue = adjustOutgoingHue(value.hue) + // Needed because color picker always sends 100 + adjusted.level = null + setColor(adjusted) + } +} + void setColorTemperature(value) { if (value) { log.trace "setColorTemperature: ${value}k" @@ -110,3 +182,20 @@ void refresh() { log.debug "Executing 'refresh'" parent.manualRefresh() } + +def adjustOutgoingHue(percent) { + def adjusted = percent + if (percent > 31) { + if (percent < 63.0) { + adjusted = percent + (7 * (percent -30 ) / 32) + } + else if (percent < 73.0) { + adjusted = 69 + (5 * (percent - 62) / 10) + } + else { + adjusted = percent + (2 * (100 - percent) / 28) + } + } + log.info "percent: $percent, adjusted: $adjusted" + adjusted +}