Change subscription logic for Matter devices (#95387)

This commit is contained in:
Marcel van der Veldt 2023-06-27 21:12:29 +02:00 committed by GitHub
parent a885ceefa2
commit ed2daf1f65
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 110 additions and 30 deletions

View file

@ -52,13 +52,62 @@ class MatterAdapter:
async def setup_nodes(self) -> None:
"""Set up all existing nodes and subscribe to new nodes."""
for node in await self.matter_client.get_nodes():
for node in self.matter_client.get_nodes():
self._setup_node(node)
def node_added_callback(event: EventType, node: MatterNode) -> None:
"""Handle node added event."""
self._setup_node(node)
def endpoint_added_callback(event: EventType, data: dict[str, int]) -> None:
"""Handle endpoint added event."""
node = self.matter_client.get_node(data["node_id"])
self._setup_endpoint(node.endpoints[data["endpoint_id"]])
def endpoint_removed_callback(event: EventType, data: dict[str, int]) -> None:
"""Handle endpoint removed event."""
server_info = cast(ServerInfoMessage, self.matter_client.server_info)
try:
node = self.matter_client.get_node(data["node_id"])
except KeyError:
return # race condition
device_registry = dr.async_get(self.hass)
endpoint = node.endpoints.get(data["endpoint_id"])
if not endpoint:
return # race condition
node_device_id = get_device_id(
server_info,
node.endpoints[data["endpoint_id"]],
)
identifier = (DOMAIN, f"{ID_TYPE_DEVICE_ID}_{node_device_id}")
if device := device_registry.async_get_device({identifier}):
device_registry.async_remove_device(device.id)
def node_removed_callback(event: EventType, node_id: int) -> None:
"""Handle node removed event."""
try:
node = self.matter_client.get_node(node_id)
except KeyError:
return # race condition
for endpoint_id in node.endpoints:
endpoint_removed_callback(
EventType.ENDPOINT_REMOVED,
{"node_id": node_id, "endpoint_id": endpoint_id},
)
self.config_entry.async_on_unload(
self.matter_client.subscribe(
endpoint_added_callback, EventType.ENDPOINT_ADDED
)
)
self.config_entry.async_on_unload(
self.matter_client.subscribe(
endpoint_removed_callback, EventType.ENDPOINT_REMOVED
)
)
self.config_entry.async_on_unload(
self.matter_client.subscribe(node_removed_callback, EventType.NODE_REMOVED)
)
self.config_entry.async_on_unload(
self.matter_client.subscribe(node_added_callback, EventType.NODE_ADDED)
)

View file

@ -75,9 +75,11 @@ class MatterEntity(Entity):
await super().async_added_to_hass()
# Subscribe to attribute updates.
sub_paths: list[str] = []
for attr_cls in self._entity_info.attributes_to_watch:
attr_path = self.get_matter_attribute_path(attr_cls)
self._attributes_map[attr_cls] = attr_path
sub_paths.append(attr_path)
self._unsubscribes.append(
self.matter_client.subscribe(
callback=self._on_matter_event,
@ -86,6 +88,9 @@ class MatterEntity(Entity):
attr_path_filter=attr_path,
)
)
await self.matter_client.subscribe_attribute(
self._endpoint.node.node_id, sub_paths
)
# subscribe to node (availability changes)
self._unsubscribes.append(
self.matter_client.subscribe(

View file

@ -95,7 +95,7 @@ async def get_node_from_device_entry(
node = next(
(
node
for node in await matter_client.get_nodes()
for node in matter_client.get_nodes()
for endpoint in node.endpoints.values()
if get_device_id(server_info, endpoint) == device_id
),

View file

@ -6,5 +6,5 @@
"dependencies": ["websocket_api"],
"documentation": "https://www.home-assistant.io/integrations/matter",
"iot_class": "local_push",
"requirements": ["python-matter-server==3.5.1"]
"requirements": ["python-matter-server==3.6.0"]
}