From 174a519c038607f1771c298f6b30b4318f4c5588 Mon Sep 17 00:00:00 2001 From: Paul Spende Date: Sat, 11 Jul 2026 18:23:38 +0100 Subject: [PATCH 1/2] Guard hs_color against bulbs that do not support HS async_turn_on (both ikea_bulb and ikea_bulb_device_set) unconditionally sent an hs color to the hub and set color_mode = ColorMode.HS whenever an ATTR_HS_COLOR was present, without checking that the bulb actually supports HS. For a color_temp-only bulb (e.g. KAJPLATS GU10 WS) reached via a mixed device set, this makes the entity report color_mode=hs while its supported_color_modes is [color_temp], so HA core rejects the state write: set to unsupported color mode hs, expected color_temp repeatedly flooding the log and leaving the color command half-applied. Only apply the hs color / switch to ColorMode.HS when HS is in the bulb's supported color modes; otherwise ignore the request and log at debug. Co-Authored-By: Claude Opus 4.8 (1M context) --- custom_components/dirigera_platform/light.py | 25 ++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/custom_components/dirigera_platform/light.py b/custom_components/dirigera_platform/light.py index 1848870..556f513 100644 --- a/custom_components/dirigera_platform/light.py +++ b/custom_components/dirigera_platform/light.py @@ -331,7 +331,7 @@ async def async_turn_on(self, **kwargs): self._color_mode = ColorMode.COLOR_TEMP self._ignore_update = True - if ATTR_HS_COLOR in kwargs: + if ATTR_HS_COLOR in kwargs and ColorMode.HS in self._supported_color_modes: logger.debug("Request to set color HS") hs_tuple = kwargs[ATTR_HS_COLOR] self._color_hue = hs_tuple[0] @@ -341,6 +341,15 @@ async def async_turn_on(self, **kwargs): await self.hass.async_add_executor_job(self._json_data.set_light_color,self._color_hue, self._color_saturation) self._color_mode = ColorMode.HS self._ignore_update = True + elif ATTR_HS_COLOR in kwargs: + # A hs_color was requested for a bulb that does not support HS + # (e.g. a color_temp-only bulb reached via a mixed device set). + # Ignore it instead of forcing color_mode=hs, which HA core rejects + # with "unsupported color mode hs, expected color_temp". + logger.debug( + "Ignoring hs_color for %s: HS not in supported color modes %s", + self.name, self._supported_color_modes, + ) self.async_schedule_update_ha_state(False) except Exception as ex: logger.error("error encountered turning on : {}".format(self.name)) @@ -494,15 +503,23 @@ async def async_turn_on(self, **kwargs): await self.hass.async_add_executor_job(self.patch_command, {"colorTemperature" : ct}) self._controller._ignore_update = True - if ATTR_HS_COLOR in kwargs: + if ATTR_HS_COLOR in kwargs and ColorMode.HS in self._controller.supported_color_modes: logger.debug("Request to set color HS device_set") hs_tuple = kwargs[ATTR_HS_COLOR] self._color_hue = hs_tuple[0] self._color_saturation = hs_tuple[1] / 100 # Saturation is 0 - 1 at IKEA - self._controller._ignore_update = True - + self._controller._ignore_update = True + await self.hass.async_add_executor_job(self.patch_command,{ "colorHue" : self._color_hue, "colorSaturation" : self._color_saturation}) + elif ATTR_HS_COLOR in kwargs: + # hs_color requested for a device set whose controller bulb does not + # support HS (color_temp-only). Ignore it to avoid pushing an + # unsupported color mode to the group. + logger.debug( + "Ignoring hs_color for device_set %s: HS not in supported color modes %s", + self.name, self._controller.supported_color_modes, + ) except Exception as ex: logger.error("error encountered turning on device_set : {}".format(self.name)) From 50961593981508ecaa2f2ba06ddf4298c0304a1c Mon Sep 17 00:00:00 2001 From: Paul Spende Date: Sat, 11 Jul 2026 18:34:04 +0100 Subject: [PATCH 2/2] Guard hub-event color_mode updates against unsupported HS hub_event_listener sets entity._color_mode = ColorMode.HS whenever a deviceStateChanged or sceneUpdated event carries a colorHue/colorSaturation attribute, without checking the bulb supports HS. For a color_temp-only bulb that receives a colorHue attribute via a mixed device set / group scene, this makes the entity report color_mode=hs against supported_color_modes [color_temp], and HA core rejects every subsequent state write with "unsupported color mode hs, expected color_temp" - firing on each hub event and on startup state replay. This is the primary source of the log flood; the async_turn_on guard in the previous commit covers the service-call path. Only switch to HS / COLOR_TEMP when that mode is in the entity's supported_color_modes. --- .../dirigera_platform/hub_event_listener.py | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/custom_components/dirigera_platform/hub_event_listener.py b/custom_components/dirigera_platform/hub_event_listener.py index 7b5b94f..01cdeaa 100644 --- a/custom_components/dirigera_platform/hub_event_listener.py +++ b/custom_components/dirigera_platform/hub_event_listener.py @@ -326,12 +326,17 @@ def _apply_scene_actions(self, msg): except Exception as ex: logger.warning(f"Scene action: failed to set {key} on {device_id}: {ex}") - # Update color_mode based on scene attributes + # Update color_mode based on scene attributes. + # Only switch to a mode the bulb actually supports - otherwise HA core + # rejects the state write with "unsupported color mode hs, expected + # color_temp" (e.g. a color_temp-only bulb in a mixed device set that + # receives a colorHue attribute from a group scene). if updated and hasattr(entity, '_color_mode'): - if "colorHue" in attributes or "colorSaturation" in attributes: + supported = getattr(entity, 'supported_color_modes', None) or [] + if ("colorHue" in attributes or "colorSaturation" in attributes) and ColorMode.HS in supported: entity._color_mode = ColorMode.HS logger.debug(f"Scene action: set color_mode to HS for {device_id}") - elif "colorTemperature" in attributes: + elif "colorTemperature" in attributes and ColorMode.COLOR_TEMP in supported: entity._color_mode = ColorMode.COLOR_TEMP logger.debug(f"Scene action: set color_mode to COLOR_TEMP for {device_id}") @@ -602,11 +607,14 @@ def on_message(self, ws:Any, ws_msg:str): logger.warn(f"Failed to set attribute key: {key} converted to {key_attr} on device: {id}") logger.warn(ex) - # Update color_mode for lights when color attributes change + # Update color_mode for lights when color attributes change. + # Guard against switching to a mode the bulb does not support + # (see _apply_scene_actions) to avoid HA core rejecting the write. if device_type == "light" and hasattr(entity, '_color_mode'): - if "colorHue" in attributes or "colorSaturation" in attributes: + supported = getattr(entity, 'supported_color_modes', None) or [] + if ("colorHue" in attributes or "colorSaturation" in attributes) and ColorMode.HS in supported: entity._color_mode = ColorMode.HS - elif "colorTemperature" in attributes: + elif "colorTemperature" in attributes and ColorMode.COLOR_TEMP in supported: entity._color_mode = ColorMode.COLOR_TEMP # Lights behave odd with hubs when setting attribute one event is generated which