mirror of
https://github.com/home-assistant/core.git
synced 2025-04-25 09:47:52 +00:00
Add helper method to get matter device info (#103765)
* Add helper method to get matter device info * Cleanup async * Guard * get node from device id instead of node id * Fix test --------- Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
parent
e157206eeb
commit
ebdd2daab6
@ -3,6 +3,7 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from contextlib import suppress
|
||||
from functools import cache
|
||||
|
||||
from matter_server.client import MatterClient
|
||||
from matter_server.client.exceptions import CannotConnect, InvalidServerVersion
|
||||
@ -28,12 +29,34 @@ from .addon import get_addon_manager
|
||||
from .api import async_register_api
|
||||
from .const import CONF_INTEGRATION_CREATED_ADDON, CONF_USE_ADDON, DOMAIN, LOGGER
|
||||
from .discovery import SUPPORTED_PLATFORMS
|
||||
from .helpers import MatterEntryData, get_matter, get_node_from_device_entry
|
||||
from .helpers import (
|
||||
MatterEntryData,
|
||||
get_matter,
|
||||
get_node_from_device_entry,
|
||||
node_from_ha_device_id,
|
||||
)
|
||||
from .models import MatterDeviceInfo
|
||||
|
||||
CONNECT_TIMEOUT = 10
|
||||
LISTEN_READY_TIMEOUT = 30
|
||||
|
||||
|
||||
@callback
|
||||
@cache
|
||||
def get_matter_device_info(
|
||||
hass: HomeAssistant, device_id: str
|
||||
) -> MatterDeviceInfo | None:
|
||||
"""Return Matter device info or None if device does not exist."""
|
||||
if not (node := node_from_ha_device_id(hass, device_id)):
|
||||
return None
|
||||
|
||||
return MatterDeviceInfo(
|
||||
unique_id=node.device_info.uniqueID,
|
||||
vendor_id=hex(node.device_info.vendorID),
|
||||
product_id=hex(node.device_info.productID),
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
"""Set up Matter from a config entry."""
|
||||
if use_addon := entry.data.get(CONF_USE_ADDON):
|
||||
@ -190,7 +213,7 @@ async def async_remove_config_entry_device(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry, device_entry: dr.DeviceEntry
|
||||
) -> bool:
|
||||
"""Remove a config entry from a device."""
|
||||
node = await get_node_from_device_entry(hass, device_entry)
|
||||
node = get_node_from_device_entry(hass, device_entry)
|
||||
|
||||
if node is None:
|
||||
return True
|
||||
@ -218,21 +241,11 @@ async def async_remove_config_entry_device(
|
||||
def _async_init_services(hass: HomeAssistant) -> None:
|
||||
"""Init services."""
|
||||
|
||||
async def _node_id_from_ha_device_id(ha_device_id: str) -> int | None:
|
||||
"""Get node id from ha device id."""
|
||||
dev_reg = dr.async_get(hass)
|
||||
device = dev_reg.async_get(ha_device_id)
|
||||
if device is None:
|
||||
return None
|
||||
if node := await get_node_from_device_entry(hass, device):
|
||||
return node.node_id
|
||||
return None
|
||||
|
||||
async def open_commissioning_window(call: ServiceCall) -> None:
|
||||
"""Open commissioning window on specific node."""
|
||||
node_id = await _node_id_from_ha_device_id(call.data["device_id"])
|
||||
node = node_from_ha_device_id(hass, call.data["device_id"])
|
||||
|
||||
if node_id is None:
|
||||
if node is None:
|
||||
raise HomeAssistantError("This is not a Matter device")
|
||||
|
||||
matter_client = get_matter(hass).matter_client
|
||||
@ -240,7 +253,7 @@ def _async_init_services(hass: HomeAssistant) -> None:
|
||||
# We are sending device ID .
|
||||
|
||||
try:
|
||||
await matter_client.open_commissioning_window(node_id)
|
||||
await matter_client.open_commissioning_window(node.node_id)
|
||||
except NodeCommissionFailed as err:
|
||||
raise HomeAssistantError(str(err)) from err
|
||||
|
||||
|
@ -58,7 +58,7 @@ async def async_get_device_diagnostics(
|
||||
"""Return diagnostics for a device."""
|
||||
matter = get_matter(hass)
|
||||
server_diagnostics = await matter.matter_client.get_diagnostics()
|
||||
node = await get_node_from_device_entry(hass, device)
|
||||
node = get_node_from_device_entry(hass, device)
|
||||
|
||||
return {
|
||||
"server_info": dataclass_to_dict(server_diagnostics.info),
|
||||
|
@ -66,7 +66,18 @@ def get_device_id(
|
||||
return f"{operational_instance_id}-{postfix}"
|
||||
|
||||
|
||||
async def get_node_from_device_entry(
|
||||
@callback
|
||||
def node_from_ha_device_id(hass: HomeAssistant, ha_device_id: str) -> MatterNode | None:
|
||||
"""Get node id from ha device id."""
|
||||
dev_reg = dr.async_get(hass)
|
||||
device = dev_reg.async_get(ha_device_id)
|
||||
if device is None:
|
||||
raise ValueError("Invalid device ID")
|
||||
return get_node_from_device_entry(hass, device)
|
||||
|
||||
|
||||
@callback
|
||||
def get_node_from_device_entry(
|
||||
hass: HomeAssistant, device: dr.DeviceEntry
|
||||
) -> MatterNode | None:
|
||||
"""Return MatterNode from device entry."""
|
||||
|
@ -2,6 +2,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import TypedDict
|
||||
|
||||
from chip.clusters import Objects as clusters
|
||||
from chip.clusters.Objects import ClusterAttributeDescriptor
|
||||
@ -16,6 +17,20 @@ SensorValueTypes = type[
|
||||
]
|
||||
|
||||
|
||||
class MatterDeviceInfo(TypedDict):
|
||||
"""Dictionary with Matter Device info.
|
||||
|
||||
Used to send to other Matter controllers,
|
||||
such as Google Home to prevent duplicated devices.
|
||||
|
||||
Reference: https://developers.home.google.com/matter/device-deduplication
|
||||
"""
|
||||
|
||||
unique_id: str
|
||||
vendor_id: str # vendorId hex string
|
||||
product_id: str # productId hex string
|
||||
|
||||
|
||||
@dataclass
|
||||
class MatterEntityInfo:
|
||||
"""Info discovered from (primary) Matter Attribute to create entity."""
|
||||
|
@ -56,7 +56,7 @@ async def test_get_node_from_device_entry(
|
||||
device_registry, config_entry.entry_id
|
||||
)[0]
|
||||
assert device_entry
|
||||
node_from_device_entry = await get_node_from_device_entry(hass, device_entry)
|
||||
node_from_device_entry = get_node_from_device_entry(hass, device_entry)
|
||||
|
||||
assert node_from_device_entry is node
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user