mirror of
https://github.com/home-assistant/core.git
synced 2025-04-25 01:38:02 +00:00
Adjust device registry for Matter devices (#86108)
* adjust device registry * ignore test unique id * update test * ditch uniqueid + prefix serial * adjust test * add tests * fix switch test * prefix all identifiers * Update homeassistant/components/matter/adapter.py Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * no underscore in id * fix test Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
parent
5e6ba594aa
commit
4bebf00598
@ -17,7 +17,7 @@ from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .const import DOMAIN, LOGGER
|
||||
from .const import DOMAIN, ID_TYPE_DEVICE_ID, ID_TYPE_SERIAL, LOGGER
|
||||
from .device_platform import DEVICE_PLATFORM
|
||||
from .helpers import get_device_id
|
||||
|
||||
@ -91,10 +91,7 @@ class MatterAdapter:
|
||||
) -> None:
|
||||
"""Create a device registry entry."""
|
||||
server_info = cast(ServerInfo, self.matter_client.server_info)
|
||||
node_unique_id = get_device_id(
|
||||
server_info,
|
||||
node_device,
|
||||
)
|
||||
|
||||
basic_info = node_device.device_info()
|
||||
device_type_instances = node_device.device_type_instances()
|
||||
|
||||
@ -103,16 +100,23 @@ class MatterAdapter:
|
||||
# fallback name for Bridge
|
||||
name = "Hub device"
|
||||
elif not name and device_type_instances:
|
||||
# fallback name based on device type
|
||||
name = (
|
||||
f"{device_type_instances[0].device_type.__doc__[:-1]}"
|
||||
f" {node_device.node().node_id}"
|
||||
)
|
||||
# use the productName if no node label is present
|
||||
name = basic_info.productName
|
||||
|
||||
node_device_id = get_device_id(
|
||||
server_info,
|
||||
node_device,
|
||||
)
|
||||
identifiers = {(DOMAIN, f"{ID_TYPE_DEVICE_ID}_{node_device_id}")}
|
||||
# if available, we also add the serialnumber as identifier
|
||||
if basic_info.serialNumber and "test" not in basic_info.serialNumber.lower():
|
||||
# prefix identifier with 'serial_' to be able to filter it
|
||||
identifiers.add((DOMAIN, f"{ID_TYPE_SERIAL}_{basic_info.serialNumber}"))
|
||||
|
||||
dr.async_get(self.hass).async_get_or_create(
|
||||
name=name,
|
||||
config_entry_id=self.config_entry.entry_id,
|
||||
identifiers={(DOMAIN, node_unique_id)},
|
||||
identifiers=identifiers,
|
||||
hw_version=basic_info.hardwareVersionString,
|
||||
sw_version=basic_info.softwareVersionString,
|
||||
manufacturer=basic_info.vendorName,
|
||||
|
@ -8,3 +8,7 @@ CONF_USE_ADDON = "use_addon"
|
||||
|
||||
DOMAIN = "matter"
|
||||
LOGGER = logging.getLogger(__package__)
|
||||
|
||||
# prefixes to identify device identifier id types
|
||||
ID_TYPE_DEVICE_ID = "deviceid"
|
||||
ID_TYPE_SERIAL = "serial"
|
||||
|
@ -15,7 +15,7 @@ from matter_server.common.models.server_information import ServerInfo
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.entity import DeviceInfo, Entity, EntityDescription
|
||||
|
||||
from .const import DOMAIN
|
||||
from .const import DOMAIN, ID_TYPE_DEVICE_ID
|
||||
from .helpers import get_device_id, get_operational_instance_id
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@ -68,8 +68,9 @@ class MatterEntity(Entity):
|
||||
f"{device_type_instance.endpoint}-"
|
||||
f"{device_type_instance.device_type.device_type}"
|
||||
)
|
||||
node_device_id = get_device_id(server_info, node_device)
|
||||
self._attr_device_info = DeviceInfo(
|
||||
identifiers={(DOMAIN, get_device_id(server_info, node_device))}
|
||||
identifiers={(DOMAIN, f"{ID_TYPE_DEVICE_ID}_{node_device_id}")}
|
||||
)
|
||||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
|
@ -175,7 +175,7 @@
|
||||
"attribute_id": 5,
|
||||
"attribute_type": "chip.clusters.Objects.Basic.Attributes.NodeLabel",
|
||||
"attribute_name": "NodeLabel",
|
||||
"value": "Mock OnOff Plugin Unit"
|
||||
"value": ""
|
||||
},
|
||||
"0/40/6": {
|
||||
"node_id": 1,
|
||||
|
@ -469,7 +469,7 @@
|
||||
"attribute_id": 15,
|
||||
"attribute_type": "chip.clusters.Objects.Basic.Attributes.SerialNumber",
|
||||
"attribute_name": "SerialNumber",
|
||||
"value": "TEST_SN"
|
||||
"value": "12345678"
|
||||
},
|
||||
"0/40/16": {
|
||||
"node_id": 1,
|
||||
|
@ -28,10 +28,13 @@ async def test_device_registry_single_node_device(
|
||||
|
||||
dev_reg = dr.async_get(hass)
|
||||
entry = dev_reg.async_get_device(
|
||||
{(DOMAIN, "00000000000004D2-0000000000000001-MatterNodeDevice")}
|
||||
{(DOMAIN, "deviceid_00000000000004D2-0000000000000001-MatterNodeDevice")}
|
||||
)
|
||||
assert entry is not None
|
||||
|
||||
# test serial id present as additional identifier
|
||||
assert (DOMAIN, "serial_12345678") in entry.identifiers
|
||||
|
||||
assert entry.name == "Mock OnOff Light"
|
||||
assert entry.manufacturer == "Nabu Casa"
|
||||
assert entry.model == "Mock Light"
|
||||
@ -39,6 +42,30 @@ async def test_device_registry_single_node_device(
|
||||
assert entry.sw_version == "v1.0"
|
||||
|
||||
|
||||
async def test_device_registry_single_node_device_alt(
|
||||
hass: HomeAssistant,
|
||||
matter_client: MagicMock,
|
||||
) -> None:
|
||||
"""Test additional device with different attribute values."""
|
||||
await setup_integration_with_node_fixture(
|
||||
hass,
|
||||
"on-off-plugin-unit",
|
||||
matter_client,
|
||||
)
|
||||
|
||||
dev_reg = dr.async_get(hass)
|
||||
entry = dev_reg.async_get_device(
|
||||
{(DOMAIN, "deviceid_00000000000004D2-0000000000000001-MatterNodeDevice")}
|
||||
)
|
||||
assert entry is not None
|
||||
|
||||
# test name is derived from productName (because nodeLabel is absent)
|
||||
assert entry.name == "Mock OnOffPluginUnit (powerplug/switch)"
|
||||
|
||||
# test serial id NOT present as additional identifier
|
||||
assert (DOMAIN, "serial_TEST_SN") not in entry.identifiers
|
||||
|
||||
|
||||
@pytest.mark.skip("Waiting for a new test fixture")
|
||||
async def test_device_registry_bridge(
|
||||
hass: HomeAssistant,
|
||||
|
@ -30,7 +30,7 @@ async def test_turn_on(
|
||||
switch_node: MatterNode,
|
||||
) -> None:
|
||||
"""Test turning on a switch."""
|
||||
state = hass.states.get("switch.mock_onoff_plugin_unit")
|
||||
state = hass.states.get("switch.mock_onoffpluginunit_powerplug_switch")
|
||||
assert state
|
||||
assert state.state == "off"
|
||||
|
||||
@ -38,7 +38,7 @@ async def test_turn_on(
|
||||
"switch",
|
||||
"turn_on",
|
||||
{
|
||||
"entity_id": "switch.mock_onoff_plugin_unit",
|
||||
"entity_id": "switch.mock_onoffpluginunit_powerplug_switch",
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
@ -53,7 +53,7 @@ async def test_turn_on(
|
||||
set_node_attribute(switch_node, 1, 6, 0, True)
|
||||
await trigger_subscription_callback(hass, matter_client)
|
||||
|
||||
state = hass.states.get("switch.mock_onoff_plugin_unit")
|
||||
state = hass.states.get("switch.mock_onoffpluginunit_powerplug_switch")
|
||||
assert state
|
||||
assert state.state == "on"
|
||||
|
||||
@ -64,7 +64,7 @@ async def test_turn_off(
|
||||
switch_node: MatterNode,
|
||||
) -> None:
|
||||
"""Test turning off a switch."""
|
||||
state = hass.states.get("switch.mock_onoff_plugin_unit")
|
||||
state = hass.states.get("switch.mock_onoffpluginunit_powerplug_switch")
|
||||
assert state
|
||||
assert state.state == "off"
|
||||
|
||||
@ -72,7 +72,7 @@ async def test_turn_off(
|
||||
"switch",
|
||||
"turn_off",
|
||||
{
|
||||
"entity_id": "switch.mock_onoff_plugin_unit",
|
||||
"entity_id": "switch.mock_onoffpluginunit_powerplug_switch",
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user