Skip to content

[hue] Fix Hue color temperature regression when light is soft-off or unreachable#21018

Closed
kaikreuzer wants to merge 1 commit into
openhab:mainfrom
kaikreuzer:kaikreuzer-hue-soft-off-regression
Closed

[hue] Fix Hue color temperature regression when light is soft-off or unreachable#21018
kaikreuzer wants to merge 1 commit into
openhab:mainfrom
kaikreuzer:kaikreuzer-hue-soft-off-regression

Conversation

@kaikreuzer

@kaikreuzer kaikreuzer commented Jun 20, 2026

Copy link
Copy Markdown
Member

When a color-temperature command is sent to a Hue light that is soft-off, the binding logs a spurious INFO message and the color temperature is lost:

Command '12' for thing 'hue:device:1:29', channel 'hue:device:1:29:color-temperature' succeeded with errors:
  device (light) 9985ea7b-6ce3-4870-b9b3-2212ee04dc49 is "soft off", command (.color_temperature.mirek) may not have effect

The same issue occurs when the light is temporarily unreachable or any other transient failure prevents the command from taking effect.

Fixes #21011

Solution

When a color-temperature command is sent, the binding now:

  1. Immediately reflects it in the local state cache and updates the item channel state, regardless of whether the PUT succeeded
  2. Remembers the pending mirek value (pendingColorTemperatureMirek)
  3. Merges it into the next ON-like command — switch, on-off, brightness, and dimming-only channels (but not HSB color or effect commands, which encode their own color mode)
  4. Clears the pending value once such a command succeeds, or once a direct color-temperature command succeeds without errors (light was already on)

The "succeeded with errors" log message is now emitted at DEBUG level instead of INFO, so soft-off and similar transient conditions no longer produce noise in the default log output.

@kaikreuzer kaikreuzer changed the title Fix Hue color temperature regression when light is soft-off or unreachable [hue] Fix Hue color temperature regression when light is soft-off or unreachable Jun 20, 2026
@kaikreuzer kaikreuzer force-pushed the kaikreuzer-hue-soft-off-regression branch from 83f950b to 0a8652a Compare June 20, 2026 23:15
…hable

When a color-temperature command is sent to a light that is soft-off,
unreachable, or experiences any other transient failure, the binding now:
- Immediately reflects the commanded color temperature in the local state cache
  and item channel state
- Remembers the pending mirek value
- Merges it into the next plain ON command (switch/on-off channels only)
- Clears the pending value once an ON or a successful direct CT command is
  processed

This restores the previously supported behavior where color temperature set
while a light is off takes effect when the light is next switched on.

Fixes openhab#21011

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Kai Kreuzer <kai@openhab.org>
@kaikreuzer kaikreuzer force-pushed the kaikreuzer-hue-soft-off-regression branch from 0a8652a to ebae61d Compare June 20, 2026 23:20
@andrewfg

andrewfg commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

@kaikreuzer I am not sure if I am fully in agreement with this approach. Until now the state of a light in OH is exactly what is received over the wire via SSE from the Hub. And you are proposing to interpolate a best guess buffer between a command sent, and an SSE not seen. i.e. by internally caching some assumed state. This breaks the model, and sets a bad precedent for other future horrors. So I plan to propose a better solution. However before I do it, I would like to better understand exactly what is your issue. So can you please post three things..

  1. TRACE log of the full state json from the first GET after the light thing comes online.
  2. TRACE log of the PUT json and its respective response json
  3. TRACE log of all SSE event json arriving after the PUT

EDIT so in other words, I think that the correct state of an Item linked to CT channel after a PUT fails, should simply be whatever value it was commanded to. And it should only change again from that value when the next SSE event comes in to say something different. And if it is off, and/or offline then next SSE that comes in when it is once more on(line) will provide the new CT value directly. i.e. no internal caching. (please)

@andrewfg

andrewfg commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

PS so I am thinking that perhaps this PR should be simplified to just downgrading the log level..

E.g. if you send a CT command to a lamp which off, and then you turn it on (via the on/off only channel) does it come on at the desired CT. Or, if you change the brightness from ~0 to say 60 (via the dimming only channel) does it come on at the desired CT. PS do not try to turn it on via the HSB channel since that sends a munge of color xy, brightness, on/off state, and indeed the color xy may indeed then trash the CT.

@kaikreuzer

Copy link
Copy Markdown
Member Author

does it come on at the desired CT

No, and that is the regression I would like to fix (note that before the v2 refactoring, this worked nicely).

The use-case is simple:
While a light is OFF, (i.e. it has a state with brightness=0) it should be possible to set a new state with a different CT (while brightness is still 0). Once brightness is changed (either through an ON command or a brightness value), the light should have the CT that had been sent previously. Note that the binding needs to work around the different models between openHAB and hue: openHAB does not know/care about "softoff", while hue typically turns a light on when sending a CT (which must be prevented) - that's why this code here caches it locally until it is allowed to send the value. Just to repeat: That logic was once in the binding but has been lost by a refactoring.

@andrewfg

Copy link
Copy Markdown
Contributor

refactoring

Haha. It certainly is not something that I would call a "refactoring". Clip2 is a whole new, and very different API, that totally replaces the whole Hue architecture. And in OH it is a total code base written from scratch. And it took me many weeks to write it. It is certainly not a refactoring nor even a "rewrite" (that would imply the same architecture). So the issue whatever it is, is certainly NOT a regression. Perhaps more an architectural fact of life. And or a request for new functionality. .. But anyway let me think about it..

@andrewfg

andrewfg commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

anyway let me think about it..

@kaikreuzer can you please help me by running a few tests?

A. Background

Refer to chart..

image

Internally within the Hue bridge Clip2 API, the state of a lamp is represented by four orthogonal state variables. This is a quantum step different than how the state used to be mapped in Clip1 API (via HSB). The orthogonal state variables are as follows:

  1. The CIE color xy state (see chart above).
  2. The brightness percentage.
  3. The on/off state.
  4. The color temperature (a point on the "Planckian Locus" within the CIE color xy space, see chart above).

These state variables are essentially orthogonal. And in OH these are directly mapped to the color-xy-only, dimming-only, on-off-only, and color-temperature (advanced) channels. These are the "pure" channels in OH that most closely map to the actual state of the lamp. (Albeit the color-xy-only and color-temperature are not fully orthogonal due to the Planckian Locus being a constraint within the CIE xy color space).

... and then in OH we have the color channel which is a "munge" of 3. plus 2. plus 1. plus (therefore) 4. into a common HSBType state. This OH munge is a compromise to make the actual light state "pretend" to look like an HSB value. So when doing tests, do not use the color channel because there is no purity in the round tripping of state:

  1. Exact round trip command <=> state mapping

    • Command color-xy-only => sent to bridge => SSE event => color-xy-only channel state.
    • Command dimming-only => sent to bridge => SSE event => dimming-only channel state.
    • Command on-off-only => sent to bridge => SSE event => on-off-only channel state.
    • Command color-temperature => sent to bridge => SSE event => color-temperature channel state.
    • Plus command color-temperature resp. color-xy-only => sent to bridge => SSE event of counterpart channel => change of its state (mapping via Planckian Locus).
  2. NOT exact round trip command <=> state mapping (RISKY)

    • Command color => OH splits (un-munges) into color-xy-only (HS), dimming-only (B), on-off-only (B>n) => three variables sent to bridge => three SSE events => color-xy-only, dimming-only), on-off-only => OH recombines (re-munges) into 'color' state => plus one SSE event => color-temperature channel state.

Therefore when running tests, please always use the something-only channels in order to avoid un-munge => re-munge state approximation.

B. API Architecture (THEORY)

Philips API architecture INTENTION is that the four orthogonal state variables are indeed orthogonal. So one can for example send new values of color-xy-only and dimming-only states while the on-off-only is "off", and then at a later time command the on-off-only to "on"; and at this time the light will come on with the color xy and brightness that had previously been sent.

C. Your Observations (PRACTICE)

@kaikreuzer if I understand you correctly, (please correct me if I am wrong), in your case the example cited above in B. DOES work as described. Please confirm. Yet setting a new value of color-temperature state while the on-off-only is "off", and then at a later time commanding the on-off-only to "on", does NOT result in the desired CT being applied. Please confirm if that is the case?

D. Practical Considerations

As you can see from the CIE chart there is a perfect mathematical congruence between CT and XY values. However mathematics inside the Hue bridge is not perfect. To be specific any color temperature between about 2000K and 6500K (depending on the model of the light) will ALWAYS produce a corresponding XY value. And any CT outside that range may not. But -- more importantly -- in the opposite direction any XY value will (unless we are extremely lucky) NOT produce a valid CT. I think Hue uses some algorithm where if XY is "close to" the locus then a CT is returned and otherwise not. However that "close to" algorithm is opaque to us.

So to be specific: If you confirm your observations in C. above (OFF => CT => ON => CT' != CT). Can you please test in more detail:

  1. If the return CT' is a) CT' ~= CT (close to), b) CT' is totally different than CT, or c) CT' == null/undef -- in which case check 2. below...
  2. If a) the return CT' is null AND the returned XY' is "close to" the point on the Planckian Locus corresponding to CT, or b) something totally different..

In my opinion the states {1a} or {1c + 2a} are consistent with the Philips / Signify API architecture B. above. Whereas {1b} and {1c + 2b} are not. And indeed if {1b} or {1c + 2b} apply, then this is probably a regression and non compliance versus the API Architecture, rather than a regression caused by us.

And @kaikreuzer if you have understood me so far, you may perhaps now understand my concern about making a hasty fix via this PR. ;)

@andrewfg

andrewfg commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

^ .. furthermore .. I do NOT see the problem that you cite (see my log below) neither the error log nor the failure to update the CT state. This was on a model LTW001 light. => So I think we need to fully understand the reasons before committing any fixes..

2026-06-23 14:41:50.165 [DEBUG] [e.internal.handler.Clip2ThingHandler] - adeb3425-6a6b-49a0-8262-129126de7941 -> handleCommand() put resource id:ba38af49-4206-47fb-b05a-b54887c12b4c, type:light
2026-06-23 14:41:50.166 [DEBUG] [.internal.handler.Clip2BridgeHandler] - putResource() id:ba38af49-4206-47fb-b05a-b54887c12b4c, type:light
2026-06-23 14:41:50.167 [TRACE] [.hue.internal.connection.Clip2Bridge] - PUT https://192.168.1.108/clip/v2/resource/light/ba38af49-4206-47fb-b05a-b54887c12b4c HTTPS/2 >> {"type":"light","id":"ba38af49-4206-47fb-b05a-b54887c12b4c","color_temperature":{"mirek":400}}
2026-06-23 14:41:50.215 [TRACE] [.hue.internal.connection.Clip2Bridge] - HTTPS/2 200 (Content-Type: application/json) << {"data":[{"rid":"ba38af49-4206-47fb-b05a-b54887c12b4c","rtype":"light"}],"errors":[]}
2026-06-23 14:41:50.284 [TRACE] [.hue.internal.connection.Clip2Bridge] - onEventData() data:[{"creationtime":"2026-06-23T13:41:50Z","data":[{"color_temperature":{"mirek":400,"mirek_valid":true},"id":"ba38af49-4206-47fb-b05a-b54887c12b4c","id_v1":"/lights/10","owner":{"rid":"adeb3425-6a6b-49a0-8262-129126de7941","rtype":"device"},"service_id":0,"type":"light"}],"id":"7765c076-815b-469d-808d-b7697d285be3","type":"update"}]
2026-06-23 14:41:50.285 [DEBUG] [.internal.handler.Clip2BridgeHandler] - onResourcesEventTask() resource count 1
2026-06-23 14:41:50.286 [DEBUG] [e.internal.handler.Clip2ThingHandler] - adeb3425-6a6b-49a0-8262-129126de7941 -> updateChannels() from resource id:ba38af49-4206-47fb-b05a-b54887c12b4c, type:light
2026-06-23 14:41:50.286 [DEBUG] [e.internal.handler.Clip2ThingHandler] - adeb3425-6a6b-49a0-8262-129126de7941 -> updateState() 'color-temperature' update with '82.06' (fullUpdate:false, isDefined:true)
2026-06-23 14:41:50.287 [DEBUG] [e.internal.handler.Clip2ThingHandler] - adeb3425-6a6b-49a0-8262-129126de7941 -> updateState() 'color-temperature-abs' update with '2500 K' (fullUpdate:false, isDefined:true)
2026-06-23 14:41:50.288 [DEBUG] [e.internal.handler.Clip2ThingHandler] - adeb3425-6a6b-49a0-8262-129126de7941 -> updateState() 'brightness' update with '0' (fullUpdate:false, isDefined:true)
2026-06-23 14:41:50.289 [DEBUG] [e.internal.handler.Clip2ThingHandler] - adeb3425-6a6b-49a0-8262-129126de7941 -> updateState() 'dimming-only' update with '100' (fullUpdate:false, isDefined:true)
2026-06-23 14:41:50.290 [DEBUG] [e.internal.handler.Clip2ThingHandler] - adeb3425-6a6b-49a0-8262-129126de7941 -> updateState() 'on-off-only' update with 'OFF' (fullUpdate:false, isDefined:true)
2026-06-23 14:41:50.291 [DEBUG] [e.internal.handler.Clip2ThingHandler] - adeb3425-6a6b-49a0-8262-129126de7941 -> updateState() 'alert' update with 'NO_ACTION' (fullUpdate:false, isDefined:true)
2026-06-23 14:41:50.294 [DEBUG] [e.internal.handler.Clip2ThingHandler] - adeb3425-6a6b-49a0-8262-129126de7941 -> updateState() 'last-updated' update with '2026-06-23T14:41:50.294711519+0100' (fullUpdate:false, isDefined:true)
2026-06-23 14:41:50.295 [DEBUG] [e.internal.handler.Clip2ThingHandler] - adeb3425-6a6b-49a0-8262-129126de7941 -> onResource() consumed resource id:ba38af49-4206-47fb-b05a-b54887c12b4c, type:light, flags:12

Note: the above is the log from a LTW001 on/off/dimming/ct-only light. And below is the log from a LCA006 on/off/dimming/full color light (it also has no errors).

2026-06-23 14:54:54.869 [DEBUG] [e.internal.handler.Clip2ThingHandler] - eafb9a2c-15a6-49ec-af65-8920b8c44d45 -> handleCommand() put resource id:01fa810d-31c8-406b-937c-6902058dcfc5, type:light
2026-06-23 14:54:54.870 [DEBUG] [.internal.handler.Clip2BridgeHandler] - putResource() id:01fa810d-31c8-406b-937c-6902058dcfc5, type:light
2026-06-23 14:54:54.871 [TRACE] [.hue.internal.connection.Clip2Bridge] - PUT https://192.168.1.108/clip/v2/resource/light/01fa810d-31c8-406b-937c-6902058dcfc5 HTTPS/2 >> {"type":"light","id":"01fa810d-31c8-406b-937c-6902058dcfc5","color_temperature":{"mirek":345}}
2026-06-23 14:54:54.929 [TRACE] [.hue.internal.connection.Clip2Bridge] - HTTPS/2 200 (Content-Type: application/json) << {"data":[{"rid":"01fa810d-31c8-406b-937c-6902058dcfc5","rtype":"light"}],"errors":[]}
2026-06-23 14:54:54.992 [TRACE] [.hue.internal.connection.Clip2Bridge] - onEventData() data:[{"creationtime":"2026-06-23T13:54:54Z","data":[{"color":{"xy":{"x":0.4444,"y":0.4065}},"color_temperature":{"mirek":345,"mirek_valid":true},"id":"01fa810d-31c8-406b-937c-6902058dcfc5","id_v1":"/lights/24","owner":{"rid":"eafb9a2c-15a6-49ec-af65-8920b8c44d45","rtype":"device"},"service_id":0,"type":"light"}],"id":"3753d60e-a84f-4bbe-b691-7740ec77a1f2","type":"update"}]
2026-06-23 14:54:54.993 [DEBUG] [.internal.handler.Clip2BridgeHandler] - onResourcesEventTask() resource count 1
2026-06-23 14:54:54.994 [DEBUG] [e.internal.handler.Clip2ThingHandler] - eafb9a2c-15a6-49ec-af65-8920b8c44d45 -> updateChannels() from resource id:01fa810d-31c8-406b-937c-6902058dcfc5, type:light
2026-06-23 14:54:54.995 [DEBUG] [e.internal.handler.Clip2ThingHandler] - eafb9a2c-15a6-49ec-af65-8920b8c44d45 -> updateState() 'color-temperature' update with '55.33' (fullUpdate:false, isDefined:true)
2026-06-23 14:54:54.996 [DEBUG] [e.internal.handler.Clip2ThingHandler] - eafb9a2c-15a6-49ec-af65-8920b8c44d45 -> updateState() 'color-temperature-abs' update with '2898.550724637681159420289855072464 K' (fullUpdate:false, isDefined:true)
2026-06-23 14:54:54.997 [DEBUG] [e.internal.handler.Clip2ThingHandler] - eafb9a2c-15a6-49ec-af65-8920b8c44d45 -> updateState() 'color' update with '39.216,48.86300,0' (fullUpdate:false, isDefined:true)
2026-06-23 14:54:54.999 [DEBUG] [e.internal.handler.Clip2ThingHandler] - eafb9a2c-15a6-49ec-af65-8920b8c44d45 -> updateState() 'color-xy-only' update with '39.216,48.86300,100' (fullUpdate:false, isDefined:true)
2026-06-23 14:54:55.000 [DEBUG] [e.internal.handler.Clip2ThingHandler] - eafb9a2c-15a6-49ec-af65-8920b8c44d45 -> updateState() 'effect' update with 'NO_EFFECT' (fullUpdate:false, isDefined:true)
2026-06-23 14:54:55.001 [DEBUG] [e.internal.handler.Clip2ThingHandler] - eafb9a2c-15a6-49ec-af65-8920b8c44d45 -> updateState() 'dimming-only' update with '100' (fullUpdate:false, isDefined:true)
2026-06-23 14:54:55.002 [DEBUG] [e.internal.handler.Clip2ThingHandler] - eafb9a2c-15a6-49ec-af65-8920b8c44d45 -> updateState() 'on-off-only' update with 'OFF' (fullUpdate:false, isDefined:true)
2026-06-23 14:54:55.003 [DEBUG] [e.internal.handler.Clip2ThingHandler] - eafb9a2c-15a6-49ec-af65-8920b8c44d45 -> updateState() 'alert' update with 'NO_ACTION' (fullUpdate:false, isDefined:true)
2026-06-23 14:54:55.003 [DEBUG] [e.internal.handler.Clip2ThingHandler] - eafb9a2c-15a6-49ec-af65-8920b8c44d45 -> updateState() 'last-updated' update with '2026-06-23T14:54:55.003572902+0100' (fullUpdate:false, isDefined:true)
2026-06-23 14:54:55.004 [DEBUG] [e.internal.handler.Clip2ThingHandler] - eafb9a2c-15a6-49ec-af65-8920b8c44d45 -> onResource() consumed resource id:01fa810d-31c8-406b-937c-6902058dcfc5, type:light, flags:12

@andrewfg

andrewfg commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Also perhaps we need to go back to this forum thread. See in particular my then comment about not making a hack.

https://community.openhab.org/t/philips-hue-clip-2-api-v2-discussion-thread/142111/369

@jlaur do you want to come back on this?

@andrewfg

andrewfg commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

And furthermore -- for the case that the light is offline due to hard power off -- please keep in mind that in the Hue app every light has a setting for "power on behaviour" i.e. [default, Last on, Stays off, Turns On, Custom]. So even if you have sent a CT value (or indeed any other value) to the device whilst it was hard powered off, the simple act of hard powering it on again will execute the "power on behaviour" and this will OVERRIDE whatever state had been sent to it from OH whilst it was physically off. See example below.

// device hard powered off
2026-06-23 18:22:43.823 [DEBUG] [.internal.handler.Clip2BridgeHandler] - onResourcesEventTask() resource count 1
2026-06-23 18:22:43.825 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateChannels() from resource id:7a47e2a0-6207-492a-8f3a-7156ac1bb2e2, type:zigbee_connectivity
2026-06-23 18:22:43.826 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateConnectivityState() thingStatus:ONLINE, zigbeeStatus:Connectivity issue
2026-06-23 18:22:43.829 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateState() 'last-updated' update with '2026-06-23T18:22:43.828820110+0100' (fullUpdate:false, isDefined:true)
2026-06-23 18:22:43.830 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> onResource() consumed resource id:7a47e2a0-6207-492a-8f3a-7156ac1bb2e2, type:zigbee_connectivity, flags:12
2026-06-23 18:22:59.157 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> handleCommand() put resource id:c6b67058-7e29-4705-81d8-d2fcbe36c7ec, type:light

// send CT 500 Mirek whilst powered off; receive CT 2000K aka 500 Mirek whilst powered off
2026-06-23 18:22:59.158 [DEBUG] [.internal.handler.Clip2BridgeHandler] - putResource() id:c6b67058-7e29-4705-81d8-d2fcbe36c7ec, type:light
2026-06-23 18:22:59.159 [TRACE] [.hue.internal.connection.Clip2Bridge] - PUT https://192.168.1.108/clip/v2/resource/light/c6b67058-7e29-4705-81d8-d2fcbe36c7ec HTTPS/2 >> {"type":"light","id":"c6b67058-7e29-4705-81d8-d2fcbe36c7ec","color_temperature":{"mirek":500}}
2026-06-23 18:22:59.217 [TRACE] [.hue.internal.connection.Clip2Bridge] - HTTPS/2 207 (Content-Type: application/json) << {"data":[{"rid":"c6b67058-7e29-4705-81d8-d2fcbe36c7ec","rtype":"light"}],"errors":[{"description":"device (light) c6b67058-7e29-4705-81d8-d2fcbe36c7ec has communication issues, command (.color_temperature.mirek) may not have effect","error_code":"communication_error"}]}
2026-06-23 18:22:59.218 [INFO ] [e.internal.handler.Clip2ThingHandler] - Command '2000 K' for thing 'hue:device:g24:589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae', channel 'hue:device:g24:589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae:color-temperature-abs' succeeded with errors: device (light) c6b67058-7e29-4705-81d8-d2fcbe36c7ec has communication issues, command (.color_temperature.mirek) may not have effect
2026-06-23 18:22:59.260 [TRACE] [.hue.internal.connection.Clip2Bridge] - onEventData() data:[{"creationtime":"2026-06-23T17:22:59Z","data":[{"color":{"xy":{"x":0.5267,"y":0.4133}},"color_temperature":{"mirek":500,"mirek_valid":true},"id":"c6b67058-7e29-4705-81d8-d2fcbe36c7ec","id_v1":"/lights/40","owner":{"rid":"589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae","rtype":"device"},"service_id":0,"type":"light"}],"id":"bba207f9-f07f-40cc-90ff-1034901db709","type":"update"}]
2026-06-23 18:22:59.261 [DEBUG] [.internal.handler.Clip2BridgeHandler] - onResourcesEventTask() resource count 1
2026-06-23 18:22:59.262 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateChannels() from resource id:c6b67058-7e29-4705-81d8-d2fcbe36c7ec, type:light
2026-06-23 18:22:59.263 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateState() 'color-temperature' update with '100' (fullUpdate:false, isDefined:true)
2026-06-23 18:22:59.264 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateState() 'color-temperature-abs' update with '2000 K' (fullUpdate:false, isDefined:true)
2026-06-23 18:22:59.265 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateState() 'color' update with '35.464,74.43700,100' (fullUpdate:false, isDefined:true)
2026-06-23 18:22:59.266 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateState() 'color-xy-only' update with '35.464,74.43700,100' (fullUpdate:false, isDefined:true)
2026-06-23 18:22:59.267 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateState() 'dimming-only' update with '100' (fullUpdate:false, isDefined:true)
2026-06-23 18:22:59.267 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateState() 'on-off-only' update with 'ON' (fullUpdate:false, isDefined:true)
2026-06-23 18:22:59.268 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateState() 'alert' update with 'NO_ACTION' (fullUpdate:false, isDefined:true)
2026-06-23 18:22:59.269 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateState() 'last-updated' update with '2026-06-23T18:22:59.269317969+0100' (fullUpdate:false, isDefined:true)
2026-06-23 18:22:59.270 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> onResource() consumed resource id:c6b67058-7e29-4705-81d8-d2fcbe36c7ec, type:light, flags:12

// device hard powered on; receive CT 2732K aka 366 Mirek whilst now powered on
// NOTE: this state comes from the "power on behavior" of the light
2026-06-23 18:23:07.757 [TRACE] [.hue.internal.connection.Clip2Bridge] - onEventData() data:[{"creationtime":"2026-06-23T17:23:07Z","data":[{"id":"7a47e2a0-6207-492a-8f3a-7156ac1bb2e2","id_v1":"/lights/40","owner":{"rid":"589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae","rtype":"device"},"status":"connected","type":"zigbee_connectivity"}],"id":"b0aad46b-9ca6-4e6c-bd48-ad0445ca5f29","type":"update"}]
2026-06-23 18:23:07.758 [DEBUG] [.internal.handler.Clip2BridgeHandler] - onResourcesEventTask() resource count 1
2026-06-23 18:23:07.759 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateChannels() from resource id:7a47e2a0-6207-492a-8f3a-7156ac1bb2e2, type:zigbee_connectivity
2026-06-23 18:23:07.759 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateConnectivityState() thingStatus:OFFLINE, zigbeeStatus:Connected
2026-06-23 18:23:07.760 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateState() 'last-updated' update with '2026-06-23T18:23:07.760258414+0100' (fullUpdate:false, isDefined:true)
2026-06-23 18:23:07.760 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> onResource() consumed resource id:7a47e2a0-6207-492a-8f3a-7156ac1bb2e2, type:zigbee_connectivity, flags:12
2026-06-23 18:23:10.759 [TRACE] [.hue.internal.connection.Clip2Bridge] - onEventData() data:[{"creationtime":"2026-06-23T17:23:10Z","data":[{"color":{"xy":{"x":0.4572,"y":0.4099}},"color_temperature":{"mirek":366,"mirek_valid":true},"id":"c6b67058-7e29-4705-81d8-d2fcbe36c7ec","id_v1":"/lights/40","owner":{"rid":"589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae","rtype":"device"},"service_id":0,"type":"light"}],"id":"72cce356-231d-4c25-ab69-4dc0bbad54e2","type":"update"}]
2026-06-23 18:23:10.760 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateServiceContributors() called for 5 contributors
2026-06-23 18:23:10.761 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateResource() from resource id:af3f1291-c109-462f-a884-0a76027a497e, type:motion_area_candidate
2026-06-23 18:23:10.761 [DEBUG] [.internal.handler.Clip2BridgeHandler] - onResourcesEventTask() resource count 1
2026-06-23 18:23:10.762 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateChannels() from resource id:c6b67058-7e29-4705-81d8-d2fcbe36c7ec, type:light
2026-06-23 18:23:10.762 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateState() 'color-temperature' update with '61.38' (fullUpdate:false, isDefined:true)
2026-06-23 18:23:10.764 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateState() 'color-temperature-abs' update with '2732.240437158469945355191256830601 K' (fullUpdate:false, isDefined:true)
2026-06-23 18:23:10.765 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateState() 'color' update with '38.615,52.98800,100' (fullUpdate:false, isDefined:true)
2026-06-23 18:23:10.771 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateState() 'color-xy-only' update with '38.615,52.98800,100' (fullUpdate:false, isDefined:true)
2026-06-23 18:23:10.772 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateState() 'dimming-only' update with '100' (fullUpdate:false, isDefined:true)
2026-06-23 18:23:10.773 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateState() 'on-off-only' update with 'ON' (fullUpdate:false, isDefined:true)
2026-06-23 18:23:10.773 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateState() 'alert' update with 'NO_ACTION' (fullUpdate:false, isDefined:true)
2026-06-23 18:23:10.777 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> updateState() 'last-updated' update with '2026-06-23T18:23:10.777379221+0100' (fullUpdate:false, isDefined:true)
2026-06-23 18:23:10.778 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 589c9a7b-c12c-44dd-9e0f-6a3dfad4f8ae -> onResource() consumed resource id:c6b67058-7e29-4705-81d8-d2fcbe36c7ec, type:light, flags:12

@kaikreuzer

Copy link
Copy Markdown
Member Author

Many thanks for your extensive efforts, @andrewfg!

It certainly is not something that I would call a "refactoring". Clip2 is a whole new, and very different API

Haha, yeah, ok, I didn't mean to belittle the effort - it was definitely a huge challenge and you did a fantastic job!

Sorry that my reply took so long. I only now found the time for a debugging session and it even took me longer than expected.

TL;DR: I tested many different lights and most of them behave quite differently. 🤦

I've created this rule for testing:

rule "CT Test"
then
	Light.sendCommand(100)
	Thread::sleep(1000)
	Light_CT.sendCommand(0)
	Thread::sleep(1000)
	Light.sendCommand(0)
	Thread::sleep(1000)
	Light_CT.sendCommand(100)
	Thread::sleep(1000)
	Light.sendCommand(100)
end

As you can see in the logs, the CT at the end is 0 instead of the expected 100 (and the light itself if cold white) - and after 30 secs, the CT is updated to UNDEF:

Property Value
resourceType Device
vendor _TZ3000_gb5gaeca
resourceArchetype Pendant long
productCertified false
colorTemperatureRange 6536 K .. 2000 K
firmwareVersion 0.0.0
modelId TS0505B
resourceId 31a5ded4-3bf7-4465-833e-ba8913daa78b
productName Extended color light
thingTypeVersion 1
productArchetype Classic bulb
hardwareVersion 1002-1602
2026-06-24 21:08:39.700 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> handleCommand() put resource id:9985ea7b-6ce3-4870-b9b3-2212ee05dc49, type:light
2026-06-24 21:08:39.796 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateChannels() from resource id:9985ea7b-6ce3-4870-b9b3-2212ee05dc49, type:light
2026-06-24 21:08:39.796 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'color-temperature' update with 'UNDEF' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:39.797 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'color-temperature-abs' update with 'UNDEF' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:39.797 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'color' update with '208.984,100,100' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:39.797 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'color-xy-only' update with '208.984,100,100' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:39.798 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'dimming-only' update with '100' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:39.798 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'on-off-only' update with 'ON' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:39.798 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'alert' update with 'NO_ACTION' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:39.798 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'last-updated' update with '2026-06-24T21:08:39.798680+0200' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:39.798 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> onResource() consumed resource id:9985ea7b-6ce3-4870-b9b3-2212ee05dc49, type:light, flags:12
2026-06-24 21:08:40.702 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> handleCommand() put resource id:9985ea7b-6ce3-4870-b9b3-2212ee05dc49, type:light
2026-06-24 21:08:40.815 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateChannels() from resource id:9985ea7b-6ce3-4870-b9b3-2212ee05dc49, type:light
2026-06-24 21:08:40.815 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'color-temperature' update with '0' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:40.816 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'color-temperature-abs' update with '6535.947712418300653594771241830065 K' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:40.816 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'color' update with '188.5715,4.1300,100' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:40.816 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'color-xy-only' update with '188.5715,4.1300,100' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:40.816 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'dimming-only' update with '100' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:40.817 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'on-off-only' update with 'ON' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:40.817 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'alert' update with 'NO_ACTION' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:40.817 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'last-updated' update with '2026-06-24T21:08:40.817279+0200' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:40.817 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> onResource() consumed resource id:9985ea7b-6ce3-4870-b9b3-2212ee05dc49, type:light, flags:12
2026-06-24 21:08:41.709 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> handleCommand() put resource id:9985ea7b-6ce3-4870-b9b3-2212ee05dc49, type:light
2026-06-24 21:08:41.850 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateChannels() from resource id:9985ea7b-6ce3-4870-b9b3-2212ee05dc49, type:light
2026-06-24 21:08:41.850 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'color-temperature' update with '0' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:41.851 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'color-temperature-abs' update with '6535.947712418300653594771241830065 K' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:41.851 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'color' update with '188.5715,4.1300,0' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:41.851 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'color-xy-only' update with '188.5715,4.1300,100' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:41.851 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'dimming-only' update with '0.4000' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:41.852 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'on-off-only' update with 'OFF' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:41.852 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'alert' update with 'NO_ACTION' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:41.852 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'last-updated' update with '2026-06-24T21:08:41.852697+0200' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:41.852 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> onResource() consumed resource id:9985ea7b-6ce3-4870-b9b3-2212ee05dc49, type:light, flags:12
2026-06-24 21:08:42.715 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> handleCommand() put resource id:9985ea7b-6ce3-4870-b9b3-2212ee05dc49, type:light
2026-06-24 21:08:42.750 [INFO ] [e.internal.handler.Clip2ThingHandler] - Command '100' for thing 'hue:device:1:29', channel 'hue:device:1:29:color-temperature' succeeded with errors: device (light) 9985ea7b-6ce3-4870-b9b3-2212ee05dc49 is "soft off", command (.color_temperature.mirek) may not have effect
2026-06-24 21:08:43.725 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> handleCommand() put resource id:9985ea7b-6ce3-4870-b9b3-2212ee05dc49, type:light
2026-06-24 21:08:43.878 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateChannels() from resource id:9985ea7b-6ce3-4870-b9b3-2212ee05dc49, type:light
2026-06-24 21:08:43.878 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'color-temperature' update with '0' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:43.878 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'color-temperature-abs' update with '6535.947712418300653594771241830065 K' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:43.878 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'color' update with '188.5715,4.1300,100' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:43.879 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'color-xy-only' update with '188.5715,4.1300,100' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:43.879 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'dimming-only' update with '100' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:43.879 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'on-off-only' update with 'ON' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:43.879 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'alert' update with 'NO_ACTION' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:43.879 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'last-updated' update with '2026-06-24T21:08:43.879838+0200' (fullUpdate:false, isDefined:true)
2026-06-24 21:08:43.880 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> onResource() consumed resource id:9985ea7b-6ce3-4870-b9b3-2212ee05dc49, type:light, flags:12
2026-06-24 21:09:25.990 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateChannels() from resource id:9985ea7b-6ce3-4870-b9b3-2212ee05dc49, type:light
2026-06-24 21:09:25.990 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'color-temperature' update with 'UNDEF' (fullUpdate:false, isDefined:true)
2026-06-24 21:09:25.990 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'color-temperature-abs' update with 'UNDEF' (fullUpdate:false, isDefined:true)
2026-06-24 21:09:25.991 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'color' update with '208.984,100,100' (fullUpdate:false, isDefined:true)
2026-06-24 21:09:25.991 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'color-xy-only' update with '208.984,100,100' (fullUpdate:false, isDefined:true)
2026-06-24 21:09:25.991 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'dimming-only' update with '100' (fullUpdate:false, isDefined:true)
2026-06-24 21:09:25.991 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'on-off-only' update with 'ON' (fullUpdate:false, isDefined:true)
2026-06-24 21:09:25.992 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'alert' update with 'NO_ACTION' (fullUpdate:false, isDefined:true)
2026-06-24 21:09:25.992 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> updateState() 'last-updated' update with '2026-06-24T21:09:25.992377+0200' (fullUpdate:false, isDefined:true)
2026-06-24 21:09:25.992 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 31a5ded4-3bf7-4465-833e-ba8913daa78b -> onResource() consumed resource id:9985ea7b-6ce3-4870-b9b3-2212ee05dc49, type:light, flags:12

This light behaves the same way:

Property Value
resourceType Device
vendor _TZ3000_v1srfw9x
resourceArchetype Ceiling square
productCertified false
colorTemperatureRange 6536 K .. 2000 K
firmwareVersion 0.0.0
modelId TS0505B
resourceId 9d33eb95-63a7-43ef-bd7d-fe0350b2fa84
productName Extended color light
thingTypeVersion 1
productArchetype Classic bulb
hardwareVersion 1002-1602

This light works perfectly fine, although it also logs the INFO error and updates CT to 0 (although the light is turned on as warm white i.e. 100) - only 30 secs later it correctly updates CT to 100:

Property Value
resourceType Device
vendor Neuhaus Lighting Group
resourceArchetype Classic bulb
productCertified false
colorTemperatureRange 5000 K .. 2703 K
firmwareVersion 1001
modelId NLG-CCT light
resourceId 4694417e-2bf8-4995-9a48-26c8d43dbf78
productName Color temperature light
thingTypeVersion 1
productArchetype Classic bulb
hardwareVersion 1037-1220
2026-06-24 20:54:20.845 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> handleCommand() put resource id:5c3e01ff-a18c-4299-892e-6ab4c90c62b2, type:light
2026-06-24 20:54:21.845 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> handleCommand() put resource id:5c3e01ff-a18c-4299-892e-6ab4c90c62b2, type:light
2026-06-24 20:54:21.922 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateChannels() from resource id:5c3e01ff-a18c-4299-892e-6ab4c90c62b2, type:light
2026-06-24 20:54:21.922 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'color-temperature' update with '0' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:21.923 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'color-temperature-abs' update with '5000 K' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:21.923 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'brightness' update with '100' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:21.923 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'dimming-only' update with '100' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:21.923 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'on-off-only' update with 'ON' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:21.923 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'alert' update with 'NO_ACTION' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:21.924 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'last-updated' update with '2026-06-24T20:54:21.924085+0200' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:21.924 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> onResource() consumed resource id:5c3e01ff-a18c-4299-892e-6ab4c90c62b2, type:light, flags:12
2026-06-24 20:54:22.853 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> handleCommand() put resource id:5c3e01ff-a18c-4299-892e-6ab4c90c62b2, type:light
2026-06-24 20:54:23.859 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> handleCommand() put resource id:5c3e01ff-a18c-4299-892e-6ab4c90c62b2, type:light
2026-06-24 20:54:23.887 [INFO ] [e.internal.handler.Clip2ThingHandler] - Command '100' for thing 'hue:device:1:20', channel 'hue:device:1:20:color-temperature' succeeded with errors: device (light) 5c3e01ff-a18c-4299-892e-6ab4c90c62b2 is "soft off", command (.color_temperature.mirek) may not have effect
2026-06-24 20:54:23.938 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateChannels() from resource id:5c3e01ff-a18c-4299-892e-6ab4c90c62b2, type:light
2026-06-24 20:54:23.939 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'color-temperature' update with '0' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:23.939 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'color-temperature-abs' update with '5000 K' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:23.939 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'brightness' update with '0' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:23.939 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'dimming-only' update with '0.4000' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:23.940 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'on-off-only' update with 'OFF' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:23.940 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'alert' update with 'NO_ACTION' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:23.940 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'last-updated' update with '2026-06-24T20:54:23.940512+0200' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:23.940 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> onResource() consumed resource id:5c3e01ff-a18c-4299-892e-6ab4c90c62b2, type:light, flags:12
2026-06-24 20:54:24.863 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> handleCommand() put resource id:5c3e01ff-a18c-4299-892e-6ab4c90c62b2, type:light
2026-06-24 20:54:24.949 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateChannels() from resource id:5c3e01ff-a18c-4299-892e-6ab4c90c62b2, type:light
2026-06-24 20:54:24.949 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'color-temperature' update with '0' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:24.949 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'color-temperature-abs' update with '5000 K' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:24.950 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'brightness' update with '100' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:24.950 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'dimming-only' update with '100' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:24.950 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'on-off-only' update with 'ON' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:24.950 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'alert' update with 'NO_ACTION' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:24.950 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'last-updated' update with '2026-06-24T20:54:24.950732+0200' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:24.950 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> onResource() consumed resource id:5c3e01ff-a18c-4299-892e-6ab4c90c62b2, type:light, flags:12
2026-06-24 20:54:55.213 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateChannels() from resource id:5c3e01ff-a18c-4299-892e-6ab4c90c62b2, type:light
2026-06-24 20:54:55.213 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'color-temperature' update with '100' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:55.214 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'color-temperature-abs' update with '2702.702702702702702702702702702703 K' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:55.214 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'brightness' update with '100' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:55.214 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'dimming-only' update with '100' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:55.214 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'on-off-only' update with 'ON' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:55.214 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'alert' update with 'NO_ACTION' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:55.214 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> updateState() 'last-updated' update with '2026-06-24T20:54:55.214792+0200' (fullUpdate:false, isDefined:true)
2026-06-24 20:54:55.214 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> onResource() consumed resource id:5c3e01ff-a18c-4299-892e-6ab4c90c62b2, type:light, flags:12
2026-06-24 20:55:00.665 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 4694417e-2bf8-4995-9a48-26c8d43dbf78 -> handleCommand() put resource id:5c3e01ff-a18c-4299-892e-6ab4c90c62b2, type:light

And this one works as expected (i.e. it is "warm white" at the end), while it logs the INFO error, sets CT to 0 and the end and to UNDEF after 30 seconds:

Property Value
resourceType Device
vendor MLI
resourceArchetype Ceiling square
productCertified false
colorTemperatureRange 6452 K .. 1818 K
firmwareVersion 2.5.3
modelId RGB-CCT
resourceId 5a47411d-a8bf-4925-93c3-bb3869b2bb6d
productName Extended color light
thingTypeVersion 1
productArchetype Classic bulb
hardwareVersion 121b-7d2
2026-06-24 21:15:53.669 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateChannels() from resource id:99221d17-33be-43a9-9944-c075ad040fe8, type:light
2026-06-24 21:15:53.669 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'color-temperature' update with 'UNDEF' (fullUpdate:false, isDefined:true)
2026-06-24 21:15:53.669 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'color-temperature-abs' update with 'UNDEF' (fullUpdate:false, isDefined:true)
2026-06-24 21:15:53.669 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'color' update with '30.967,87.32800,100' (fullUpdate:false, isDefined:true)
2026-06-24 21:15:53.670 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'color-xy-only' update with '30.967,87.32800,100' (fullUpdate:false, isDefined:true)
2026-06-24 21:15:53.670 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'dimming-only' update with '100' (fullUpdate:false, isDefined:true)
2026-06-24 21:15:53.670 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'on-off-only' update with 'ON' (fullUpdate:false, isDefined:true)
2026-06-24 21:15:53.670 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'alert' update with 'NO_ACTION' (fullUpdate:false, isDefined:true)
2026-06-24 21:15:53.670 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'last-updated' update with '2026-06-24T21:15:53.670698+0200' (fullUpdate:false, isDefined:true)
2026-06-24 21:15:53.670 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> onResource() consumed resource id:99221d17-33be-43a9-9944-c075ad040fe8, type:light, flags:12
2026-06-24 21:16:01.443 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> handleCommand() put resource id:99221d17-33be-43a9-9944-c075ad040fe8, type:light
2026-06-24 21:16:02.442 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> handleCommand() put resource id:99221d17-33be-43a9-9944-c075ad040fe8, type:light
2026-06-24 21:16:02.533 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateChannels() from resource id:99221d17-33be-43a9-9944-c075ad040fe8, type:light
2026-06-24 21:16:02.533 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'color-temperature' update with '0' (fullUpdate:false, isDefined:true)
2026-06-24 21:16:02.534 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'color-temperature-abs' update with '6451.612903225806451612903225806452 K' (fullUpdate:false, isDefined:true)
2026-06-24 21:16:02.534 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'color' update with '181.5223,3.42900,100' (fullUpdate:false, isDefined:true)
2026-06-24 21:16:02.534 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'color-xy-only' update with '181.5223,3.42900,100' (fullUpdate:false, isDefined:true)
2026-06-24 21:16:02.535 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'dimming-only' update with '100' (fullUpdate:false, isDefined:true)
2026-06-24 21:16:02.535 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'on-off-only' update with 'ON' (fullUpdate:false, isDefined:true)
2026-06-24 21:16:02.535 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'alert' update with 'NO_ACTION' (fullUpdate:false, isDefined:true)
2026-06-24 21:16:02.535 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'last-updated' update with '2026-06-24T21:16:02.535473+0200' (fullUpdate:false, isDefined:true)
2026-06-24 21:16:02.535 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> onResource() consumed resource id:99221d17-33be-43a9-9944-c075ad040fe8, type:light, flags:12
2026-06-24 21:16:03.444 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> handleCommand() put resource id:99221d17-33be-43a9-9944-c075ad040fe8, type:light
2026-06-24 21:16:04.448 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> handleCommand() put resource id:99221d17-33be-43a9-9944-c075ad040fe8, type:light
2026-06-24 21:16:04.477 [INFO ] [e.internal.handler.Clip2ThingHandler] - Command '100' for thing 'hue:device:1:30', channel 'hue:device:1:30:color-temperature' succeeded with errors: device (light) 99221d17-33be-43a9-9944-c075ad040fe8 is "soft off", command (.color_temperature.mirek) may not have effect
2026-06-24 21:16:04.551 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateChannels() from resource id:99221d17-33be-43a9-9944-c075ad040fe8, type:light
2026-06-24 21:16:04.551 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'color-temperature' update with '0' (fullUpdate:false, isDefined:true)
2026-06-24 21:16:04.552 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'color-temperature-abs' update with '6451.612903225806451612903225806452 K' (fullUpdate:false, isDefined:true)
2026-06-24 21:16:04.552 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'color' update with '181.5223,3.42900,0' (fullUpdate:false, isDefined:true)
2026-06-24 21:16:04.552 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'color-xy-only' update with '181.5223,3.42900,100' (fullUpdate:false, isDefined:true)
2026-06-24 21:16:04.552 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'dimming-only' update with '0.4000' (fullUpdate:false, isDefined:true)
2026-06-24 21:16:04.553 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'on-off-only' update with 'OFF' (fullUpdate:false, isDefined:true)
2026-06-24 21:16:04.553 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'alert' update with 'NO_ACTION' (fullUpdate:false, isDefined:true)
2026-06-24 21:16:04.553 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'last-updated' update with '2026-06-24T21:16:04.553314+0200' (fullUpdate:false, isDefined:true)
2026-06-24 21:16:04.553 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> onResource() consumed resource id:99221d17-33be-43a9-9944-c075ad040fe8, type:light, flags:12
2026-06-24 21:16:05.458 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> handleCommand() put resource id:99221d17-33be-43a9-9944-c075ad040fe8, type:light
2026-06-24 21:16:05.582 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateChannels() from resource id:99221d17-33be-43a9-9944-c075ad040fe8, type:light
2026-06-24 21:16:05.583 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'color-temperature' update with '0' (fullUpdate:false, isDefined:true)
2026-06-24 21:16:05.583 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'color-temperature-abs' update with '6451.612903225806451612903225806452 K' (fullUpdate:false, isDefined:true)
2026-06-24 21:16:05.583 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'color' update with '181.5223,3.42900,100' (fullUpdate:false, isDefined:true)
2026-06-24 21:16:05.583 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'color-xy-only' update with '181.5223,3.42900,100' (fullUpdate:false, isDefined:true)
2026-06-24 21:16:05.584 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'dimming-only' update with '100' (fullUpdate:false, isDefined:true)
2026-06-24 21:16:05.584 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'on-off-only' update with 'ON' (fullUpdate:false, isDefined:true)
2026-06-24 21:16:05.584 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'alert' update with 'NO_ACTION' (fullUpdate:false, isDefined:true)
2026-06-24 21:16:05.584 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'last-updated' update with '2026-06-24T21:16:05.584597+0200' (fullUpdate:false, isDefined:true)
2026-06-24 21:16:05.584 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> onResource() consumed resource id:99221d17-33be-43a9-9944-c075ad040fe8, type:light, flags:12
2026-06-24 21:17:11.371 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateChannels() from resource id:99221d17-33be-43a9-9944-c075ad040fe8, type:light
2026-06-24 21:17:11.371 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'color-temperature' update with 'UNDEF' (fullUpdate:false, isDefined:true)
2026-06-24 21:17:11.371 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'color-temperature-abs' update with 'UNDEF' (fullUpdate:false, isDefined:true)
2026-06-24 21:17:11.372 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'color' update with '30.967,87.32800,100' (fullUpdate:false, isDefined:true)
2026-06-24 21:17:11.372 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'color-xy-only' update with '30.967,87.32800,100' (fullUpdate:false, isDefined:true)
2026-06-24 21:17:11.372 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'dimming-only' update with '100' (fullUpdate:false, isDefined:true)
2026-06-24 21:17:11.372 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'on-off-only' update with 'ON' (fullUpdate:false, isDefined:true)
2026-06-24 21:17:11.372 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'alert' update with 'NO_ACTION' (fullUpdate:false, isDefined:true)
2026-06-24 21:17:11.373 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> updateState() 'last-updated' update with '2026-06-24T21:17:11.373122+0200' (fullUpdate:false, isDefined:true)
2026-06-24 21:17:11.373 [DEBUG] [e.internal.handler.Clip2ThingHandler] - 5a47411d-a8bf-4925-93c3-bb3869b2bb6d -> onResource() consumed resource id:99221d17-33be-43a9-9944-c075ad040fe8, type:light, flags:12

I agree that this PR is not making the situation any better, I'll hence close it.
I'll instead create dedicated issues for the effects like the INFO error and the UNDEF setting as a start.

@kaikreuzer kaikreuzer closed this Jun 24, 2026
@kaikreuzer

kaikreuzer commented Jun 24, 2026

Copy link
Copy Markdown
Member Author

See #21043, #21044 and #21045.

@kaikreuzer kaikreuzer deleted the kaikreuzer-hue-soft-off-regression branch June 24, 2026 19:28
@jlaur

jlaur commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Also perhaps we need to go back to this forum thread. See in particular my then comment about not making a hack.

https://community.openhab.org/t/philips-hue-clip-2-api-v2-discussion-thread/142111/369

@jlaur do you want to come back on this?

After reading that thread again, I'm starting to remember the complexity of this. I noticed the same issue as @kaikreuzer back then, but like you was not able to propose any "clean" solution.

Reading about Kai's lights with different behavior, and the minimum dimming level from the forum thread, just one side comment: I was quite recently playing with this in context of #20912, and have one remaining issue with the Hue binding still not sorted out. For some of my lights, e.g. IKEA Trådfri, the minimum dimming level is not reported. When sending the command "0.4", the light doesn't actually turn on. This is a problem when forwarding commands from the Hue emulation. However, for other lights, such as the Hue Signe floor lamp I have in my office, such a command will actually turn on the lamp, although very dimmed (it reports dimming range 0.0%-100%). So compatiblity between devices seems like a topic on its own. I'll probably create an issue to track these findings as I need to come up with some kind of solution.

And furthermore -- for the case that the light is offline due to hard power off -- please keep in mind that in the Hue app every light has a setting for "power on behaviour" i.e. [default, Last on, Stays off, Turns On, Custom].

Please note that this only applies for original Hue lights, not other Zigbee lights controlled by the bridge.

@andrewfg

Copy link
Copy Markdown
Contributor

@kaikreuzer many thanks for the testing. I will analyze to see if there is any common conclusion.

@jlaur thanks for the input about the Tradfri lights. I have some too so I will analyze. I thought we applied a default minimum dimming level for such, but it is evidently not working..

@andrewfg

andrewfg commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

@kaikreuzer again many thanks for the logs.

I had a quick look at your logs, and I have a few observations already. Maybe more to come..

  1. It looks like the logs you posted are all for third party products; seems to be Tuya, Neuhaus, and Mueller (?). Which probably explains why I don't see such issues in my all Philips installation. Just out of interest can you check if they have productCertified property == true? ;)

  2. The logs for the last two devices show a common pattern: we can see all of the five PUT requests from the binding spaced exactly at 1 second intervals. But there are only three SSE event packages! One each for the first two PUT pairs, and one for the last singleton PUT. Legally devices are allowed to (even supposed to) amalgamate fast occurring events into common event packages to save bandwidth. However the interesting thing is that after the fifth PUT the event package comes almost immediately, so the devices are not not just applying a 1Hz throttling interval. Therefore it would be most interesting to try the following: 1) increase the sleep intervals in your script, and 2) turn on TRACE to see the exact contents of the SSE event packages.

  3. I notice that when your script send dimming=0, the binding is applying dimming=0.4% .. which is curiously similar to @jlaur's Ikea Tradfri use case. So can you please report the value of their dimmingRange properties? And if as @jlaur says, they have no such dimmingRange property, it may be that the binding is applying a default 0.4% minimum. (??) And therefore perhaps the lamp is rounding that down to 0% and perhaps forcing the device into the traumatic "soft off" state. => So I have in mind that in the case of devices that do not report a dimmingRange the binding shall apply a default of (say) 2% rather than 0.4% .. which may therefore eliminate the issue entirely. => TBD

  4. THEREFORE -- apropos your request to reduce the logging level for the soft off warning -- I am thinking perhaps to leave it at INFO for devices having productCertified == true; and only reduce it DEBUG for other devices. Albeit there is quite a strong argument for this change be the other way round since it otherwise masks a real issue for "bad" devices. => WDYT?

@andrewfg

andrewfg commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

^ .. apropos IKEA Tradfri: My own such lights have the following attributes and behaviour:

  • productCertified == false
  • dimmingRange == null
  • when I dim them to absolute minimum via a Hue dimmer pad their dimming state => 1%
  • and when I dim them to 0.5% via the binding I can force them to produce a "soft off" error as below..

Ergo: this tends to reinforce the points and questions in @jlaur's and my prior posts above. But since my Tradfri's devices do not support CT, I cannot try @kaikreuzer 's tests. Although I may see if I can order an IKEA Tradfri with CT to play around with.

In any case, I am inclined to force a default minimum dimming level of 1.0% on any device which does not support its own dimmingRange property. This is exactly what the Hue system itself does when a dimmer switch commands such lights directly. And should therefore eliminate 'soft off' errors.

2026-06-25 13:55:09.310 [TRACE] [.hue.internal.connection.Clip2Bridge] - PUT https://192.168.1.108/clip/v2/resource/light/29e37aaf-abf6-4e5d-8018-37ba8048cfec HTTPS/2 >> {"type":"light","id":"29e37aaf-abf6-4e5d-8018-37ba8048cfec","dimming":{"brightness":0.5}}
2026-06-25 13:55:09.336 [TRACE] [.hue.internal.connection.Clip2Bridge] - HTTPS/2 207 (Content-Type: application/json) << {"data":[{"rid":"29e37aaf-abf6-4e5d-8018-37ba8048cfec","rtype":"light"}],"errors":[{"description":"device (light) 29e37aaf-abf6-4e5d-8018-37ba8048cfec is \"soft off\", command (.dimming.brightness) may not have effect","error_code":"attribute_may_have_no_effect"}]}
2026-06-25 13:55:09.337 [INFO ] [e.internal.handler.Clip2ThingHandler] - Command '0' for thing 'hue:device:g24:18212397-8c4d-4373-8f59-c047b80994ac', channel 'hue:device:g24:18212397-8c4d-4373-8f59-c047b80994ac:dimming-only' succeeded with errors: device (light) 29e37aaf-abf6-4e5d-8018-37ba8048cfec is "soft off", command (.dimming.brightness) may not have effect

@andrewfg

andrewfg commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

@jlaur some comments..

For some of my lights, e.g. IKEA Trådfri, the minimum dimming level is not reported. When sending the command "0.4", the light doesn't actually turn on. This is a problem when forwarding commands from the Hue emulation.

However, for other lights, such as the Hue Signe floor lamp I have in my office, such a command will actually turn on the lamp, although very dimmed (it reports dimming range 0.0%-100%).

These two observations are consistent with the current logic.

  1. OH issues a dimmingbrightness *) command above the minimum dimming level, and the binding does the following:

    • the dimming command sent to the binding is verbatim to the command from by OH
    • AND it appends an on/off 'ON' command to the command json
  2. OH issues a dimmingbrightness *) command below the minimum dimming level, and the binding does the following:

    • the dimming command sent to the binding is clamped to the minimum dimming level
    • AND it appends an on/off 'ON' or 'OFF' command to the command json

The minimum dimming level is whatever value is reported by the device or 0.5% if the device does not report it. So your IKEA lamp follows logic branch 2. above and your Signe lamp follows logic branch 1. above.

So compatiblity between devices seems like a topic on its own.

I hear what you say. However it is obvious that Philips / Signify defines different minimum dimming levels on their devices for a distinct reason. (Just as they define different color gamuts on their different devices). So therefore -- per definition -- there is actually no compatiblity between devices that have different minimum levels .. they will track each other compatibly from dimming 100% down to their respective minimum dimming levels, but below that level the compatibility is indeed broken. This is a physical fact that depends only on the hardware of the two respective devices. We cannot dream to solve this via software..

*) note that this is a case where a brightness (as issued by your script) is not the same as a dimming-only command, the former appends an "OFF" to the JSON whereas the latter does not. This is why we have dimming-only and the like .. in order to decouple the "munging"..

1. brightness command (with munging)

            case CHANNEL_2_BRIGHTNESS:
                putResource = Objects.nonNull(putResource) ? putResource : new Resource(lightResourceType);
                if (command instanceof IncreaseDecreaseType increaseDecreaseCommand && Objects.nonNull(cache)) {
                    command = translateIncreaseDecreaseCommand(increaseDecreaseCommand, cache.getBrightnessState());
                }
                if (command instanceof PercentType brightnessCommand) {
                    putResource = Setters.setDimming(putResource, brightnessCommand, cache);
                    Double minDimLevel = Objects.nonNull(cache) ? cache.getMinimumDimmingLevel() : null;
                    minDimLevel = Objects.nonNull(minDimLevel) ? minDimLevel : Dimming.DEFAULT_MINIMUM_DIMMIMG_LEVEL;
                    command = OnOffType.from(brightnessCommand.doubleValue() >= minDimLevel);
                }
                // NB fall through for handling of switch related commands !!

            case CHANNEL_2_SWITCH:
                putResource = Objects.nonNull(putResource) ? putResource : new Resource(lightResourceType);
                putResource.setOnOff(command);
                break;

1. dimming only and on-off-only commands (WITHOUT munging)

            case CHANNEL_2_DIMMING_ONLY:
                putResource = Setters.setDimming(new Resource(lightResourceType), command, cache);
                break;

            case CHANNEL_2_ON_OFF_ONLY:
                putResource = new Resource(lightResourceType).setOnOff(command);
                break;

@andrewfg

Copy link
Copy Markdown
Contributor

@kaikreuzer some further thoughts apropos the 0.4% reported by all of your logs: It is not a clamping to the default min dim level COMMAND as I had earlier surmised (the default clamp level is 0.5). Actually 0.4 is what the device sends in its RESPONSE after the command is sent. So the sequence is

  1. your rule sends dimming = 0%
  2. EITHER a) the device has reported a minimum dimming level of 0.4% in which case the binding clamps the command to 0.4% in the JSON and appends an OFF command to the JSON, OR b) the device has NOT reported a minimum dimming level in which case the binding clamps the command to 0.5% default in the JSON and appends an OFF command to the JSON
  3. the device responds with 0.4% .. which is compatible with 2a) above, or otherwise totally confusing to me..

FACIT I really really need to see your above three test results again but at log TRACE; plus their respective values of productCertified and dimmingRange properties.

@kaikreuzer

Copy link
Copy Markdown
Member Author

Thanks @andrewfg, I'll do the tests and create the logs that you asked for. Hope to find some time for that in the coming days, so please be patient.

@jlaur

jlaur commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

@andrewfg - I have now created an issue and provided my findings there: #21057

@andrewfg

Copy link
Copy Markdown
Contributor

I'll do the tests and create the logs that you asked for.
Hope to find some time for that in the coming days, so please be patient.

@kaikreuzer perhaps to save time, try running the tests on my #21062 branch..

@andrewfg

andrewfg commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Hmm. @kaikreuzer while waiting for your logs, I bought a Lidl Livarno light (vendor: _TZ3000_49qchf10, modelId: TS0502A) which I think is from the same stable as some of your misbehaving lights.

I noticed immediately that it does support a color temperature mirek schema (see below) which should potentially fix out of range UNDEF color temperature errors.

HOWEVER using this value would actually be far far worse than wrong using the default schema. At least using the default schema does not crash the binding. So this leaves me in a difficult situation not knowing how to proceed...

The light's packaging says the CT range is 2200K .. 6500K (which is 454Mk .. 153Mk) .. however as you can see its JSON is brain dead. (I suppose the 65535 may be a wrong statement of the K upper limit .. but the 0 value is completely and utterly brain dead). It even crashes my code with a divide by zero error.

=> @kaikreuzer and @jlaure I would appreciate you thoughts on this.

"color_temperature": {
    "mirek": 153,
    "mirek_valid": true,
    "mirek_schema": {
        "mirek_minimum": 0,
        "mirek_maximum": 65535
    }
},

@kaikreuzer

Copy link
Copy Markdown
Member Author

Hi @andrewfg, thanks for following up on this and sorry for me falling quiet - I was actually busy with 5.2 preparations and now it is vacation time, so I probably won't find time for in-depth testing the next weeks and have to ask you for patience.
As you now have a misbehaving light yourself, I guess you do not rely on my testing that much anymore, that's great.
Indeed, these cheap lights seem to report buggy values, which will be tricky to handle.

Maybe the best is trying to figure out if reported values do not make any sense (such as the 0-65535 range) and simply ignore them and just go for sensible defaults. Or alternatively, do not support the CT-abs channel at all for such devices, which is probably the cleaner solution (assuming you can still do the CT 0-100% support without issues).

@andrewfg

andrewfg commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

guess you do not rely on my testing that much anymore

Indeed. So I think that #21062 has fixed all of your issues. But obviously before we merge it, it would be good if you can test it and confirm that your issues are indeed fixed. For convenience, the JAR is in the first post of the PR so you can simply drop and test.

@kaikreuzer

Copy link
Copy Markdown
Member Author

Great - I'll test your PR next week!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[hue] Hue binding logs INFO and ignores queued color temperature while light is soft-off

3 participants