How I remedied the glaring white Alexa insists on

Right now, the OH Alexa skill doesn’t support color temperature yet. “White” will command the most unfriendly, glaring shade of white the lamp is able to produce. The whitest it can do.

My Hue lamps do support color temperature, and I can control that via the zigbee binding, but it is a seperate mode of operation. This means that once you use color temperature, the HSB color channel is not updated to reflect what the lamp is doing. So after you have corrected the glaring white set by alexa, the HSB channel will stay at glaring white, and the CT channel will report something else. Now how does OH know which one is being used? In the zigbee binding, there is no channel for that. So you don’t know which of the two values is currently controlling the lamp’s behaviour, and thus you don’t know whether a glaring white needs to be corrected, or has already been taken care of.

I decided to decouple the color temperature items from the respective channels, so I can always assume that the lamps are the color that the HSB channel is set to. From now on, a rule will handle commands for the color temperature channel, and convert the color temperatures into HSB commands. The lamps will no longer get any commands that cause them to operate in color temperature mode.

Adjustment to item definitions:
I added the items which control the HSB and CT channels to a group for all the color lamps in the house. Updates to the group can then trigger a rule or help construct a corresponding item. From the CT items, I removed the channel definitions. Note the suffixes “_ColorColor” and “_ColorTemperature”. These are important to help the rules identify the associated color temperature items.

Color    HUELichtleisteSchrank_ColorColor "Lichtleiste" (gLampColor) ["Lighting"] {channel="zigbee:device:3e5f395e:0017880101210cca:0017880101210CCA_11_color_color"}
Dimmer   HUELichtleisteSchrank_ColorTemperature "Farbtemperatur Lichtleiste" (gLampCT)               

Rule to detect a lamp turning maximum white:
When any lamp receives a change, the group will receive an update and then this rule will iterate through all its lamps. When a lamp is found with HSB set to glaring white, it will control the affected lamp’s color temperature item to 70%.

rule "Adjust CT"
    //Adjust color temperature from plain white set by Alexa to warm white by default
    //every time a lamp color somewhere changes
    Item gLampColor received update 
    gLampColor.members.forEach[lamp |
        //make sure this group item actually exists right now
        if ( lamp !== null) {
            //check whether this lamp is on and is maximum white        
            if ( ((lamp.state as HSBType).getSaturation() == 0 ) && ((lamp.state as HSBType).getBrightness() > 0) ) {
                //construct the CT item  
                var itemName = lamp.getName().replace("_ColorColor","_ColorTemperature") 
                var lampCT = gLampCT.members.filter[lamp| == itemName].head
                if (lampCT !== null){
                    sendCommand( lampCT, 70 )
                else {
                    logWarn("WhiteRule", itemName + " item not found, could not adjust color temperature" )

Translation of color temperature commands into HSB commands
The now “dummy” color temperature items need a rule to do anything. The following rule gets triggered when any of the CT items receives a command. Then it will send a corresponding HSB command to the associated lamp HSB item. It will actually set HSB to a hue of 45 (warm yellow), with a saturation between 1% and 61% corresponding to a color temperature setting between 0% and 100%, respectively. It won’t set it to 0% because that would trigger above rule and we would have an infinite loop.

rule "Color Temperature HSB translator"
    //translate CT to HSB so we never operate lamps in CT mode 
    //this will help to consistently provide reliable state information through the HSB channel
    Item HUELichtleisteSchrank_ColorTemperature received command or 
    Item HUESchlafzimmerStehlampe_ColorTemperature received command or 
    Item StehlampeOben_ColorTemperature received command or 
    Item StehlampeUnten_ColorTemperature received command or 
    Item NachttischLinks_ColorTemperature received command or 
    Item NachttischRechts_ColorTemperature received command  
    //construct corresponding color item
    var itemName = triggeringItem.getName().replace("_ColorTemperature", "_ColorColor") 
    var lampColor = gLampColor.members.filter[lamp| == itemName].head

    if ( lampColor !== null) {
        //convert CT to color value (hue 45, saturation 0.6*CT, brightness as is)
        //actual rule is *0.6 + 1, so that saturation never hits 0 when commanded by CT slider.
        //This is to distinguish this operation from Alexa "White" command, which triggers a rule to change color temp.
        val targetSaturation = new PercentType ((receivedCommand as PercentType) * 0.6 + 1)
        val targetBrightness =  new PercentType ((lampColor.state as HSBType).getBrightness().intValue() )
        val targetColor = new HSBType( new DecimalType(45), targetSaturation, targetBrightness) 

        sendCommand( lampColor, targetColor)
    else {
        logWarn("CTConvert", "The color item to adjust color temperature " + itemName + " could not be found")

In 2020, I would make the rule trigger shorter by using

when Member of gVirtual_CT received command

and add all corresponding items to the gVirtual_CT group.
That wasn’t available yet when I wrote the original code.

In 2020, Alexa and the v3 skill support color temperature.

My update was prompted by a discussion about the fact that it is still not possible to know whether a Hue light is operating in CT or HSB color mode. This still makes it impossible to know what the current state of a lamp is. Unless one operates it in HSB only, which this solution is a recipe for.

Unfortunately, the limitation around color state is not technical, but it is deemed to not fit into the design concept of OH to provide a channel with the active operating mode within the Zigbee binding (other bindings do have it). So it is likely to stay this way for people who prefer to use the zigbee binding.