Fix discovery schema for Matter switches (#103762)

* Fix discovery schema for matter switches

* fix typo in function that generates device name

* add test for switchunit
This commit is contained in:
Marcel van der Veldt 2023-11-21 20:25:07 +01:00 committed by GitHub
parent 95e322c52e
commit b604c1c222
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 162 additions and 13 deletions

View File

@ -145,9 +145,7 @@ class MatterAdapter:
get_clean_name(basic_info.nodeLabel)
or get_clean_name(basic_info.productLabel)
or get_clean_name(basic_info.productName)
or device_type.__name__
if device_type
else None
or (device_type.__name__ if device_type else None)
)
# handle bridged devices

View File

@ -67,7 +67,15 @@ DISCOVERY_SCHEMAS = [
),
entity_class=MatterSwitch,
required_attributes=(clusters.OnOff.Attributes.OnOff,),
# restrict device type to prevent discovery by the wrong platform
device_type=(device_types.OnOffPlugInUnit,),
),
MatterDiscoverySchema(
platform=Platform.SWITCH,
entity_description=SwitchEntityDescription(
key="MatterSwitch", device_class=SwitchDeviceClass.SWITCH, name=None
),
entity_class=MatterSwitch,
required_attributes=(clusters.OnOff.Attributes.OnOff,),
not_device_type=(
device_types.ColorTemperatureLight,
device_types.DimmableLight,
@ -76,7 +84,6 @@ DISCOVERY_SCHEMAS = [
device_types.DoorLock,
device_types.ColorDimmerSwitch,
device_types.DimmerSwitch,
device_types.OnOffLightSwitch,
device_types.Thermostat,
),
),

View File

@ -0,0 +1,119 @@
{
"node_id": 1,
"date_commissioned": "2022-11-29T21:23:48.485051",
"last_interview": "2022-11-29T21:23:48.485057",
"interview_version": 2,
"attributes": {
"0/29/0": [
{
"deviceType": 99999,
"revision": 1
}
],
"0/29/1": [
4, 29, 31, 40, 42, 43, 44, 48, 49, 50, 51, 52, 53, 54, 55, 59, 60, 62, 63,
64, 65
],
"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/40/0": 1,
"0/40/1": "Nabu Casa",
"0/40/2": 65521,
"0/40/3": "Mock SwitchUnit",
"0/40/4": 32768,
"0/40/5": "Mock SwitchUnit",
"0/40/6": "XX",
"0/40/7": 0,
"0/40/8": "v1.0",
"0/40/9": 1,
"0/40/10": "v1.0",
"0/40/11": "20221206",
"0/40/12": "",
"0/40/13": "",
"0/40/14": "",
"0/40/15": "TEST_SN",
"0/40/16": false,
"0/40/17": true,
"0/40/18": "mock-switch-unit",
"0/40/19": {
"caseSessionsPerFabric": 3,
"subscriptionsPerFabric": 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, 11, 12, 13, 14, 15, 16, 17, 18, 19,
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/5/0": 0,
"1/5/1": 0,
"1/5/2": 0,
"1/5/3": false,
"1/5/4": 0,
"1/5/65532": 0,
"1/5/65533": 4,
"1/5/65528": [0, 1, 2, 3, 4, 6],
"1/5/65529": [0, 1, 2, 3, 4, 5, 6],
"1/5/65531": [0, 1, 2, 3, 4, 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/7/0": 0,
"1/7/16": 0,
"1/7/65532": 0,
"1/7/65533": 1,
"1/7/65528": [],
"1/7/65529": [],
"1/7/65531": [0, 16, 65528, 65529, 65531, 65532, 65533],
"1/29/0": [
{
"deviceType": 9999999,
"revision": 1
}
],
"1/29/1": [
3, 4, 5, 6, 7, 8, 15, 29, 30, 37, 47, 59, 64, 65, 69, 80, 257, 258, 259,
512, 513, 514, 516, 768, 1024, 1026, 1027, 1028, 1029, 1030, 1283, 1284,
1285, 1286, 1287, 1288, 1289, 1290, 1291, 1292, 1293, 1294, 2820,
4294048773
],
"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]
},
"available": true,
"attribute_subscriptions": []
}

View File

@ -14,22 +14,30 @@ from .common import (
)
@pytest.fixture(name="switch_node")
async def switch_node_fixture(
@pytest.fixture(name="powerplug_node")
async def powerplug_node_fixture(
hass: HomeAssistant, matter_client: MagicMock
) -> MatterNode:
"""Fixture for a switch node."""
"""Fixture for a Powerplug node."""
return await setup_integration_with_node_fixture(
hass, "on-off-plugin-unit", matter_client
)
@pytest.fixture(name="switch_unit")
async def switch_unit_fixture(
hass: HomeAssistant, matter_client: MagicMock
) -> MatterNode:
"""Fixture for a Switch Unit node."""
return await setup_integration_with_node_fixture(hass, "switch-unit", matter_client)
# This tests needs to be adjusted to remove lingering tasks
@pytest.mark.parametrize("expected_lingering_tasks", [True])
async def test_turn_on(
hass: HomeAssistant,
matter_client: MagicMock,
switch_node: MatterNode,
powerplug_node: MatterNode,
) -> None:
"""Test turning on a switch."""
state = hass.states.get("switch.mock_onoffpluginunit_powerplug_switch")
@ -47,12 +55,12 @@ async def test_turn_on(
assert matter_client.send_device_command.call_count == 1
assert matter_client.send_device_command.call_args == call(
node_id=switch_node.node_id,
node_id=powerplug_node.node_id,
endpoint_id=1,
command=clusters.OnOff.Commands.On(),
)
set_node_attribute(switch_node, 1, 6, 0, True)
set_node_attribute(powerplug_node, 1, 6, 0, True)
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get("switch.mock_onoffpluginunit_powerplug_switch")
@ -65,7 +73,7 @@ async def test_turn_on(
async def test_turn_off(
hass: HomeAssistant,
matter_client: MagicMock,
switch_node: MatterNode,
powerplug_node: MatterNode,
) -> None:
"""Test turning off a switch."""
state = hass.states.get("switch.mock_onoffpluginunit_powerplug_switch")
@ -83,7 +91,24 @@ async def test_turn_off(
assert matter_client.send_device_command.call_count == 1
assert matter_client.send_device_command.call_args == call(
node_id=switch_node.node_id,
node_id=powerplug_node.node_id,
endpoint_id=1,
command=clusters.OnOff.Commands.Off(),
)
# This tests needs to be adjusted to remove lingering tasks
@pytest.mark.parametrize("expected_lingering_tasks", [True])
async def test_switch_unit(
hass: HomeAssistant,
matter_client: MagicMock,
switch_unit: MatterNode,
) -> None:
"""Test if a switch entity is discovered from any (non-light) OnOf cluster device."""
# A switch entity should be discovered as fallback for ANY Matter device (endpoint)
# that has the OnOff cluster and does not fall into an explicit discovery schema
# by another platform (e.g. light, lock etc.).
state = hass.states.get("switch.mock_switchunit")
assert state
assert state.state == "off"
assert state.attributes["friendly_name"] == "Mock SwitchUnit"