3 from __future__
import annotations
7 from chip.clusters
import Objects
as clusters
8 from matter_server.client.models
import device_types
18 LightEntityDescription,
20 filter_supported_color_modes,
27 from .const
import LOGGER
28 from .entity
import MatterEntity
29 from .helpers
import get_matter
30 from .models
import MatterDiscoverySchema
40 clusters.ColorControl.Enums.ColorMode.kCurrentHueAndCurrentSaturation: ColorMode.HS,
41 clusters.ColorControl.Enums.ColorMode.kCurrentXAndCurrentY: ColorMode.XY,
42 clusters.ColorControl.Enums.ColorMode.kColorTemperature: ColorMode.COLOR_TEMP,
52 TRANSITION_BLOCKLIST = (
53 (4107, 8475,
"v1.0",
"v1.0"),
54 (4107, 8550,
"v1.0",
"v1.0"),
55 (4107, 8551,
"v1.0",
"v1.0"),
56 (4107, 8571,
"v1.0",
"v1.0"),
57 (4107, 8656,
"v1.0",
"v1.0"),
58 (4448, 36866,
"V1",
"V1.0.0.5"),
59 (4456, 1011,
"1.0.0",
"2.00.00"),
60 (4488, 260,
"1.0",
"1.0.0"),
61 (4488, 514,
"1.0",
"1.0.0"),
62 (4921, 42,
"1.0",
"1.01.060"),
63 (4921, 43,
"1.0",
"1.01.060"),
64 (4999, 24875,
"1.0",
"27.0"),
65 (4999, 25057,
"1.0",
"27.0"),
66 (5009, 514,
"1.0",
"1.0.0"),
67 (5010, 769,
"3.0",
"1.0.0"),
68 (5130, 544,
"v0.4",
"6.7.196e9d4e08-14"),
69 (5127, 4232,
"ver_0.1",
"v1.00.51"),
70 (5245, 1412,
"1.0",
"1.0.21"),
76 config_entry: ConfigEntry,
77 async_add_entities: AddEntitiesCallback,
79 """Set up Matter Light from Config Entry."""
81 matter.register_platform_handler(Platform.LIGHT, async_add_entities)
85 """Representation of a Matter light."""
87 entity_description: LightEntityDescription
88 _supports_brightness =
False
89 _supports_color =
False
90 _supports_color_temperature =
False
91 _transitions_disabled =
False
92 _platform_translation_key =
"light"
95 self, xy_color: tuple[float, float], transition: float = 0.0
102 clusters.ColorControl.Commands.MoveToColor(
103 colorX=
int(matter_xy[0]),
104 colorY=
int(matter_xy[1]),
106 transitionTime=
int(transition * 10),
115 self, hs_color: tuple[float, float], transition: float = 0.0
122 clusters.ColorControl.Commands.MoveToHueAndSaturation(
123 hue=
int(matter_hs[0]),
124 saturation=
int(matter_hs[1]),
126 transitionTime=
int(transition * 10),
135 """Set color temperature."""
138 clusters.ColorControl.Commands.MoveToColorTemperature(
139 colorTemperatureMireds=color_temp,
141 transitionTime=
int(transition * 10),
150 """Set brightness."""
152 level_control = self.
_endpoint_endpoint.get_cluster(clusters.LevelControl)
154 assert level_control
is not None
160 (level_control.minLevel
or 1, level_control.maxLevel
or 254),
165 clusters.LevelControl.Commands.MoveToLevelWithOnOff(
168 transitionTime=
int(transition * 10),
173 """Get xy color from matter."""
176 clusters.ColorControl.Attributes.CurrentX
179 clusters.ColorControl.Attributes.CurrentY
182 assert x_color
is not None
183 assert y_color
is not None
187 "Got xy color %s for %s",
195 """Get hs color from matter."""
198 clusters.ColorControl.Attributes.CurrentHue
202 clusters.ColorControl.Attributes.CurrentSaturation
205 assert hue
is not None
206 assert saturation
is not None
211 "Got hs color %s for %s",
219 """Get color temperature from matter."""
222 clusters.ColorControl.Attributes.ColorTemperatureMireds
225 assert color_temp
is not None
228 "Got color temperature %s for %s",
233 return int(color_temp)
236 """Get brightness from matter."""
238 level_control = self.
_endpoint_endpoint.get_cluster(clusters.LevelControl)
241 assert level_control
is not None
244 "Got brightness %s for %s",
245 level_control.currentLevel,
251 level_control.currentLevel,
252 (level_control.minLevel
or 1, level_control.maxLevel
or 254),
258 """Get color mode from matter."""
261 clusters.ColorControl.Attributes.ColorMode
264 assert color_mode
is not None
266 ha_color_mode = COLOR_MODE_MAP[color_mode]
269 "Got color mode (%s) for %s",
277 """Send device command."""
279 node_id=self.
_endpoint_endpoint.node.node_id,
280 endpoint_id=self.
_endpoint_endpoint.endpoint_id,
287 hs_color = kwargs.get(ATTR_HS_COLOR)
288 xy_color = kwargs.get(ATTR_XY_COLOR)
289 color_temp = kwargs.get(ATTR_COLOR_TEMP)
290 brightness = kwargs.get(ATTR_BRIGHTNESS)
291 transition = kwargs.get(ATTR_TRANSITION, 0)
301 color_temp
is not None
311 clusters.OnOff.Commands.On(),
315 """Turn light off."""
317 clusters.OnOff.Commands.Off(),
322 """Update from device."""
325 supported_color_modes = {ColorMode.ONOFF}
327 if self.
_entity_info_entity_info.endpoint.has_attribute(
328 None, clusters.LevelControl.Attributes.CurrentLevel
329 )
and self.
_entity_info_entity_info.endpoint.device_types != {device_types.OnOffLight}:
333 supported_color_modes.add(ColorMode.BRIGHTNESS)
336 if self.
_entity_info_entity_info.endpoint.has_attribute(
337 None, clusters.ColorControl.Attributes.ColorMode
338 )
and self.
_entity_info_entity_info.endpoint.has_attribute(
339 None, clusters.ColorControl.Attributes.ColorCapabilities
342 clusters.ColorControl.Attributes.ColorCapabilities
345 assert capabilities
is not None
349 & clusters.ColorControl.Bitmaps.ColorCapabilities.kHueSaturationSupported
351 supported_color_modes.add(ColorMode.HS)
356 & clusters.ColorControl.Bitmaps.ColorCapabilities.kXYAttributesSupported
358 supported_color_modes.add(ColorMode.XY)
363 & clusters.ColorControl.Bitmaps.ColorCapabilities.kColorTemperatureSupported
365 supported_color_modes.add(ColorMode.COLOR_TEMP)
368 clusters.ColorControl.Attributes.ColorTempPhysicalMinMireds
373 clusters.ColorControl.Attributes.ColorTempPhysicalMaxMireds
383 supported_color_modes != {ColorMode.ONOFF}
386 self._attr_supported_features |= LightEntityFeature.TRANSITION
389 "Supported color modes: %s for %s",
396 clusters.OnOff.Attributes.OnOff
409 and color_mode == ColorMode.HS
414 and color_mode == ColorMode.XY
425 """Check if this device is reported to have non working transitions."""
426 device_info = self.
_endpoint_endpoint.device_info
427 if isinstance(device_info, clusters.BridgedDeviceBasicInformation):
430 device_info.vendorID,
431 device_info.productID,
432 device_info.hardwareVersionString,
433 device_info.softwareVersionString,
434 )
in TRANSITION_BLOCKLIST:
437 "Detected a device that has been reported to have firmware issues "
438 "with light transitions. Transitions will be disabled for this light"
443 DISCOVERY_SCHEMAS = [
445 platform=Platform.LIGHT,
450 entity_class=MatterLight,
451 required_attributes=(clusters.OnOff.Attributes.OnOff,),
452 optional_attributes=(
453 clusters.LevelControl.Attributes.CurrentLevel,
454 clusters.ColorControl.Attributes.ColorMode,
455 clusters.ColorControl.Attributes.CurrentHue,
456 clusters.ColorControl.Attributes.CurrentSaturation,
457 clusters.ColorControl.Attributes.CurrentX,
458 clusters.ColorControl.Attributes.CurrentY,
459 clusters.ColorControl.Attributes.ColorTemperatureMireds,
462 device_types.ColorTemperatureLight,
463 device_types.DimmableLight,
464 device_types.DimmablePlugInUnit,
465 device_types.ExtendedColorLight,
466 device_types.OnOffLight,
467 device_types.DimmerSwitch,
468 device_types.ColorDimmerSwitch,
473 platform=Platform.LIGHT,
475 key=
"MatterHSColorLightFallback",
478 entity_class=MatterLight,
479 required_attributes=(
480 clusters.OnOff.Attributes.OnOff,
481 clusters.ColorControl.Attributes.CurrentHue,
482 clusters.ColorControl.Attributes.CurrentSaturation,
484 optional_attributes=(
485 clusters.LevelControl.Attributes.CurrentLevel,
486 clusters.ColorControl.Attributes.ColorTemperatureMireds,
487 clusters.ColorControl.Attributes.ColorMode,
488 clusters.ColorControl.Attributes.CurrentX,
489 clusters.ColorControl.Attributes.CurrentY,
494 platform=Platform.LIGHT,
496 key=
"MatterXYColorLightFallback",
499 entity_class=MatterLight,
500 required_attributes=(
501 clusters.OnOff.Attributes.OnOff,
502 clusters.ColorControl.Attributes.CurrentX,
503 clusters.ColorControl.Attributes.CurrentY,
505 optional_attributes=(
506 clusters.LevelControl.Attributes.CurrentLevel,
507 clusters.ColorControl.Attributes.ColorTemperatureMireds,
508 clusters.ColorControl.Attributes.ColorMode,
509 clusters.ColorControl.Attributes.CurrentHue,
510 clusters.ColorControl.Attributes.CurrentSaturation,
515 platform=Platform.LIGHT,
517 key=
"MatterColorTemperatureLightFallback",
520 entity_class=MatterLight,
521 required_attributes=(
522 clusters.OnOff.Attributes.OnOff,
523 clusters.LevelControl.Attributes.CurrentLevel,
524 clusters.ColorControl.Attributes.ColorTemperatureMireds,
526 optional_attributes=(clusters.ColorControl.Attributes.ColorMode,),
set[ColorMode]|set[str]|None supported_color_modes(self)
Any get_matter_attribute_value(self, type[ClusterAttributeDescriptor] attribute, bool null_as_none=True)
ColorMode _get_color_mode(self)
bool _supports_color_temperature
None send_device_command(self, Any command)
bool _supports_brightness
tuple[float, float] _get_xy_color(self)
_supports_color_temperature
None async_turn_off(self, **Any kwargs)
tuple[float, float] _get_hs_color(self)
None async_turn_on(self, **Any kwargs)
None _check_transition_blocklist(self)
None _set_brightness(self, int brightness, float transition=0.0)
None _set_color_temp(self, int color_temp, float transition=0.0)
int _get_color_temperature(self)
None _set_hs_color(self, tuple[float, float] hs_color, float transition=0.0)
bool _transitions_disabled
None _set_xy_color(self, tuple[float, float] xy_color, float transition=0.0)
None _update_from_device(self)
int _get_brightness(self)
_attr_supported_color_modes
set[ColorMode] filter_supported_color_modes(Iterable[ColorMode] color_modes)
MatterAdapter get_matter(HomeAssistant hass)
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
tuple[float, float] convert_to_hass_xy(tuple[float, float] matter_xy)
tuple[float, float] convert_to_matter_hs(tuple[float, float] hass_hs)
float renormalize(float number, tuple[float, float] from_range, tuple[float, float] to_range)
tuple[float, float] convert_to_hass_hs(tuple[float, float] matter_hs)
tuple[float, float] convert_to_matter_xy(tuple[float, float] hass_xy)