Setting HSL values for an RGB light

I used the RGB tile to find the color I want for my light which was displayed as an RGB value which I used a website to convert to HSL and my hue value is above 100. In my rule the hue value can be between 1-100. I noticed the option within the device to set a 360 hue option, which I did and from the device I could set the correct value even though the field stated 1-100. Going back to my rule I still can’t set above 100 for the hue. I’m sure this is simple but I don’t quite understand the RGB to HSL conversion.

The rule is never going to take the degree number. It is validating the numbers in the standard 0-100 scale. Just convert your degrees into percent by dividing by 360 and then multiplying by 100. That's how you convert from the degree scale to the % scale the Hubitat likes. The wikipedia article on HSV and HSL is actually really good at describing how HSL and HSV work and how you get all the possible colors from those couple of numbers. And it has good pictures too.

Hue is the part that wraps around the cylinder. So, that can be expressed as the number of degrees around or as a percentage of the whole. That's why the two different scales.

2 Likes

I'd consider this a Rule Machine bug. (It is indeed true that Hubitat's standard color model uses hue as 0-100, but high-resolution/0-360 hue is an option in most stock drivers, so I'm not sure I'd expect this to not work in that case.) I just tested what you describe: with 360-degree hue enabled on the device, RM still only lets you input 0-100 but doesn't scale it to 360, so a value of, say, 100 is green and not red--you can't use those input fields to get any higher:

That being said, I'm not sure there's an easy way to check, and not all bulbs support this, so RM might be working as intended or at least the best it can (without allowing this for any bulb) here. Maybe @bravenel can confirm.

In the meantime, you can still do this from RM. You can use a custom action instead of the built-in "set color" action. For example, this works:

You can either call setColor as I did above (the parameters are hue, saturation, and level) or just use setHue if you don't want to adjust anything else.

1 Like

Any reason to not just divide it by 3.6? :slight_smile:

It's not so much a bug as a design flaw, if being able to specify a hue value greater than 100 is needed or of use for some drivers. This would be easy to change in RM. There is of necessity some assumption that the user is going to know what they are doing, but this is certainly not the only place that assumption is made.

I'm going to allow 360 in RM. Next release... A hot fix will be out soon.

3 Likes

Thank you! An additional, thought, why do we use HSL in RM, but the tile's use RGB values? It seems like there should be consistency across the board.

Will this only be allowed if the device is set to 360 or always? What will happen if you put in 350 and the device is set to only work with values of 0-100? You're still making an assumption that the user knows what they are doing and has enabled the 360 feature in the driver. Seems like Hubitat should just pick a standard and then have helper text in the UI when you are entering the hue in the rule tell you that you need to convert 360 values to percents or whatnot. It seems allowing both would cause more problems than it would solve, IMHO.

I already answered that above:

You're probably right in your view of this. I'm always a bit torn between laissez-faire approach and constrained approach. We don't have time right now to do a top-to-bottom overall of how color is handled, so laissez-faire wins out for now.

I don't see an answer to that question.

That's all you said Bruce. where is the answer to that question? You say it will be changed in Rule Machine. For all devices or only ones with high definition hue? I'm not asking for a dissertation here. 1 word is all i need.

That's what I was referring to. Doing that would be a mistake, and it probably depends on the driver what would happen. I know that some drivers range check the hue value, but I don't know if all do or not. From above:

I feel like a users will figure it out pretty quickly when the light either doesn’t change color and throws an error to the logs, or changes to the wrong color. :slight_smile:

I’ll double check my implementation of this in my drivers. Thanks for the heads up that this will be in an upcoming release.

Tagging users to double check their lighting drivers for 0-360 hue compatibility:
@sgrayban (Shelly driver) @damon.dinsmore (Tasmota driver) @RobinWinbourne (Fibaro driver)

Tag others I’ve missed :slight_smile:

(Feel free to grab my limit/clamp methods from any of my drivers. I’ve been thinking of how to clean it up, so I’m all ears for ideas)

I have had issues where I do see a error only when setting the colour via a rule or the simple lighting app.

Voice control seems to work though.

My Drivers use the 1 to 100 range of Set Color but if Hue is set above 100 it would not error as it would catch this. It does the conversion to HSL so any number over 100 would be set to 360. So my drivers do the error checking.

1 Like

FWIW, CoCoHue will (apparently like your driver) set values below the accepted range to the minimum accepted value and values higher than the accepted range to the maximum accepted value. It looks like Hubitat's generic drivers don't do anything to prevent you from sending out-of-range values (but obviously they do correctly scale either 0-100 or 0-360 to the appropriate bulb values--there's just nothing to keep you in that range), so they'll do whatever the bulb does (likely nothing) when it gets an out-of-range value: HubitatPublic/GenericZigbeeRGBWBulb.groovy at master · hubitat/HubitatPublic · GitHub. The default Hue integration also doesn't do anything in such a case (not sure if it sends something to the Bridge and the Bridge ignores it or if it knows and just doesn't try).

I wasn't sure which direction to go with my drivers but erred on the side of doing something vaguely similar to what the user probably wanted, even though this shouldn't really ever happen. I'm willing to change this (or not) if someone can make a more compelling argument for either behavior. :slight_smile:

But then, if a user is expecting a value between 0-360, anything 0-100 would be rendered unexpectedly, no? Included drivers have an option that parses it down. I’ve got my drivers (I think they still do?) to have an option, but still try to correct for values over 100.

What errors are you seeing?

What error are they throwing?

Seems like a good approach. :slight_smile:

It would be out of range and the math would just bring it down to the top of the range. But I agree with you that an attempt to get where the user is looking for would be a good approach. But also thinking that a note to use 1 to 100 scale in RM would be just as useful. It isn't a big deal either way to me personally but users could be confused. The other problem is that if they use a number 100 or below then it will act wrong for the ones using a 360 scale for that range. And since the set color button in the driver doing the 100 scale you have to have a catch for that regardless and there is not really a way to catch which is which.

1 Like

@bravenel

Would it make sense to have a parameter for setColor—perhaps String: HueResolution: 100 or 360 (which would default to 100). This way, we could adjust the hue based off of what an app is choosing. Drivers that don’t support it would just ignore the parameter, so it wouldn’t break anything, as far as I can think? It would also save a preference for each device.

Of course, it’s an extra layer of management for drivers, which is a downside... but it seems like a lot of us have this built in as a user-preference already, so we would just need to change the verification check from a preference to params.HueResolution == 360 ? ...

I agree adding that adding a preference option to the driver is the best course of action to deal with the proper ranges. And its simple to add.

Yup. That’s the default for HE’s drivers. Dividing values by 3.6 is easy :crazy_face:

I’m just wondering if it makes more sense to change it to a parameter in the setColor map that lets a transmitting app select what range to use.