Philips Hue CLIP 2 API v2 Discussion Thread

From what I could understand that is what @djpsycho82 is trying to do.
Preset the required color_temp and then turn on the lamp when he is ready - rather than turn on lamp and then adjust the color temp.

I tried this, with several methods (color-xy-only / color-temperature) but it only changes with brightness above 0, when the error occurs the settings isn’t picked up by the light.

@Mark_VG describes that the changes are lost after [OnOff_Only changes] does not happen in my setup. The light temperature stays the same regardless it’s on / off or any brightness value. I’m monitoring this with the items in openhab (text based/log) but also the hue app, the hue app follows exactly the light changes made with openhab.

The behaviour on my own system is as follows…

  • color-temperature commands are ignored if the lamp is off
  • color-temperature commands are executed if the lamp is on
  • color-temperature values are persisted if the lamp is toggled on=>off=>on

Notes:

  1. The color-xy-only channel behaves as above too.
  2. i.e. color-temperature behaves as color-temperature-**ONLY**.
  3. By contrast HSB commands to color channel do not behave as above.

So it’s behaving different than in API 1 unfortunately :frowning:

For my own setup I have to think what to do, or going back to API 1 (much slower and no scene control, which i don’t use at the moment.) Or accept that my lights are going on/off when there are situation changes in my house.

Do you knwo if API v1 is deprecated? Or is API v2 just an extra control layer for Hue?

This is definitely an OH Main UI issue. It works fine if you send the command via a color picker control or via a sitemap color picker or via a rule. Your Main UI video is new to me (as I hardly ever use Main UI for such things) but I can confirm that I now do see the same on my own system. From my past recollection, the color controls used to look different – more like three sliders. Therefore I think this is a new bug introduced in a recent OH version. => So instead of continuing to discuss it here, I would advise to open a new thread under the Main UI topic so that OH Main UI maintainers will respond.

EDIT: I see the same bug both on Chrome and Edge browsers…

1 Like

Thanks, have opened a new thread as suggested.

I understand your issue, and am thinking if there is any way to resolve it via changes in the binding, however so far I have no ideas.

I can only suggest two possible work arounds (neither of which is perfect)…

  1. Implement a dummy item not linked to any channel to store your “preset” color temperature, and implement a rule that triggers when a lamp turns on and sends the preset color temperature to that lamp.
  2. In your rule that changes the color temperature, if the lamp is off, send a brightness n% value to the color channel, so it will be on (and can therefore accept the color temperature value), but nevertheless be very dim. Select n% from the lamp’s dimmingRange property (see screenshot below).

EDIT: You could even try a variant of 2. as follows: In your rule issue the following commands rapidly in sequence: a) if the lamp is off, send Percent n% to color channel, send color-temperature value, send OFF to color channel, or b) if the lamp is on, just send color-temperature value. :slight_smile:

Yes it is. Philips / Signify has announced that it will be phased out – albeit they have not announced a fixed date. Their newly introduced Matter support is built entirely on API v2 and therefore all future development is focussed on that API.

1 Like

Allright, good to know! Thanks for the info.

So I will stick with API 2 and think of a way to change the color of the lights. Most easy way for me is building it in the rule where I control my lights, I already use proxy items to save certain values like the color-temperature. Best way is after turning on the lights, send the color value to the lights. It takes a little while for the lights to change, but so it is. There are greater problems in the world :wink:

Below is the rule for all my rooms to load scenes I saved into an item into JSON string, afterwards it’s able to save it as a “state” to load that scene when the house is in a specific state according to some items. It’s growing bit by bit, but OH4 is fast enough to execute it luckily. I think it can manage some color changes but it takes a while for me to rebuild it.

rule "2 - load scene"
when
    Item LoadScene changed // string with input: "Woonkamer, Avond Verlichting evt.[,save/forceload/manualm, fade]"
then
    LoadScene.postUpdate("")
    SceneActive.postUpdate(ON)
    if (newState === NULL || newState == ""){
        LoadScene.postUpdate("")
        return;
    }

    if (intFlapDetect > 5){
        FlapDetect.postUpdate(ON)
        logInfo("mr_autoscenes", "Loadscene : FLAPPING Detect! LoadScene gestopt! --> " + LoadScene.state.toString())
        sendSmartHomeNotify.postUpdate("Loadscene : FLAPPING Detect! LoadScene gestopt!" + LoadScene.state.toString())
        return;
    } else {
        intFlapDetect = intFlapDetect + 1
    }

    val String strNewState = newState.toString
    var hueLightAction = getActions("hue","hue:device:wkbridge:Thing_Slaapkamerkastspot1")
    var Long FadeSpeed = 1000
    var Boolean blnSaveState = false
    var Boolean blnSkipLoad = true
    var Boolean blnFade = false


    if (strNewState.contains(",") == false || strNewState.split(",").length() < 2){
        logError("mr_autoscene", "LoadScene heeft verkeerde waardes, functie afgebroken. Verwacht: 'Ruimte','Scenenaam' maar ontvangen --> [" + strNewState + "]")
        sendSmartHomeNotify.postUpdate("LoadScene heeft verkeerde waardes, functie afgebroken. Verwacht: 'Ruimte','Scenenaam' maar ontvangen --> [" + strNewState + "]")
        LoadScene.postUpdate("")
        return;
    }

    if (strNewState.split(",").length() == 3){
        if (strNewState.split(",").get(2).trim == "forceload"){
            blnSkipLoad = false
            blnSaveState = false            
        }

        if (strNewState.split(",").get(2).trim == "manual" || strNewState.split(",").get(2).trim == "save"){
            blnSkipLoad = false
            blnSaveState = true
        }
    }

    if (strNewState.split(",").length() == 4){
        if (strNewState.split(",").get(2).trim == "fade"){
            blnFade = true
            FadeSpeed = new DecimalType(strNewState.split(",").get(3).trim).longValue * 1000
        }
    }
        
    val String strRoom = strNewState.split(",").get(0).trim
    val String strSceneName = strNewState.split(",").get(1).trim
    val String strAction = ""
    val String jsonString = ScriptServiceUtil.getItemRegistry.getItem(strRoom + "_scenes").state.toString
    var Boolean blnSceneFound = false

    if (strSceneName == ScriptServiceUtil.getItemRegistry.getItem(strRoom + "_scene").state.toString().toLowerCase() && blnSkipLoad == true){
        logInfo("mr_autoscene", "Inladen van scene: " + strSceneName + " afgebroken, huidige scene is gelijk.")
    } else {
        if (jsonString == "NULL" || jsonString == "" || jsonString.contains('{"Scenes":[{') == false){
            logError("mr_autoscene", "LoadScene afgebroken! Item: [" + strRoom + "_scenes] is NULL, Leeg of lijkt geen geldige JSON.")
            sendSmartHomeNotify.postUpdate("LoadScene afgebroken! Item: [" + strRoom + "_scenes] is NULL, Leeg of lijkt geen geldige JSON.")
            LoadScene.postUpdate("")
            return;
        }

        if (jsonString.split("Scenes").length() > 2){
            logError("mr_autoscene", "LoadScene afgebroken door fatale fout! Scenes van item: [" + strRoom + "_scenes] zijn corrupt!")
            sendSmartHomeNotify.postUpdate("LoadScene afgebroken door fatale fout! Scenes van item: [" + strRoom + "_scenes] zijn corrupt!")
            LoadScene.postUpdate("")
            return;
        }

        val int intSceneCount = Integer.parseInt(transform("JSONPATH", "$[*].length()", jsonString)) - 1

        for (var i=0; i<=intSceneCount; i++){
            if (transform("JSONPATH", "$.Scenes[" + i + "].Naam", jsonString).toString.toUpperCase() == strSceneName.toUpperCase()){
                var String strJson = transform("JSONPATH", "$.Scenes[" + i + "]",jsonString)
                var pairs = strJson.replace("{", "").replace("}", "").split(", ")
                var pairLength = pairs.length()

                for (var x=1 ; x < pairLength; x++){
                    var String lamp = pairs.get(x).split("=").get(0)
                    var String value = pairs.get(x).split("=").get(1)

                    if (blnFade == true){
                        try{
                            logInfo("Autoscene", "---------- Fading begint --------------")
                            hueLightAction = getActions("hue","hue:device:wkbridge:Thing_" + lamp)

                            if (value.contains(",")){
                                hueLightAction.dynamicCommand("color", new HSBType(value), FadeSpeed)
                            } else {
                                hueLightAction.dynamicCommand("brightness", new PercentType(new DecimalType(value).intValue), FadeSpeed)
                            }

                            
                        } catch (Exception e) {
                            sendCommand(lamp, value)
                        }
                    } else {
                        sendCommand(lamp, value)
                    }
                }

                blnSceneFound = true
            }
        }

        if (blnSceneFound == false){
            logWarn("mr_autoscene", "LoadScene heeft geen scene gevonden. Gegevens ontvangen --> [" + strNewState + "]")
            sendSmartHomeNotify.postUpdate("LoadScene heeft geen scene gevonden. Gegevens ontvangen --> [" + strNewState + "]")
        }

        postUpdate(strRoom + "_current_scene",strSceneName)
        postUpdate(strRoom + "_scene",strSceneName)
    }
    
    if (blnSaveState == true){
        logInfo("AutoScenes", "SaveState wordt gestart")
        sendCommand(SaveState, strRoom)
    }
end

uh, took some time but it could have been this easy:

sudo apt reinstall openhab openhab-addons

this did the job, api v2 bridge is online!

thanks @AndrewFG and @Mark_VG for being patient with me! :blush:

1 Like

You could even try issuing a ‘dynamics’ command immediately before the ‘color-temperature’ command; that way, the lamp would come on immediately with whatever c-t it had previously had, and then gently fade to the new preset c-t value; which would probably be less jarring to people in the room.

1 Like

That’s a very good idea :bulb:

I think I’m gonna implement that!

Wouldn’t it be possible to ‘memorize’ changes done in off state in the binding and send them whenever an ‘on’ command is sent (or alternatively, and probably preferably, when an off → on state transition is detected)?

I actually had the same thought today. :slight_smile:

I wanted to test the behavior with API v1 to compare results, but didn’t get to that yet.

See also this comments that are somewhat related:

Your proposal is precisely what I have suggested the OP to do via a dummy item and a rule. This is a hack to try to resolve a particular user’s needs. It carries obvious disadvantages – namely that OH will post-hoc overwrite any commands sent via the Hue system from switches, dimmers, and the app. For that reason such a hack should definitely not be hardwired into the binding code.

API v1 has similar behavior. Color temperature changes while bulb is without power won’t have effect when it comes online again - it resets to previous value.

However, if the bulb is with power and only “soft” turned off, it’s possible to change the color temperature while bulb is “off”, and it will turn on with the set color temperature. This does not work the same way with Hue API v2. Here the color temperature is reset/lost when setting the brightness >0 again.

EDIT: I verified only through the binding with API v1 and API v2 things. not directly through the API. So I cannot yet rule out that the two implementations have impact on this behavior.

Lamps have a minimum dimming level. e.g. 2% So I presume you mean by “soft off” a dimming level > 0 and < minimum dimming level? Currently the binding constrains brightness commands to >= minimum dimming level and <= 100% …

Yeah, I was switching between ~50% and 0% brightness for the tests.

Considering only the “soft off” scenario, will it actually? Any external state changes should fail as well, the same way we do. And if they would succeed, I guess we would receive those state changes as well. So we should be fully synchronized until the moment when we would flush our queued color temperature update. I’m not saying there are no traps still, just playing with the idea.

Disclaimer: The following is only brainstorming… so please bear with me. :wink:

The best moment to “queue” such changes would probably be upon a failed command, e.g.:

Command '0' for thing 'hue:device:xxx', channel 'hue:device:xxx:color-temperature' succeeded with errors: device (light) is "soft off", command (.color_temperature.mirek) may not have effect

First problem: How to detect that? I don’t know. I wouldn’t like to search in the text, but I don’t think there’s an error code available. Maybe we can fully analyze the logic and assess when this error will occur - for example when sending color-temperature while dimming level is below minimum. But this could change in future firmware upgrades (hopefully, actually). So maybe a flag could be set when attempting this command we expect to fail - and the presence of any errors after the call would then confirm and queue. We could remember the current color temperature also for verification.

Next, when should we “retry” the change? There are at least two different scenarios that might occur: The device is turned on again by some external event. Or we send a command ourselves to turn it on again. To be decided if both scenarios should result in the queued update, but probably they should, because otherwise you can’t adjust color temperatures throughout the day and let them become effective when a button would turn the bulb on. So at this point we’ll send our command, but only if the remembered current color temperature is still the same as when we queued the command, as otherwise we would overwrite external changes of color temperature in the meantime. And of course only if the desired color temperature is different from the current color temperature.

For the last sentence (“only if”) I may have just discovered a bug:

  • Set color temperature to 100%
  • Set brightness to 0%.
  • Set color temperature to 0%
  • Command failed, but state of the color-temperature channel is still 0%.
  • Pause the Thing.
  • Resume the Thing.
  • The color-temperature channel is now updated to 100% (because of initial state).

If we receive push messages with new state after successful commands, we might consider a veto policy here:

@laursen I feel seriously uncomfortable with your line of reasoning here. It is trying to devise a hack to “out fox” the native functionality of the Hue system. This is dangerous and can have unexpected bad consequences. IMHO such a hack could be done on a particular user’s system by means of a dummy item and a rule. But it must not be done opaquely hardwired in the binding code.