From fabf8802f5b5db81ff790a42d661dd00099d250f Mon Sep 17 00:00:00 2001 From: Martin Hjelmare Date: Thu, 25 Jan 2024 09:15:38 +0100 Subject: [PATCH] Fix matter color modes (#108804) * Fix matter light color modes * Make onoff light fixture only onoff * Make dimmable light only a dimmable light * Make color temp light fixture only a color temp light --- homeassistant/components/matter/light.py | 64 ++++++++--------- .../nodes/color-temperature-light.json | 34 +--------- .../matter/fixtures/nodes/dimmable-light.json | 44 +----------- .../matter/fixtures/nodes/onoff-light.json | 68 +------------------ 4 files changed, 34 insertions(+), 176 deletions(-) diff --git a/homeassistant/components/matter/light.py b/homeassistant/components/matter/light.py index 43c47046162..7e6f42f44b4 100644 --- a/homeassistant/components/matter/light.py +++ b/homeassistant/components/matter/light.py @@ -14,6 +14,7 @@ from homeassistant.components.light import ( ColorMode, LightEntity, LightEntityDescription, + filter_supported_color_modes, ) from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform @@ -53,30 +54,9 @@ class MatterLight(MatterEntity, LightEntity): """Representation of a Matter light.""" entity_description: LightEntityDescription - - @property - def supports_color(self) -> bool: - """Return if the device supports color control.""" - if not self._attr_supported_color_modes: - return False - return ( - ColorMode.HS in self._attr_supported_color_modes - or ColorMode.XY in self._attr_supported_color_modes - ) - - @property - def supports_color_temperature(self) -> bool: - """Return if the device supports color temperature control.""" - if not self._attr_supported_color_modes: - return False - return ColorMode.COLOR_TEMP in self._attr_supported_color_modes - - @property - def supports_brightness(self) -> bool: - """Return if the device supports bridghtness control.""" - if not self._attr_supported_color_modes: - return False - return ColorMode.BRIGHTNESS in self._attr_supported_color_modes + _supports_brightness = False + _supports_color = False + _supports_color_temperature = False async def _set_xy_color(self, xy_color: tuple[float, float]) -> None: """Set xy color.""" @@ -283,7 +263,7 @@ class MatterLight(MatterEntity, LightEntity): ): await self._set_color_temp(color_temp) - if brightness is not None and self.supports_brightness: + if brightness is not None and self._supports_brightness: await self._set_brightness(brightness) return @@ -302,12 +282,13 @@ class MatterLight(MatterEntity, LightEntity): """Update from device.""" if self._attr_supported_color_modes is None: # work out what (color)features are supported - supported_color_modes: set[ColorMode] = set() + supported_color_modes = {ColorMode.ONOFF} # brightness support if self._entity_info.endpoint.has_attribute( None, clusters.LevelControl.Attributes.CurrentLevel ): supported_color_modes.add(ColorMode.BRIGHTNESS) + self._supports_brightness = True # colormode(s) if self._entity_info.endpoint.has_attribute( None, clusters.ColorControl.Attributes.ColorMode @@ -325,19 +306,23 @@ class MatterLight(MatterEntity, LightEntity): & clusters.ColorControl.Bitmaps.ColorCapabilities.kHueSaturationSupported ): supported_color_modes.add(ColorMode.HS) + self._supports_color = True if ( capabilities & clusters.ColorControl.Bitmaps.ColorCapabilities.kXYAttributesSupported ): supported_color_modes.add(ColorMode.XY) + self._supports_color = True if ( capabilities & clusters.ColorControl.Bitmaps.ColorCapabilities.kColorTemperatureSupported ): supported_color_modes.add(ColorMode.COLOR_TEMP) + self._supports_color_temperature = True + supported_color_modes = filter_supported_color_modes(supported_color_modes) self._attr_supported_color_modes = supported_color_modes LOGGER.debug( @@ -347,8 +332,17 @@ class MatterLight(MatterEntity, LightEntity): ) # set current values + self._attr_is_on = self.get_matter_attribute_value( + clusters.OnOff.Attributes.OnOff + ) - if self.supports_color: + if self._supports_brightness: + self._attr_brightness = self._get_brightness() + + if self._supports_color_temperature: + self._attr_color_temp = self._get_color_temperature() + + if self._supports_color: self._attr_color_mode = color_mode = self._get_color_mode() if ( ColorMode.HS in self._attr_supported_color_modes @@ -360,16 +354,12 @@ class MatterLight(MatterEntity, LightEntity): and color_mode == ColorMode.XY ): self._attr_xy_color = self._get_xy_color() - - if self.supports_color_temperature: - self._attr_color_temp = self._get_color_temperature() - - self._attr_is_on = self.get_matter_attribute_value( - clusters.OnOff.Attributes.OnOff - ) - - if self.supports_brightness: - self._attr_brightness = self._get_brightness() + elif self._attr_color_temp is not None: + self._attr_color_mode = ColorMode.COLOR_TEMP + elif self._attr_brightness is not None: + self._attr_color_mode = ColorMode.BRIGHTNESS + else: + self._attr_color_mode = ColorMode.ONOFF # Discovery schema(s) to map Matter Attributes to HA entities diff --git a/tests/components/matter/fixtures/nodes/color-temperature-light.json b/tests/components/matter/fixtures/nodes/color-temperature-light.json index 45d1c18635c..370e028e721 100644 --- a/tests/components/matter/fixtures/nodes/color-temperature-light.json +++ b/tests/components/matter/fixtures/nodes/color-temperature-light.json @@ -206,47 +206,17 @@ "1": 1 } ], - "1/29/1": [6, 29, 57, 768, 8, 80, 3, 4], + "1/29/1": [3, 4, 6, 8, 29, 80, 768], "1/29/2": [], "1/29/3": [], "1/29/65533": 1, "1/29/65528": [], "1/29/65529": [], "1/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65533], - "1/768/0": 36, - "1/768/3": 26515, - "1/768/4": 25657, "1/768/7": 284, "1/768/1": 51, - "1/768/16384": 9305, "1/768/8": 0, - "1/768/15": 0, - "1/768/16385": 0, - "1/768/16386": { - "TLVValue": null, - "Reason": null - }, - "1/768/16387": { - "TLVValue": null, - "Reason": null - }, - "1/768/16388": { - "TLVValue": null, - "Reason": null - }, - "1/768/16389": { - "TLVValue": null, - "Reason": null - }, - "1/768/16390": { - "TLVValue": null, - "Reason": null - }, - "1/768/16394": 25, - "1/768/16": { - "TLVValue": null, - "Reason": null - }, + "1/768/16394": 16, "1/768/16395": 153, "1/768/16396": 500, "1/768/16397": 250, diff --git a/tests/components/matter/fixtures/nodes/dimmable-light.json b/tests/components/matter/fixtures/nodes/dimmable-light.json index 7ccc3eef3af..74f132a88a9 100644 --- a/tests/components/matter/fixtures/nodes/dimmable-light.json +++ b/tests/components/matter/fixtures/nodes/dimmable-light.json @@ -358,54 +358,14 @@ "1": 1 } ], - "1/29/1": [3, 4, 6, 8, 29, 768, 1030], + "1/29/1": [3, 4, 6, 8, 29], "1/29/2": [], "1/29/3": [], "1/29/65532": 0, "1/29/65533": 1, "1/29/65528": [], "1/29/65529": [], - "1/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533], - "1/768/0": 0, - "1/768/1": 0, - "1/768/2": 0, - "1/768/3": 24939, - "1/768/4": 24701, - "1/768/7": 0, - "1/768/8": 2, - "1/768/15": 0, - "1/768/16": 0, - "1/768/16384": 0, - "1/768/16385": 2, - "1/768/16386": 0, - "1/768/16387": 0, - "1/768/16388": 25, - "1/768/16389": 8960, - "1/768/16390": 0, - "1/768/16394": 31, - "1/768/16395": 0, - "1/768/16396": 65279, - "1/768/16397": 0, - "1/768/16400": 0, - "1/768/65532": 31, - "1/768/65533": 5, - "1/768/65528": [], - "1/768/65529": [ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 64, 65, 66, 67, 68, 71, 75, 76 - ], - "1/768/65531": [ - 0, 1, 2, 3, 4, 7, 8, 15, 16, 16384, 16385, 16386, 16387, 16388, 16389, - 16390, 16394, 16395, 16396, 16397, 16400, 65528, 65529, 65531, 65532, - 65533 - ], - "1/1030/0": 0, - "1/1030/1": 0, - "1/1030/2": 1, - "1/1030/65532": 0, - "1/1030/65533": 3, - "1/1030/65528": [], - "1/1030/65529": [], - "1/1030/65531": [0, 1, 2, 65528, 65529, 65531, 65532, 65533] + "1/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533] }, "available": true, "attribute_subscriptions": [] diff --git a/tests/components/matter/fixtures/nodes/onoff-light.json b/tests/components/matter/fixtures/nodes/onoff-light.json index eed404ff85d..15390129dd2 100644 --- a/tests/components/matter/fixtures/nodes/onoff-light.json +++ b/tests/components/matter/fixtures/nodes/onoff-light.json @@ -330,82 +330,20 @@ "1/6/65531": [ 0, 16384, 16385, 16386, 16387, 65528, 65529, 65531, 65532, 65533 ], - "1/8/0": 52, - "1/8/1": 0, - "1/8/2": 1, - "1/8/3": 254, - "1/8/4": 0, - "1/8/5": 0, - "1/8/6": 0, - "1/8/15": 0, - "1/8/16": 0, - "1/8/17": null, - "1/8/18": 0, - "1/8/19": 0, - "1/8/20": 50, - "1/8/16384": null, - "1/8/65532": 3, - "1/8/65533": 5, - "1/8/65528": [], - "1/8/65529": [0, 1, 2, 3, 4, 5, 6, 7], - "1/8/65531": [ - 0, 1, 2, 3, 4, 5, 6, 15, 16, 17, 18, 19, 20, 16384, 65528, 65529, 65531, - 65532, 65533 - ], "1/29/0": [ { - "0": 257, + "0": 256, "1": 1 } ], - "1/29/1": [3, 4, 6, 8, 29, 768, 1030], + "1/29/1": [3, 4, 6, 29], "1/29/2": [], "1/29/3": [], "1/29/65532": 0, "1/29/65533": 1, "1/29/65528": [], "1/29/65529": [], - "1/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533], - "1/768/0": 0, - "1/768/1": 0, - "1/768/2": 0, - "1/768/3": 24939, - "1/768/4": 24701, - "1/768/7": 0, - "1/768/8": 2, - "1/768/15": 0, - "1/768/16": 0, - "1/768/16384": 0, - "1/768/16385": 2, - "1/768/16386": 0, - "1/768/16387": 0, - "1/768/16388": 25, - "1/768/16389": 8960, - "1/768/16390": 0, - "1/768/16394": 31, - "1/768/16395": 0, - "1/768/16396": 65279, - "1/768/16397": 0, - "1/768/16400": 0, - "1/768/65532": 31, - "1/768/65533": 5, - "1/768/65528": [], - "1/768/65529": [ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 64, 65, 66, 67, 68, 71, 75, 76 - ], - "1/768/65531": [ - 0, 1, 2, 3, 4, 7, 8, 15, 16, 16384, 16385, 16386, 16387, 16388, 16389, - 16390, 16394, 16395, 16396, 16397, 16400, 65528, 65529, 65531, 65532, - 65533 - ], - "1/1030/0": 0, - "1/1030/1": 0, - "1/1030/2": 1, - "1/1030/65532": 0, - "1/1030/65533": 3, - "1/1030/65528": [], - "1/1030/65529": [], - "1/1030/65531": [0, 1, 2, 65528, 65529, 65531, 65532, 65533] + "1/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533] }, "available": true, "attribute_subscriptions": []