Skip to content

Commit

Permalink
Some fixes for the Matter light discovery schema (home-assistant#116108)
Browse files Browse the repository at this point in the history
* Fix discovery schema for light platform

* fix switch platform discovery schema

* extend light tests

* Update switch.py

* clarify comment

* use parameter for supported_color_modes
  • Loading branch information
marcelveldt authored May 1, 2024
1 parent ac608ef commit 8230bfc
Show file tree
Hide file tree
Showing 4 changed files with 273 additions and 47 deletions.
41 changes: 6 additions & 35 deletions homeassistant/components/matter/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,10 @@ def _update_from_device(self) -> None:
# brightness support
if self._entity_info.endpoint.has_attribute(
None, clusters.LevelControl.Attributes.CurrentLevel
):
) and self._entity_info.endpoint.device_types != {device_types.OnOffLight}:
# We need to filter out the OnOffLight device type here because
# that can have an optional LevelControl cluster present
# which we should ignore.
supported_color_modes.add(ColorMode.BRIGHTNESS)
self._supports_brightness = True
# colormode(s)
Expand Down Expand Up @@ -406,11 +409,11 @@ def _update_from_device(self) -> None:
entity_class=MatterLight,
required_attributes=(
clusters.OnOff.Attributes.OnOff,
clusters.LevelControl.Attributes.CurrentLevel,
clusters.ColorControl.Attributes.CurrentHue,
clusters.ColorControl.Attributes.CurrentSaturation,
),
optional_attributes=(
clusters.LevelControl.Attributes.CurrentLevel,
clusters.ColorControl.Attributes.ColorTemperatureMireds,
clusters.ColorControl.Attributes.ColorMode,
clusters.ColorControl.Attributes.CurrentX,
Expand All @@ -426,11 +429,11 @@ def _update_from_device(self) -> None:
entity_class=MatterLight,
required_attributes=(
clusters.OnOff.Attributes.OnOff,
clusters.LevelControl.Attributes.CurrentLevel,
clusters.ColorControl.Attributes.CurrentX,
clusters.ColorControl.Attributes.CurrentY,
),
optional_attributes=(
clusters.LevelControl.Attributes.CurrentLevel,
clusters.ColorControl.Attributes.ColorTemperatureMireds,
clusters.ColorControl.Attributes.ColorMode,
clusters.ColorControl.Attributes.CurrentHue,
Expand All @@ -451,36 +454,4 @@ def _update_from_device(self) -> None:
),
optional_attributes=(clusters.ColorControl.Attributes.ColorMode,),
),
# Additional schema to match generic dimmable lights with incorrect/missing device type
MatterDiscoverySchema(
platform=Platform.LIGHT,
entity_description=LightEntityDescription(
key="MatterDimmableLightFallback", name=None
),
entity_class=MatterLight,
required_attributes=(
clusters.OnOff.Attributes.OnOff,
clusters.LevelControl.Attributes.CurrentLevel,
),
optional_attributes=(
clusters.ColorControl.Attributes.ColorMode,
clusters.ColorControl.Attributes.CurrentHue,
clusters.ColorControl.Attributes.CurrentSaturation,
clusters.ColorControl.Attributes.CurrentX,
clusters.ColorControl.Attributes.CurrentY,
clusters.ColorControl.Attributes.ColorTemperatureMireds,
),
# important: make sure to rule out all device types that are also based on the
# onoff and levelcontrol clusters !
not_device_type=(
device_types.Fan,
device_types.GenericSwitch,
device_types.OnOffPlugInUnit,
device_types.HeatingCoolingUnit,
device_types.Pump,
device_types.CastingVideoClient,
device_types.VideoRemoteControl,
device_types.Speaker,
),
),
]
6 changes: 1 addition & 5 deletions homeassistant/components/matter/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,8 @@ def _update_from_device(self) -> None:
device_types.ColorTemperatureLight,
device_types.DimmableLight,
device_types.ExtendedColorLight,
device_types.OnOffLight,
device_types.DoorLock,
device_types.ColorDimmerSwitch,
device_types.DimmerSwitch,
device_types.Thermostat,
device_types.RoomAirConditioner,
device_types.OnOffLight,
),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
{
"node_id": 8,
"date_commissioned": "2024-03-07T01:39:20.590755",
"last_interview": "2024-04-02T14:16:31.045880",
"interview_version": 6,
"available": true,
"is_bridge": false,
"attributes": {
"0/29/0": [
{
"0": 22,
"1": 1
}
],
"0/29/1": [29, 31, 40, 42, 43, 44, 48, 49, 50, 51, 52, 54, 60, 62, 63],
"0/29/2": [41],
"0/29/3": [1],
"0/29/65532": 0,
"0/29/65533": 1,
"0/29/65528": [],
"0/29/65529": [],
"0/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533],
"0/31/0": [
{
"254": 1
},
{
"1": 5,
"2": 2,
"3": [112233],
"4": null,
"254": 2
}
],
"0/31/1": [],
"0/31/2": 4,
"0/31/3": 3,
"0/31/4": 3,
"0/31/65532": 0,
"0/31/65533": 1,
"0/31/65528": [],
"0/31/65529": [],
"0/31/65531": [0, 1, 2, 3, 4, 65528, 65529, 65531, 65532, 65533],
"0/40/0": 1,
"0/40/1": "Leviton",
"0/40/2": 4251,
"0/40/3": "D215S",
"0/40/4": 4097,
"0/40/5": "",
"0/40/6": "**REDACTED**",
"0/40/7": 1,
"0/40/8": "1.0",
"0/40/9": 131365,
"0/40/10": "2.1.25",
"0/40/15": "12345678",
"0/40/18": "abcdefgh",
"0/40/19": {
"0": 3,
"1": 3
},
"0/40/65532": 0,
"0/40/65533": 1,
"0/40/65528": [],
"0/40/65529": [],
"0/40/65531": [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 18, 19, 65528, 65529, 65531, 65532,
65533
],
"0/42/0": [],
"0/42/1": true,
"0/42/2": 1,
"0/42/3": null,
"0/42/65532": 0,
"0/42/65533": 1,
"0/42/65528": [],
"0/42/65529": [0],
"0/42/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533],
"0/43/0": "en-US",
"0/43/1": [
"en-US",
"de-DE",
"fr-FR",
"en-GB",
"es-ES",
"zh-CN",
"it-IT",
"ja-JP"
],
"0/43/65532": 0,
"0/43/65533": 1,
"0/43/65528": [],
"0/43/65529": [],
"0/43/65531": [0, 1, 65528, 65529, 65531, 65532, 65533],
"0/44/0": 0,
"0/44/1": 0,
"0/44/2": [0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 7],
"0/44/65532": 0,
"0/44/65533": 1,
"0/44/65528": [],
"0/44/65529": [],
"0/44/65531": [0, 1, 2, 65528, 65529, 65531, 65532, 65533],
"0/48/0": 0,
"0/48/1": {
"0": 60,
"1": 900
},
"0/48/2": 0,
"0/48/3": 0,
"0/48/4": true,
"0/48/65532": 0,
"0/48/65533": 1,
"0/48/65528": [1, 3, 5],
"0/48/65529": [0, 2, 4],
"0/48/65531": [0, 1, 2, 3, 4, 65528, 65529, 65531, 65532, 65533],
"0/49/0": 1,
"0/49/2": 10,
"0/49/3": 20,
"0/49/4": true,
"0/49/5": 0,
"0/49/7": null,
"0/49/65532": 1,
"0/49/65533": 1,
"0/49/65528": [1, 5, 7],
"0/49/65529": [0, 2, 4, 6, 8],
"0/49/65531": [0, 1, 2, 3, 4, 5, 6, 7, 65528, 65529, 65531, 65532, 65533],
"0/50/65532": 0,
"0/50/65533": 1,
"0/50/65528": [1],
"0/50/65529": [0],
"0/50/65531": [65528, 65529, 65531, 65532, 65533],
"0/51/1": 1,
"0/51/2": 2380987,
"0/51/3": 661,
"0/51/4": 0,
"0/51/5": [],
"0/51/6": [],
"0/51/7": [],
"0/51/8": false,
"0/51/65532": 0,
"0/51/65533": 1,
"0/51/65528": [],
"0/51/65529": [0],
"0/51/65531": [
0, 1, 2, 3, 4, 5, 6, 7, 8, 65528, 65529, 65531, 65532, 65533
],
"0/52/1": 49792,
"0/52/2": 262528,
"0/52/3": 272704,
"0/52/65532": 1,
"0/52/65533": 1,
"0/52/65528": [],
"0/52/65529": [0],
"0/52/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533],
"0/54/0": "blah",
"0/54/1": 4,
"0/54/2": 3,
"0/54/3": 11,
"0/54/4": -43,
"0/54/65532": 0,
"0/54/65533": 1,
"0/54/65528": [],
"0/54/65529": [],
"0/54/65531": [0, 1, 2, 3, 4, 65528, 65529, 65531, 65532, 65533],
"0/60/0": 0,
"0/60/1": null,
"0/60/2": null,
"0/60/65532": 0,
"0/60/65533": 1,
"0/60/65528": [],
"0/60/65529": [0, 1, 2],
"0/60/65531": [0, 1, 2, 65528, 65529, 65531, 65532, 65533],
"0/62/5": 2,
"0/62/65532": 0,
"0/62/65533": 1,
"0/62/65528": [1, 3, 5, 8],
"0/62/65529": [0, 2, 4, 6, 7, 9, 10, 11],
"0/62/65531": [0, 1, 2, 3, 4, 5, 65528, 65529, 65531, 65532, 65533],
"0/63/0": [],
"0/63/1": [],
"0/63/2": 3,
"0/63/3": 3,
"0/63/65532": 0,
"0/63/65533": 1,
"0/63/65528": [2, 5],
"0/63/65529": [0, 1, 3, 4],
"0/63/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533],
"1/3/0": 0,
"1/3/1": 2,
"1/3/65532": 0,
"1/3/65533": 4,
"1/3/65528": [],
"1/3/65529": [0, 64],
"1/3/65531": [0, 1, 65528, 65529, 65531, 65532, 65533],
"1/4/0": 128,
"1/4/65532": 1,
"1/4/65533": 4,
"1/4/65528": [0, 1, 2, 3],
"1/4/65529": [0, 1, 2, 3, 4, 5],
"1/4/65531": [0, 65528, 65529, 65531, 65532, 65533],
"1/6/0": false,
"1/6/16384": true,
"1/6/16385": 0,
"1/6/16386": 0,
"1/6/16387": null,
"1/6/65532": 1,
"1/6/65533": 4,
"1/6/65528": [],
"1/6/65529": [0, 1, 2, 64, 65, 66],
"1/6/65531": [
0, 16384, 16385, 16386, 16387, 65528, 65529, 65531, 65532, 65533
],
"1/8/0": 254,
"1/8/1": 0,
"1/8/2": 1,
"1/8/3": 254,
"1/8/15": 0,
"1/8/16": 0,
"1/8/17": null,
"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, 15, 16, 17, 20, 16384, 65528, 65529, 65531, 65532, 65533
],
"1/29/0": [
{
"0": 256,
"1": 1
}
],
"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]
},
"attribute_subscriptions": []
}
29 changes: 22 additions & 7 deletions tests/components/matter/test_light.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,31 @@
# This tests needs to be adjusted to remove lingering tasks
@pytest.mark.parametrize("expected_lingering_tasks", [True])
@pytest.mark.parametrize(
("fixture", "entity_id"),
("fixture", "entity_id", "supported_color_modes"),
[
("extended-color-light", "light.mock_extended_color_light"),
("color-temperature-light", "light.mock_color_temperature_light"),
("dimmable-light", "light.mock_dimmable_light"),
("onoff-light", "light.mock_onoff_light"),
(
"extended-color-light",
"light.mock_extended_color_light",
["color_temp", "hs", "xy"],
),
(
"color-temperature-light",
"light.mock_color_temperature_light",
["color_temp"],
),
("dimmable-light", "light.mock_dimmable_light", ["brightness"]),
("onoff-light", "light.mock_onoff_light", ["onoff"]),
("onoff-light-with-levelcontrol-present", "light.d215s", ["onoff"]),
],
)
async def test_on_off_light(
async def test_light_turn_on_off(
hass: HomeAssistant,
matter_client: MagicMock,
fixture: str,
entity_id: str,
supported_color_modes: list[str],
) -> None:
"""Test an on/off light."""
"""Test basic light discovery and turn on/off."""

light_node = await setup_integration_with_node_fixture(
hass,
Expand All @@ -48,6 +58,11 @@ async def test_on_off_light(
assert state is not None
assert state.state == "off"

# check the supported_color_modes
# especially important is the onoff light device type that does have
# a levelcontrol cluster present which we should ignore
assert state.attributes["supported_color_modes"] == supported_color_modes

# Test that the light is on
set_node_attribute(light_node, 1, 6, 0, True)
await trigger_subscription_callback(hass, matter_client)
Expand Down

0 comments on commit 8230bfc

Please sign in to comment.