38
38
import logging
39
39
import secrets
40
40
import threading
41
- import time
42
41
import typing
43
42
from ctypes import (CDLL, CFUNCTYPE, POINTER, Structure, byref, c_bool, c_char, c_char_p, c_int, c_int32, c_size_t, c_uint8,
44
43
c_uint16, c_uint32, c_uint64, c_void_p, create_string_buffer, pointer, py_object, resize, string_at)
@@ -729,8 +728,8 @@ def GetAddressAndPort(self, nodeid):
729
728
730
729
return (address.value.decode(), port.value) if error == 0 else None
731
730
732
- def DiscoverCommissionableNodes(self, filterType: discovery.FilterType = discovery.FilterType.NONE, filter: typing.Any = None,
733
- stopOnFirst: bool = False, timeoutSecond: int = 5) -> typing.Union[None, CommissionableNode, typing.List[CommissionableNode]]:
731
+ async def DiscoverCommissionableNodes(self, filterType: discovery.FilterType = discovery.FilterType.NONE, filter: typing.Any = None,
732
+ stopOnFirst: bool = False, timeoutSecond: int = 5) -> typing.Union[None, CommissionableNode, typing.List[CommissionableNode]]:
734
733
''' Discover commissionable nodes via DNS-SD with specified filters.
735
734
Supported filters are:
736
735
@@ -752,27 +751,36 @@ def DiscoverCommissionableNodes(self, filterType: discovery.FilterType = discove
752
751
if isinstance(filter, int):
753
752
filter = str(filter)
754
753
755
- self._ChipStack.Call(
756
- lambda: self._dmLib.pychip_DeviceController_DiscoverCommissionableNodes(
757
- self.devCtrl, int(filterType), str(filter).encode("utf-8"))).raise_on_error()
758
-
759
- if timeoutSecond != 0:
760
- if stopOnFirst:
761
- target = time.time() + timeoutSecond
762
- while time.time() < target:
763
- if self._ChipStack.Call(
764
- lambda: self._dmLib.pychip_DeviceController_HasDiscoveredCommissionableNode(self.devCtrl)):
765
- break
766
- time.sleep(0.1)
767
- else:
768
- time.sleep(timeoutSecond)
769
-
770
- self._ChipStack.Call(
771
- lambda: self._dmLib.pychip_DeviceController_StopCommissionableDiscovery(self.devCtrl)).raise_on_error()
754
+ # Discovery is also used during commissioning. Make sure this manual discovery
755
+ # and commissioning attempts do not interfere with each other.
756
+ async with self._commissioning_lock:
757
+ res = await self._ChipStack.CallAsync(
758
+ lambda: self._dmLib.pychip_DeviceController_DiscoverCommissionableNodes(
759
+ self.devCtrl, int(filterType), str(filter).encode("utf-8")))
760
+ res.raise_on_error()
772
761
773
- return self.GetDiscoveredDevices()
762
+ async def _wait_discovery():
763
+ while not await self._ChipStack.CallAsync(
764
+ lambda: self._dmLib.pychip_DeviceController_HasDiscoveredCommissionableNode(self.devCtrl)):
765
+ await asyncio.sleep(0.1)
766
+ return
774
767
775
- def GetDiscoveredDevices(self):
768
+ try:
769
+ if stopOnFirst:
770
+ await asyncio.wait_for(_wait_discovery(), timeoutSecond)
771
+ else:
772
+ await asyncio.sleep(timeoutSecond)
773
+ except TimeoutError:
774
+ # Expected timeout, do nothing
775
+ pass
776
+ finally:
777
+ res = await self._ChipStack.CallAsync(
778
+ lambda: self._dmLib.pychip_DeviceController_StopCommissionableDiscovery(self.devCtrl))
779
+ res.raise_on_error()
780
+
781
+ return await self.GetDiscoveredDevices()
782
+
783
+ async def GetDiscoveredDevices(self):
776
784
def GetDevices(devCtrl):
777
785
devices = []
778
786
@@ -786,7 +794,7 @@ def HandleDevice(deviceJson, deviceJsonLen):
786
794
self._dmLib.pychip_DeviceController_IterateDiscoveredCommissionableNodes(devCtrl.devCtrl, HandleDevice)
787
795
return devices
788
796
789
- return self._ChipStack.Call (lambda: GetDevices(self))
797
+ return await self._ChipStack.CallAsync (lambda: GetDevices(self))
790
798
791
799
def GetIPForDiscoveredDevice(self, idx, addrStr, length):
792
800
self.CheckIsActive()
0 commit comments