Skip to content

Commit 177dfc9

Browse files
authored
Use our own global models for CommissionableNodeData and Commissionin… (#520)
1 parent d933fe8 commit 177dfc9

File tree

4 files changed

+73
-26
lines changed

4 files changed

+73
-26
lines changed

matter_server/client/client.py

+10
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from ..common.models import (
2323
APICommand,
2424
CommandMessage,
25+
CommissionableNodeData,
2526
CommissioningParameters,
2627
ErrorResultMessage,
2728
EventMessage,
@@ -198,6 +199,15 @@ async def open_commissioning_window(
198199
),
199200
)
200201

202+
async def discover_commissionable_nodes(
203+
self,
204+
) -> list[CommissionableNodeData]:
205+
"""Discover Commissionable Nodes (discovered on BLE or mDNS)."""
206+
return [
207+
dataclass_from_dict(CommissionableNodeData, x)
208+
for x in await self.send_command(APICommand.DISCOVER, require_schema=7)
209+
]
210+
201211
async def get_matter_fabrics(self, node_id: int) -> list[MatterFabricData]:
202212
"""
203213
Get Matter fabrics from a device.

matter_server/common/const.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
# schema version is used to determine compatibility between server and client
44
# bump schema if we add new features and/or make other (breaking) changes
5-
SCHEMA_VERSION = 6
5+
SCHEMA_VERSION = 7

matter_server/common/models.py

+26-8
Original file line numberDiff line numberDiff line change
@@ -175,13 +175,31 @@ class ServerInfoMessage:
175175

176176

177177
@dataclass
178-
class CommissioningParameters:
179-
"""
180-
Object that is returned on the 'open_commisisoning_window' command.
178+
class CommissionableNodeData:
179+
"""Object that is returned on the 'discover_commissionable_nodes' command."""
180+
181+
instance_name: str | None = None
182+
host_name: str | None = None
183+
port: int | None = None
184+
long_discriminator: int | None = None
185+
vendor_id: int | None = None
186+
product_id: int | None = None
187+
commissioning_mode: int | None = None
188+
device_type: int | None = None
189+
device_name: str | None = None
190+
pairing_instruction: str | None = None
191+
pairing_hint: int | None = None
192+
mrp_retry_interval_idle: int | None = None
193+
mrp_retry_interval_active: int | None = None
194+
supports_tcp: bool | None = None
195+
addresses: list[str] | None = None
196+
rotating_id: str | None = None
197+
181198

182-
NOTE: This is just a copy of the dataclass specified in chip.ChipDeviceCtrl
183-
"""
199+
@dataclass
200+
class CommissioningParameters:
201+
"""Object that is returned on the 'open_commisisoning_window' command."""
184202

185-
setupPinCode: int # pylint: disable=invalid-name
186-
setupManualCode: str # pylint: disable=invalid-name
187-
setupQRCode: str # pylint: disable=invalid-name
203+
setup_pin_code: int
204+
setup_manual_code: str
205+
setup_qr_code: str

matter_server/server/device_controller.py

+36-17
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@
1111
import random
1212
from typing import TYPE_CHECKING, Any, Awaitable, Callable, Iterable, TypeVar, cast
1313

14-
from chip.ChipDeviceCtrl import CommissionableNode, DeviceProxyWrapper
14+
from chip.ChipDeviceCtrl import DeviceProxyWrapper
1515
from chip.clusters import Attribute, Objects as Clusters
1616
from chip.clusters.Attribute import ValueDecodeFailure
1717
from chip.clusters.ClusterObjects import ALL_ATTRIBUTES, ALL_CLUSTERS, Cluster
18-
from chip.discovery import CommissionableNode as CommissionableNodeData
1918
from chip.exceptions import ChipStackError
2019

2120
from matter_server.common.helpers.util import convert_ip_address
22-
from matter_server.common.models import CommissioningParameters
21+
from matter_server.common.models import CommissionableNodeData, CommissioningParameters
2322
from matter_server.server.helpers.attributes import parse_attributes_from_read_result
2423
from matter_server.server.helpers.utils import ping_ip
2524

@@ -391,37 +390,57 @@ async def open_commissioning_window(
391390
if discriminator is None:
392391
discriminator = 3840 # TODO generate random one
393392

394-
return await self._call_sdk(
393+
sdk_result = await self._call_sdk(
395394
self.chip_controller.OpenCommissioningWindow,
396395
nodeid=node_id,
397396
timeout=timeout,
398397
iteration=iteration,
399398
discriminator=discriminator,
400399
option=option,
401400
)
401+
return CommissioningParameters(
402+
setup_pin_code=sdk_result.setupPinCode,
403+
setup_manual_code=sdk_result.setupManualCode,
404+
setup_qr_code=sdk_result.setupQRCode,
405+
)
402406

403407
@api_command(APICommand.DISCOVER)
404408
async def discover_commissionable_nodes(
405409
self,
406-
) -> CommissionableNodeData | list[CommissionableNodeData] | None:
410+
) -> list[CommissionableNodeData]:
407411
"""Discover Commissionable Nodes (discovered on BLE or mDNS)."""
408412
if self.chip_controller is None:
409413
raise RuntimeError("Device Controller not initialized.")
410414

411-
result = await self._call_sdk(
415+
sdk_result = await self._call_sdk(
412416
self.chip_controller.DiscoverCommissionableNodes,
413417
)
414-
415-
def convert(cn: CommissionableNode) -> CommissionableNodeData:
416-
cnd = CommissionableNodeData()
417-
# pylint: disable=no-member
418-
for field in CommissionableNodeData.__dataclass_fields__:
419-
setattr(cnd, field, getattr(cn, field))
420-
return cnd
421-
422-
if isinstance(result, list):
423-
return [convert(c) for c in result]
424-
return convert(result)
418+
if sdk_result is None:
419+
return []
420+
# ensure list
421+
if not isinstance(sdk_result, list):
422+
sdk_result = [sdk_result]
423+
return [
424+
CommissionableNodeData(
425+
instance_name=x.instanceName,
426+
host_name=x.hostName,
427+
port=x.port,
428+
long_discriminator=x.longDiscriminator,
429+
vendor_id=x.vendorId,
430+
product_id=x.productId,
431+
commissioning_mode=x.commissioningMode,
432+
device_type=x.deviceType,
433+
device_name=x.deviceName,
434+
pairing_instruction=x.pairingInstruction,
435+
pairing_hint=x.pairingHint,
436+
mrp_retry_interval_idle=x.mrpRetryIntervalIdle,
437+
mrp_retry_interval_active=x.mrpRetryIntervalActive,
438+
supports_tcp=x.supportsTcp,
439+
addresses=x.addresses,
440+
rotating_id=x.rotatingId,
441+
)
442+
for x in sdk_result
443+
]
425444

426445
@api_command(APICommand.INTERVIEW_NODE)
427446
async def interview_node(self, node_id: int) -> None:

0 commit comments

Comments
 (0)