Skip to content

Commit 9a92882

Browse files
committed
Convert to asyncio Matter SDK API
Changes required to use the new co-routines based Matter SDK API.
1 parent 950663f commit 9a92882

File tree

2 files changed

+65
-68
lines changed

2 files changed

+65
-68
lines changed

matter_server/server/device_controller.py

+56-42
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,6 @@
6262
from collections.abc import Iterable
6363
from pathlib import Path
6464

65-
from chip.native import PyChipError
66-
6765
from .server import MatterServer
6866

6967
DATA_KEY_NODES = "nodes"
@@ -274,21 +272,28 @@ async def commission_with_code(
274272
attempts,
275273
MAX_COMMISSION_RETRIES,
276274
)
277-
result: (
278-
PyChipError | None
279-
) = await self._chip_device_controller.commission_with_code(
280-
node_id,
281-
code,
282-
DiscoveryType.DISCOVERY_NETWORK_ONLY
283-
if network_only
284-
else DiscoveryType.DISCOVERY_ALL,
285-
)
286-
if result and result.is_success:
287-
break
288-
if attempts >= MAX_COMMISSION_RETRIES:
289-
raise NodeCommissionFailed(
290-
f"Commission with code failed for node {node_id}."
275+
try:
276+
commissioned_node_id: int = (
277+
await self._chip_device_controller.commission_with_code(
278+
node_id,
279+
code,
280+
DiscoveryType.DISCOVERY_NETWORK_ONLY
281+
if network_only
282+
else DiscoveryType.DISCOVERY_ALL,
283+
)
291284
)
285+
# We use SDK default behavior which always uses the commissioning Node ID in the
286+
# generated NOC. So this should be the same really.
287+
LOGGER.info(
288+
"Commissioned Node ID: %s vs %s", commissioned_node_id, node_id
289+
)
290+
assert commissioned_node_id == node_id
291+
break
292+
except ChipStackError as err:
293+
if attempts >= MAX_COMMISSION_RETRIES:
294+
raise NodeCommissionFailed(
295+
f"Commission with code failed for node {node_id}."
296+
) from err
292297
await asyncio.sleep(5)
293298

294299
LOGGER.info("Matter commissioning of Node ID %s successful.", node_id)
@@ -346,33 +351,42 @@ async def commission_on_network(
346351
# by retrying, we increase the chances of a successful commission
347352
while attempts <= MAX_COMMISSION_RETRIES:
348353
attempts += 1
349-
result: PyChipError | None
350-
if ip_addr is None:
351-
# regular CommissionOnNetwork if no IP address provided
352-
LOGGER.info(
353-
"Starting Matter commissioning on network using Node ID %s (attempt %s/%s).",
354-
node_id,
355-
attempts,
356-
MAX_COMMISSION_RETRIES,
357-
)
358-
result = await self._chip_device_controller.commission_on_network(
359-
node_id, setup_pin_code, filter_type, filter
360-
)
361-
else:
362-
LOGGER.info(
363-
"Starting Matter commissioning using Node ID %s and IP %s (attempt %s/%s).",
364-
node_id,
365-
ip_addr,
366-
attempts,
367-
MAX_COMMISSION_RETRIES,
368-
)
369-
result = await self._chip_device_controller.commission_ip(
370-
node_id, setup_pin_code, ip_addr
371-
)
372-
if result and result.is_success:
354+
try:
355+
if ip_addr is None:
356+
# regular CommissionOnNetwork if no IP address provided
357+
LOGGER.info(
358+
"Starting Matter commissioning on network using Node ID %s (attempt %s/%s).",
359+
node_id,
360+
attempts,
361+
MAX_COMMISSION_RETRIES,
362+
)
363+
commissioned_node_id = (
364+
await self._chip_device_controller.commission_on_network(
365+
node_id, setup_pin_code, filter_type, filter
366+
)
367+
)
368+
else:
369+
LOGGER.info(
370+
"Starting Matter commissioning using Node ID %s and IP %s (attempt %s/%s).",
371+
node_id,
372+
ip_addr,
373+
attempts,
374+
MAX_COMMISSION_RETRIES,
375+
)
376+
commissioned_node_id = (
377+
await self._chip_device_controller.commission_ip(
378+
node_id, setup_pin_code, ip_addr
379+
)
380+
)
381+
# We use SDK default behavior which always uses the commissioning Node ID in the
382+
# generated NOC. So this should be the same really.
383+
assert commissioned_node_id == node_id
373384
break
374-
if attempts >= MAX_COMMISSION_RETRIES:
375-
raise NodeCommissionFailed(f"Commissioning failed for node {node_id}.")
385+
except ChipStackError as err:
386+
if attempts >= MAX_COMMISSION_RETRIES:
387+
raise NodeCommissionFailed(
388+
f"Commissioning failed for node {node_id}."
389+
) from err
376390
await asyncio.sleep(5)
377391

378392
LOGGER.info("Matter commissioning of Node ID %s successful.", node_id)

matter_server/server/sdk.py

+9-26
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from __future__ import annotations
99

1010
import asyncio
11-
from concurrent.futures import ThreadPoolExecutor
1211
from functools import partial
1312
import logging
1413
import time
@@ -25,6 +24,7 @@
2524

2625
if TYPE_CHECKING:
2726
from collections.abc import Callable
27+
from concurrent.futures import ThreadPoolExecutor
2828
from pathlib import Path
2929

3030
from chip.ChipDeviceCtrl import (
@@ -59,7 +59,6 @@ def __init__(self, server: MatterServer, paa_root_cert_dir: Path):
5959

6060
self._node_lock: dict[int, asyncio.Lock] = {}
6161
self._subscriptions: dict[int, Attribute.SubscriptionTransaction] = {}
62-
self._sdk_non_entrant_executor = ThreadPoolExecutor(max_workers=1)
6362

6463
# Instantiate the underlying ChipDeviceController instance on the Fabric
6564
self._chip_controller = self.server.stack.fabric_admin.NewController(
@@ -100,16 +99,6 @@ async def _call_sdk(
10099
) -> _T:
101100
return await self._call_sdk_executor(None, target, *args, **kwargs)
102101

103-
async def _call_sdk_non_reentrant(
104-
self,
105-
target: Callable[..., _T],
106-
*args: Any,
107-
**kwargs: Any,
108-
) -> _T:
109-
return await self._call_sdk_executor(
110-
self._sdk_non_entrant_executor, target, *args, **kwargs
111-
)
112-
113102
async def get_compressed_fabric_id(self) -> int:
114103
"""Get the compressed fabric id."""
115104
return await self._call_sdk(self._chip_controller.GetCompressedFabricId)
@@ -128,10 +117,9 @@ async def commission_with_code(
128117
node_id: int,
129118
setup_payload: str,
130119
discovery_type: DiscoveryType,
131-
) -> PyChipError:
120+
) -> int:
132121
"""Commission a device using a QR Code or Manual Pairing Code."""
133-
return await self._call_sdk_non_reentrant(
134-
self._chip_controller.CommissionWithCode,
122+
return await self._chip_controller.CommissionWithCode(
135123
setupPayload=setup_payload,
136124
nodeid=node_id,
137125
discoveryType=discovery_type,
@@ -143,10 +131,9 @@ async def commission_on_network(
143131
setup_pin_code: int,
144132
disc_filter_type: FilterType = FilterType.NONE,
145133
disc_filter: Any = None,
146-
) -> PyChipError:
134+
) -> int:
147135
"""Commission a device on the network."""
148-
return await self._call_sdk_non_reentrant(
149-
self._chip_controller.CommissionOnNetwork,
136+
return await self._chip_controller.CommissionOnNetwork(
150137
nodeId=node_id,
151138
setupPinCode=setup_pin_code,
152139
filterType=disc_filter_type,
@@ -155,10 +142,9 @@ async def commission_on_network(
155142

156143
async def commission_ip(
157144
self, node_id: int, setup_pin_code: int, ip_addr: str
158-
) -> PyChipError:
145+
) -> int:
159146
"""Commission a device using an IP address."""
160-
return await self._call_sdk_non_reentrant(
161-
self._chip_controller.CommissionIP,
147+
return await self._chip_controller.CommissionIP(
162148
nodeid=node_id,
163149
setupPinCode=setup_pin_code,
164150
ipaddr=ip_addr,
@@ -185,9 +171,7 @@ async def unpair_device(self, node_id: int) -> PyChipError:
185171
Tries to look up the device attached to our controller with the given
186172
remote node id and ask it to remove Fabric.
187173
"""
188-
return await self._call_sdk_non_reentrant(
189-
self._chip_controller.UnpairDevice, nodeid=node_id
190-
)
174+
return await self._chip_controller.UnpairDevice(nodeid=node_id)
191175

192176
async def open_commissioning_window(
193177
self,
@@ -199,8 +183,7 @@ async def open_commissioning_window(
199183
) -> CommissioningParameters:
200184
"""Open a commissioning window to commission a device present on this controller to another."""
201185
async with self._get_node_lock(node_id):
202-
return await self._call_sdk_non_reentrant(
203-
self._chip_controller.OpenCommissioningWindow,
186+
return await self._chip_controller.OpenCommissioningWindow(
204187
nodeid=node_id,
205188
timeout=timeout,
206189
iteration=iteration,

0 commit comments

Comments
 (0)