SmartThings Community

Setting hue colors with hex

#1

Does anyone know if this is possible? (setting hue colors with hex)

I had read on the forum that setColor([hex: #00FF00, level: 50]) was possible but I cannot get it to work.

The reason I ask is because I am capturing the state of the hue before I change it and want to reset it back. When you get the current state of color it returns a hex value, but I cannot find a way to send it back to the bulb.

Supposedly the Hue Notification app will reset the state but I can’t get that app to work either.

What am I doing wrong? :flushed:

I have tried this 100 ways, but this is what I have been working with right now, i simplified it to do some testing and have experimented with many different ways to capture vales…

any help is appreciated, thanks


preferences {
	section("Turn on when there's movement..."){
		input "motion1", "capability.motionSensor", title: "Where?"
	}
	section("And off when there's been no movement for..."){
		input "minutes1", "number", title: "Minutes?"
	}
	section("Control these bulbs...") {
input "hues", "capability.colorControl", title: "Which Hue Bulbs?", required:true, multiple:false
	}

}

def installed() {
	subscribe(motion1, "motion", motionHandler)
}

def updated() {
	unsubscribe()
	subscribe(motion1, "motion", motionHandler)
}

def motionHandler(evt) {
	log.debug "$evt.name: $evt.value"
	if (evt.value == "active") {


	def huecolor = hues.currentValue("color")
    	log.debug "current color: ${huecolor}"        
    def huelevel = hues.currentValue("level")
    	log.debug "current level: ${huelevel}"        
    def hueswitch = hues.currentValue("switch")
    	log.debug "current switch: ${hueswitch}"        
    def huehue = hues.currentValue("hue")
    	log.debug "current hue: ${huehue}"        
    def huesat = hues.currentValue("saturation")
    	log.debug "current sat: ${huesat}"


        log.debug "turning hues red for motion"        
//     	hues.setColor(hex: #5100FF, level: 100)  // testing using hex values, wont work 
		hues.setHue(100)
        hues.setLevel(100)


	} else if (evt.value == "inactive") {
		runIn(minutes1 * 60, scheduleCheck, [overwrite: false])
	}

}

def scheduleCheck() {
	log.debug "schedule check"
	def motionState = motion1.currentState("motion")
    if (motionState.value == "inactive") {
        def elapsed = now() - motionState.rawDateCreated.time
    	def threshold = 1000 * 60 * minutes1 - 1000
    	if (elapsed >= threshold) {
            log.debug "Motion has stayed inactive long enough since last check ($elapsed ms):  resetting lights"

hues.setColor([hex: $huecolor, level: $huelevel])


    	} else {
        	log.debug "Motion has not stayed inactive long enough since last check ($elapsed ms):  doing nothing"
        }
    } else {
    	log.debug "Motion is active, do nothing and wait for inactive"
    }
}
(Mike Maxwell) #2

It’s just as easy (or even easier) to use HSV, and ignore the hex altogether.

This is what I use to set color values:

def colorMap = [hue:stateMap.hue.toInteger(),saturation:stateMap.saturation.toInteger(),level:stateMap.level]
	stDevice.setColor(colorMap)

stateMap is just a map structure to hold the previous values, you can substitute your own data structure.

I think the whole hex business has to do with the ST device color wheel as its output is RGB.

#3

I will try working with HSV, Thanks for the tip :sunglasses:

do you have a good way to capture the previous color of the bulb? I guess I could use something to convert the hex to HSV :confused:

Thanks for you help

#4

Oh, should have read the code more closely, see it now, thanks :smirk:

however i just tried it and get “java.lang.NullPointerException: Cannot get property ‘hue’ on null object @ line 43”

i will look into it might be something i did.

Thanks

#5

So I think the problem I’m having is smarthings doesn’t store the previous hue and saturation levels unless they were previously set that way. If I manually set the values in another code I can retrieve them, however if I set the lamp color from the app color wheel, they are null and only the hex color has a value. So is there any way to capture the color that was set by the wheel in the app?

Thanks

(Mike Maxwell) #6

I gave up on the hex, firstly there’s a a bug in the color wheel, if you just touch it, it blows a java null error in the hue bulb device, which can be captured, but even then the thing’s so annoying to fine tune, and it won’t update correctly if you intend to capture scenes that you set with the hue app, so i removed the wheel from the prefs tile and enabled all the sliders and value tiles for HSL, thing works much better.
The HEX to HSV decode bits are in the HUE hub device I believe.

1 Like
#7

Sounds like that is what I need to do! Do you have the code sample for this? That would be awesome! :grinning:

(Mike Maxwell) #8

here ya go…

/**
 *  Hue Bulb
 *
 *  Author: SmartThings
 	maxwell:
    2015-03-01 fixed: java.lang.NullPointerException: Cannot execute null+null @ line 146 error
 */
// for the UI
metadata {
	// Automatically generated. Make future change here.
	definition (name: "Hue Bulb Fixed", namespace: "smartthings", author: "SmartThings") {
		capability "Switch Level"
		capability "Actuator"
		capability "Color Control"
		capability "Switch"
		capability "Refresh"
		capability "Sensor"

		command "setAdjustedColor"
        //[level:100, red:67, hex:#4300FF, saturation:100.0, blue:255, hue:71.04575, green:0, alpha:1] 
        command "refresh"
	}

	simulator {
		// TODO: define status and reply messages here
	}

	standardTile("switch", "device.switch", width: 1, height: 1, canChangeIcon: true) {
		state "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821"
		state "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff"
	}
	standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
		state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
	}
	controlTile("rgbSelector", "device.color", "color", height: 3, width: 3, inactiveLabel: false) {
		state "color", action:"setAdjustedColor"
	}
	controlTile("levelSliderControl", "device.level", "slider", height: 1, width: 2, inactiveLabel: false) {
		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(["switch", "levelSliderControl", "rgbSelector", "refresh"])
    details(["levelSliderControl","level","saturationSliderControl","saturation","hueSliderControl","hue","switch", "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}")
	}

	results

}

// handle commands
def on() {
	parent.on(this)
	sendEvent(name: "switch", value: "on")
}

def off() {
	parent.off(this)
	sendEvent(name: "switch", value: "off")
}

/*
Why?  This isn't event checked into Git?
def poll() {
	parent.poll()
}
*/

def 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)
}

def setLevel(percent) {
	log.debug "Executing 'setLevel'"
	parent.setLevel(this, percent)
	sendEvent(name: "level", value: percent)
}

def setSaturation(percent) {
	log.debug "Executing 'setSaturation'"
	parent.setSaturation(this, percent)
	sendEvent(name: "saturation", value: percent)
}

def setHue(percent) {
	log.debug "Executing 'setHue'"
	parent.setHue(this, percent)
	sendEvent(name: "hue", value: percent)
}

def setColor(value) {
	log.debug "setColor: ${value}"
	parent.setColor(this, value)

	if (value.hex) {
		sendEvent(name: "color", value: value.hex)
	} else if (value.hue && value.saturation) {
		def hex = colorUtil.hslToHex(value.hue, value.saturation)
		sendEvent(name: "color", value: hex)
	}

	if (value.level) {
		sendEvent(name: "level", value: value.level)
	}
	if (value.switch) {
		sendEvent(name: "switch", value: value.switch)
	}
}

def setAdjustedColor(value) {
	if (value) {
		log.debug "setAdjustedColor: ${value}"
		def adjusted = value + [:]
		adjusted.hue = adjustOutgoingHue(value.hue)
		adjusted.level = null // needed because color picker always sends 100
		setColor(adjusted)
    }
}

def save() {
	log.debug "Executing 'save'"
}

def refresh() {
	log.debug "Executing 'refresh'"
	parent.poll()
}

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
}
3 Likes
#9

Thanks! :smile: you saved me a lot of time

(Mike Maxwell) #10

Glad to help, been working on a pretty serious state scene capture/playback app, and that was just one of the many challenges I ran into…

(Justin) #11

Can you take a look at my thread here about changing colors of my lights. I have no idea what I am doing wrong but I always get the same color light whereas I am attempting to generate a random color.

#12

I am traveling ATM, I will take a look Monday or Tuesday :slight_smile:

(Justin) #13

Thank you very much.

(Larry) #14

I have a similar problem I can alrady get the hex value and the red green and blue values but I need to move them into 4 bytes… as that is what the device I am coding for wants

so for instance white ffffff

would become ffffff00 but I need this as a bigint… any ideas howto convert this thanks.