9
9
from datetime import datetime
10
10
from functools import partial
11
11
import logging
12
+ from random import randint
12
13
import time
13
14
from typing import TYPE_CHECKING , Any , Callable , Iterable , TypeVar , cast
14
15
@@ -98,6 +99,7 @@ def __init__(
98
99
self ._nodes : dict [int , MatterNodeData ] = {}
99
100
self ._last_known_ip_addresses : dict [int , list [str ]] = {}
100
101
self ._last_subscription_attempt : dict [int , int ] = {}
102
+ self ._known_commissioning_params : dict [int , CommissioningParameters ] = {}
101
103
self .wifi_credentials_set : bool = False
102
104
self .thread_credentials_set : bool = False
103
105
self .compressed_fabric_id : int | None = None
@@ -403,8 +405,16 @@ async def open_commissioning_window(
403
405
if self .chip_controller is None :
404
406
raise RuntimeError ("Device Controller not initialized." )
405
407
408
+ if (node := self ._nodes .get (node_id )) is None or not node .available :
409
+ raise NodeNotReady (f"Node { node_id } is not (yet) available." )
410
+
411
+ if node_id in self ._known_commissioning_params :
412
+ # node has already been put into commissioning mode,
413
+ # return previous parameters
414
+ return self ._known_commissioning_params [node_id ]
415
+
406
416
if discriminator is None :
407
- discriminator = 3840 # TODO generate random one
417
+ discriminator = randint ( 0 , 4095 ) # noqa: S311
408
418
409
419
sdk_result = await self ._call_sdk (
410
420
self .chip_controller .OpenCommissioningWindow ,
@@ -414,11 +424,18 @@ async def open_commissioning_window(
414
424
discriminator = discriminator ,
415
425
option = option ,
416
426
)
417
- return CommissioningParameters (
427
+ self . _known_commissioning_params [ node_id ] = params = CommissioningParameters (
418
428
setup_pin_code = sdk_result .setupPinCode ,
419
429
setup_manual_code = sdk_result .setupManualCode ,
420
430
setup_qr_code = sdk_result .setupQRCode ,
421
431
)
432
+ # we store the commission parameters and clear them after the timeout
433
+ if TYPE_CHECKING :
434
+ assert self .server .loop
435
+ self .server .loop .call_later (
436
+ timeout , self ._known_commissioning_params .pop , node_id , None
437
+ )
438
+ return params
422
439
423
440
@api_command (APICommand .DISCOVER )
424
441
async def discover_commissionable_nodes (
0 commit comments