diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index ed821ba..dd231d3 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -201,6 +201,9 @@ jobs: echo "Applying ${patch}" patch -p1 < $patch done + - uses: actions/setup-python@v5 + with: + python-version: '3.11' - name: Bootstrap working-directory: ./connectedhomeip/ run: bash scripts/bootstrap.sh -p all,darwin diff --git a/0005-Enable-node-ID-logging-in-exchanges.patch b/0005-Enable-node-ID-logging-in-exchanges.patch new file mode 100644 index 0000000..2301737 --- /dev/null +++ b/0005-Enable-node-ID-logging-in-exchanges.patch @@ -0,0 +1,26 @@ +From 3c551b7a706428d2fde77df0bc93d81bb37a2022 Mon Sep 17 00:00:00 2001 +From: Stefan Agner +Date: Thu, 18 Apr 2024 21:46:59 +0200 +Subject: [PATCH] Enable node ID logging in exchanges + +Enable node ID logging in exchanges by default. +--- + src/lib/core/CHIPConfig.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/lib/core/CHIPConfig.h b/src/lib/core/CHIPConfig.h +index 558e0ee08e..5a3f5facb7 100644 +--- a/src/lib/core/CHIPConfig.h ++++ b/src/lib/core/CHIPConfig.h +@@ -468,7 +468,7 @@ + * If asserted (1), enable logging of node IDs in exchange context. + */ + #ifndef CHIP_EXCHANGE_NODE_ID_LOGGING +-#define CHIP_EXCHANGE_NODE_ID_LOGGING 0 ++#define CHIP_EXCHANGE_NODE_ID_LOGGING 1 + #endif // CHIP_EXCHANGE_NODE_ID_LOGGING + + /** +-- +2.44.0 + diff --git a/0010-Log-nodeID-in-exchange-context.patch b/0010-Log-nodeID-in-exchange-context.patch deleted file mode 100644 index 06b7c54..0000000 --- a/0010-Log-nodeID-in-exchange-context.patch +++ /dev/null @@ -1,81 +0,0 @@ -From a0ba59275c2094028323ec6c4a4135ab8795b158 Mon Sep 17 00:00:00 2001 -From: leonardmgh -Date: Tue, 19 Mar 2024 11:25:07 +0100 -Subject: [PATCH] Log node ID in exchanges (#32550) - -* Log nodeID in exchange context - -* Update comments - -* Use ChipLogValueScopedNodeId with ScopedNodeId instead of SubjectDescriptor - -* Make node id logging optional - -* Restyled by whitespace - -* Restyled by clang-format - ---------- - -Co-authored-by: Restyled.io ---- - src/lib/core/CHIPConfig.h | 10 ++++++++++ - src/lib/support/logging/TextOnlyLogging.h | 14 +++++++++++--- - 2 files changed, 21 insertions(+), 3 deletions(-) - -diff --git a/src/lib/core/CHIPConfig.h b/src/lib/core/CHIPConfig.h -index 2de6a662ee..558e0ee08e 100644 ---- a/src/lib/core/CHIPConfig.h -+++ b/src/lib/core/CHIPConfig.h -@@ -461,6 +461,16 @@ - #define CHIP_CONFIG_ENABLE_CONDITION_LOGGING 0 - #endif // CHIP_CONFIG_ENABLE_CONDITION_LOGGING - -+/** -+ * @def CHIP_EXCHANGE_NODE_ID_LOGGING -+ * -+ * @brief -+ * If asserted (1), enable logging of node IDs in exchange context. -+ */ -+#ifndef CHIP_EXCHANGE_NODE_ID_LOGGING -+#define CHIP_EXCHANGE_NODE_ID_LOGGING 1 -+#endif // CHIP_EXCHANGE_NODE_ID_LOGGING -+ - /** - * @def CHIP_CONFIG_TEST - * -diff --git a/src/lib/support/logging/TextOnlyLogging.h b/src/lib/support/logging/TextOnlyLogging.h -index d6b22f7c6c..b0abef9d00 100644 ---- a/src/lib/support/logging/TextOnlyLogging.h -+++ b/src/lib/support/logging/TextOnlyLogging.h -@@ -268,16 +268,24 @@ using LogRedirectCallback_t = void (*)(const char * module, uint8_t category, co - #define ChipLogValueMEI(aValue) static_cast(aValue >> 16), static_cast(aValue) - - /** -- * Logging helpers for exchanges. For now just log the exchange id and whether -- * it's an initiator or responder, but eventually we may want to log the peer -- * node id as well (especially for the responder case). Some callsites only -+ * Logging helpers for exchanges. Log the exchange id, whether -+ * it's an initiator or responder and the scoped node. Some callsites only - * have the exchange id and initiator/responder boolean, not an actual exchange, - * so we want to have a helper for that case too. - */ - #define ChipLogFormatExchangeId "%u%c" - #define ChipLogValueExchangeId(id, isInitiator) id, ((isInitiator) ? 'i' : 'r') -+ -+#if CHIP_EXCHANGE_NODE_ID_LOGGING -+#define ChipLogFormatExchange ChipLogFormatExchangeId " with Node: " ChipLogFormatScopedNodeId -+#define ChipLogValueExchange(ec) \ -+ ChipLogValueExchangeId((ec)->GetExchangeId(), (ec)->IsInitiator()), \ -+ ChipLogValueScopedNodeId((ec)->HasSessionHandle() ? (ec)->GetSessionHandle()->GetPeer() : ScopedNodeId()) -+#else // CHIP_EXCHANGE_NODE_ID_LOGGING - #define ChipLogFormatExchange ChipLogFormatExchangeId - #define ChipLogValueExchange(ec) ChipLogValueExchangeId((ec)->GetExchangeId(), (ec)->IsInitiator()) -+#endif // CHIP_EXCHANGE_NODE_ID_LOGGING -+ - #define ChipLogValueExchangeIdFromSentHeader(payloadHeader) \ - ChipLogValueExchangeId((payloadHeader).GetExchangeID(), (payloadHeader).IsInitiator()) - // A received header's initiator boolean is the inverse of the exchange's. --- -2.39.3 (Apple Git-146) - diff --git a/0011-Python-Use-Python-logging-everywhere-32383.patch b/0011-Python-Use-Python-logging-everywhere-32383.patch deleted file mode 100644 index 6b83445..0000000 --- a/0011-Python-Use-Python-logging-everywhere-32383.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 9189b790c7b6f713a40222ddec9ffb99742a05e7 Mon Sep 17 00:00:00 2001 -Message-ID: <9189b790c7b6f713a40222ddec9ffb99742a05e7.1711548827.git.stefan@agner.ch> -From: Stefan Agner -Date: Fri, 1 Mar 2024 09:43:47 +0100 -Subject: [PATCH] [Python] Use Python logging everywhere (#32383) - -Do not print to the console but use the Python logging module -explicitly. ---- - src/controller/python/chip/ChipDeviceCtrl.py | 23 ++++++++++---------- - 1 file changed, 12 insertions(+), 11 deletions(-) - -diff --git a/src/controller/python/chip/ChipDeviceCtrl.py b/src/controller/python/chip/ChipDeviceCtrl.py -index 318c2b56ef..bf9bb245ec 100644 ---- a/src/controller/python/chip/ChipDeviceCtrl.py -+++ b/src/controller/python/chip/ChipDeviceCtrl.py -@@ -34,6 +34,7 @@ import copy - import ctypes - import enum - import json -+import logging - import threading - import time - import typing -@@ -265,9 +266,9 @@ class ChipDeviceControllerBase(): - def _set_dev_ctrl(self, devCtrl): - def HandleCommissioningComplete(nodeid, err): - if err.is_success: -- print("Commissioning complete") -+ logging.info("Commissioning complete") - else: -- print("Failed to commission: {}".format(err)) -+ logging.warning("Failed to commission: {}".format(err)) - - self.state = DCState.IDLE - self._ChipStack.callbackRes = err -@@ -283,30 +284,30 @@ class ChipDeviceControllerBase(): - def HandleOpenWindowComplete(nodeid: int, setupPinCode: int, setupManualCode: str, - setupQRCode: str, err: PyChipError) -> None: - if err.is_success: -- print("Open Commissioning Window complete setting nodeid {} pincode to {}".format(nodeid, setupPinCode)) -+ logging.info("Open Commissioning Window complete setting nodeid {} pincode to {}".format(nodeid, setupPinCode)) - self._ChipStack.openCommissioningWindowPincode[nodeid] = CommissioningParameters( - setupPinCode=setupPinCode, setupManualCode=setupManualCode.decode(), setupQRCode=setupQRCode.decode()) - else: -- print("Failed to open commissioning window: {}".format(err)) -+ logging.warning("Failed to open commissioning window: {}".format(err)) - - self._ChipStack.callbackRes = err - self._ChipStack.completeEvent.set() - - def HandleUnpairDeviceComplete(nodeid: int, err: PyChipError): - if err.is_success: -- print("Succesfully unpaired device with nodeid {}".format(nodeid)) -+ logging.info("Succesfully unpaired device with nodeid {}".format(nodeid)) - else: -- print("Failed to unpair device: {}".format(err)) -+ logging.warning("Failed to unpair device: {}".format(err)) - - self._ChipStack.callbackRes = err - self._ChipStack.completeEvent.set() - - def HandlePASEEstablishmentComplete(err: PyChipError): - if not err.is_success: -- print("Failed to establish secure session to device: {}".format(err)) -+ logging.warning("Failed to establish secure session to device: {}".format(err)) - self._ChipStack.callbackRes = err.to_exception() - else: -- print("Established secure session with Device") -+ logging.info("Established secure session with Device") - - if self.state != DCState.COMMISSIONING: - # During Commissioning, HandlePASEEstablishmentComplete will also be called, -@@ -785,7 +786,7 @@ class ChipDeviceControllerBase(): - res = self._ChipStack.Call(lambda: self._dmLib.pychip_GetDeviceBeingCommissioned( - self.devCtrl, nodeid, byref(returnDevice)), timeoutMs) - if res.is_success: -- print('Using PASE connection') -+ logging.info('Using PASE connection') - return DeviceProxyWrapper(returnDevice) - - class DeviceAvailableClosure(): -@@ -1151,7 +1152,7 @@ class ChipDeviceControllerBase(): - # Wildcard - pass - elif not isinstance(pathTuple, tuple): -- print(type(pathTuple)) -+ logging.debug(type(pathTuple)) - if isinstance(pathTuple, int): - endpoint = pathTuple - elif issubclass(pathTuple, ClusterObjects.Cluster): -@@ -1426,7 +1427,7 @@ class ChipDeviceControllerBase(): - raise UnknownCommand(cluster, command) - try: - res = asyncio.run(self.SendCommand(nodeid, endpoint, req)) -- print(f"CommandResponse {res}") -+ logging.debug(f"CommandResponse {res}") - return (0, res) - except InteractionModelError as ex: - return (int(ex.status), None) --- -2.44.0 - diff --git a/0012-Python-Keep-reference-to-callback-function-on-timeou.patch b/0012-Python-Keep-reference-to-callback-function-on-timeou.patch deleted file mode 100644 index a23a81c..0000000 --- a/0012-Python-Keep-reference-to-callback-function-on-timeou.patch +++ /dev/null @@ -1,170 +0,0 @@ -From f5f84d9e4a7296680a606ab4c6ddd0e265374efc Mon Sep 17 00:00:00 2001 -From: Stefan Agner -Date: Wed, 13 Dec 2023 19:51:20 +0100 -Subject: [PATCH] [Python] Keep reference to callback function on timeout - (#30877) - -* [Python] Keep reference to callback function on timeout - -When using a timeout when calling GetConnectedDeviceSync() the callback -function DeviceAvailableCallback() gets potentially GC'ed. Make sure -we hold a reference to the instance. - -* Use correct namespace for PyObject - -* Fix types in pychip_GetConnectedDeviceByNodeId - -* Call callback with context (self) - -* Correctly pass context - -* Use separate closure function ---- - .../ChipDeviceController-ScriptBinding.cpp | 17 ++++----- - src/controller/python/chip/ChipDeviceCtrl.py | 35 ++++++++++++------- - 2 files changed, 31 insertions(+), 21 deletions(-) - -diff --git a/src/controller/python/ChipDeviceController-ScriptBinding.cpp b/src/controller/python/ChipDeviceController-ScriptBinding.cpp -index da742b2463..504b952d8a 100644 ---- a/src/controller/python/ChipDeviceController-ScriptBinding.cpp -+++ b/src/controller/python/ChipDeviceController-ScriptBinding.cpp -@@ -87,7 +87,7 @@ using namespace chip::DeviceLayer; - extern "C" { - typedef void (*ConstructBytesArrayFunct)(const uint8_t * dataBuf, uint32_t dataLen); - typedef void (*LogMessageFunct)(uint64_t time, uint64_t timeUS, const char * moduleName, uint8_t category, const char * msg); --typedef void (*DeviceAvailableFunc)(DeviceProxy * device, PyChipError err); -+typedef void (*DeviceAvailableFunc)(chip::Controller::Python::PyObject * context, DeviceProxy * device, PyChipError err); - typedef void (*ChipThreadTaskRunnerFunct)(intptr_t context); - typedef void (*DeviceUnpairingCompleteFunct)(uint64_t nodeId, PyChipError error); - } -@@ -202,7 +202,7 @@ const char * pychip_Stack_StatusReportToString(uint32_t profileId, uint16_t stat - void pychip_Stack_SetLogFunct(LogMessageFunct logFunct); - - PyChipError pychip_GetConnectedDeviceByNodeId(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeId, -- DeviceAvailableFunc callback); -+ chip::Controller::Python::PyObject * context, DeviceAvailableFunc callback); - PyChipError pychip_FreeOperationalDeviceProxy(chip::OperationalDeviceProxy * deviceProxy); - PyChipError pychip_GetLocalSessionId(chip::OperationalDeviceProxy * deviceProxy, uint16_t * localSessionId); - PyChipError pychip_GetNumSessionsToPeer(chip::OperationalDeviceProxy * deviceProxy, uint32_t * numSessions); -@@ -706,36 +706,37 @@ namespace { - - struct GetDeviceCallbacks - { -- GetDeviceCallbacks(DeviceAvailableFunc callback) : -- mOnSuccess(OnDeviceConnectedFn, this), mOnFailure(OnConnectionFailureFn, this), mCallback(callback) -+ GetDeviceCallbacks(chip::Controller::Python::PyObject * context, DeviceAvailableFunc callback) : -+ mOnSuccess(OnDeviceConnectedFn, this), mOnFailure(OnConnectionFailureFn, this), mContext(context), mCallback(callback) - {} - - static void OnDeviceConnectedFn(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle) - { - auto * self = static_cast(context); - auto * operationalDeviceProxy = new OperationalDeviceProxy(&exchangeMgr, sessionHandle); -- self->mCallback(operationalDeviceProxy, ToPyChipError(CHIP_NO_ERROR)); -+ self->mCallback(self->mContext, operationalDeviceProxy, ToPyChipError(CHIP_NO_ERROR)); - delete self; - } - - static void OnConnectionFailureFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error) - { - auto * self = static_cast(context); -- self->mCallback(nullptr, ToPyChipError(error)); -+ self->mCallback(self->mContext, nullptr, ToPyChipError(error)); - delete self; - } - - Callback::Callback mOnSuccess; - Callback::Callback mOnFailure; -+ chip::Controller::Python::PyObject * const mContext; - DeviceAvailableFunc mCallback; - }; - } // anonymous namespace - - PyChipError pychip_GetConnectedDeviceByNodeId(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeId, -- DeviceAvailableFunc callback) -+ chip::Controller::Python::PyObject * context, DeviceAvailableFunc callback) - { - VerifyOrReturnError(devCtrl != nullptr, ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT)); -- auto * callbacks = new GetDeviceCallbacks(callback); -+ auto * callbacks = new GetDeviceCallbacks(context, callback); - return ToPyChipError(devCtrl->GetConnectedDevice(nodeId, &callbacks->mOnSuccess, &callbacks->mOnFailure)); - } - -diff --git a/src/controller/python/chip/ChipDeviceCtrl.py b/src/controller/python/chip/ChipDeviceCtrl.py -index 08dbdff224..1572829591 100644 ---- a/src/controller/python/chip/ChipDeviceCtrl.py -+++ b/src/controller/python/chip/ChipDeviceCtrl.py -@@ -76,7 +76,7 @@ _DevicePairingDelegate_OnFabricCheckFunct = CFUNCTYPE( - # - # CHIP_ERROR is actually signed, so using c_uint32 is weird, but everything - # else seems to do it. --_DeviceAvailableFunct = CFUNCTYPE(None, c_void_p, PyChipError) -+_DeviceAvailableCallbackFunct = CFUNCTYPE(None, py_object, c_void_p, PyChipError) - - _IssueNOCChainCallbackPythonCallbackFunct = CFUNCTYPE( - None, py_object, PyChipError, c_void_p, c_size_t, c_void_p, c_size_t, c_void_p, c_size_t, c_void_p, c_size_t, c_uint64) -@@ -100,6 +100,11 @@ class NOCChain: - adminSubject: int - - -+@_DeviceAvailableCallbackFunct -+def _DeviceAvailableCallback(closure, device, err): -+ closure.deviceAvailable(device, err) -+ -+ - @_IssueNOCChainCallbackPythonCallbackFunct - def _IssueNOCChainCallbackPythonCallback(devCtrl, status: PyChipError, noc: c_void_p, nocLen: int, icac: c_void_p, - icacLen: int, rcac: c_void_p, rcacLen: int, ipk: c_void_p, ipkLen: int, adminSubject: int): -@@ -743,16 +748,6 @@ class ChipDeviceControllerBase(): - returnErr = None - deviceAvailableCV = threading.Condition() - -- @_DeviceAvailableFunct -- def DeviceAvailableCallback(device, err): -- nonlocal returnDevice -- nonlocal returnErr -- nonlocal deviceAvailableCV -- with deviceAvailableCV: -- returnDevice = c_void_p(device) -- returnErr = err -- deviceAvailableCV.notify_all() -- - if allowPASE: - res = self._ChipStack.Call(lambda: self._dmLib.pychip_GetDeviceBeingCommissioned( - self.devCtrl, nodeid, byref(returnDevice)), timeoutMs) -@@ -760,8 +755,22 @@ class ChipDeviceControllerBase(): - print('Using PASE connection') - return DeviceProxyWrapper(returnDevice) - -+ class DeviceAvailableClosure(): -+ def deviceAvailable(self, device, err): -+ nonlocal returnDevice -+ nonlocal returnErr -+ nonlocal deviceAvailableCV -+ with deviceAvailableCV: -+ returnDevice = c_void_p(device) -+ returnErr = err -+ deviceAvailableCV.notify_all() -+ ctypes.pythonapi.Py_DecRef(ctypes.py_object(self)) -+ -+ closure = DeviceAvailableClosure() -+ ctypes.pythonapi.Py_IncRef(ctypes.py_object(closure)) - self._ChipStack.Call(lambda: self._dmLib.pychip_GetConnectedDeviceByNodeId( -- self.devCtrl, nodeid, DeviceAvailableCallback), timeoutMs).raise_on_error() -+ self.devCtrl, nodeid, ctypes.py_object(closure), _DeviceAvailableCallback), -+ timeoutMs).raise_on_error() - - # The callback might have been received synchronously (during self._ChipStack.Call()). - # Check if the device is already set before waiting for the callback. -@@ -1491,7 +1500,7 @@ class ChipDeviceControllerBase(): - self._dmLib.pychip_ScriptDevicePairingDelegate_SetFabricCheckCallback.restype = PyChipError - - self._dmLib.pychip_GetConnectedDeviceByNodeId.argtypes = [ -- c_void_p, c_uint64, _DeviceAvailableFunct] -+ c_void_p, c_uint64, py_object, _DeviceAvailableCallbackFunct] - self._dmLib.pychip_GetConnectedDeviceByNodeId.restype = PyChipError - - self._dmLib.pychip_FreeOperationalDeviceProxy.argtypes = [ --- -2.44.0 - diff --git a/0013-Python-Implement-async-friendly-GetConnectedDevice.patch b/0013-Python-Implement-async-friendly-GetConnectedDevice.patch deleted file mode 100644 index a6535de..0000000 --- a/0013-Python-Implement-async-friendly-GetConnectedDevice.patch +++ /dev/null @@ -1,115 +0,0 @@ -From eeaecf615bda4192c31d3cb569f951bede052caa Mon Sep 17 00:00:00 2001 -From: Stefan Agner -Date: Wed, 27 Mar 2024 22:13:19 +0100 -Subject: [PATCH] [Python] Implement async friendly GetConnectedDevice - -Currently GetConnectedDeviceSync() is blocking e.g. when a new session -needs to be created. This is not asyncio friendly as it blocks the -whole event loop. - -Implement a asyncio friendly variant GetConnectedDevice() which is -a co-routine function which can be awaited. ---- - src/controller/python/chip/ChipDeviceCtrl.py | 58 ++++++++++++++++++-- - 1 file changed, 54 insertions(+), 4 deletions(-) - -diff --git a/src/controller/python/chip/ChipDeviceCtrl.py b/src/controller/python/chip/ChipDeviceCtrl.py -index 4a1b3af3e2..08dbdff224 100644 ---- a/src/controller/python/chip/ChipDeviceCtrl.py -+++ b/src/controller/python/chip/ChipDeviceCtrl.py -@@ -780,6 +780,56 @@ class ChipDeviceControllerBase(): - - return DeviceProxyWrapper(returnDevice, self._dmLib) - -+ async def GetConnectedDevice(self, nodeid, allowPASE=True, timeoutMs: int = None): -+ ''' Returns DeviceProxyWrapper upon success.''' -+ self.CheckIsActive() -+ -+ if allowPASE: -+ returnDevice = c_void_p(None) -+ res = self._ChipStack.Call(lambda: self._dmLib.pychip_GetDeviceBeingCommissioned( -+ self.devCtrl, nodeid, byref(returnDevice)), timeoutMs) -+ if res.is_success: -+ logging.info('Using PASE connection') -+ return DeviceProxyWrapper(returnDevice) -+ -+ eventLoop = asyncio.get_running_loop() -+ future = eventLoop.create_future() -+ -+ class DeviceAvailableClosure(): -+ def __init__(self, loop, future: asyncio.Future): -+ self._returnDevice = c_void_p(None) -+ self._returnErr = None -+ self._event_loop = loop -+ self._future = future -+ -+ def _deviceAvailable(self): -+ if self._returnDevice.value is not None: -+ self._future.set_result(self._returnDevice) -+ else: -+ self._future.set_exception(self._returnErr.to_exception()) -+ -+ def deviceAvailable(self, device, err): -+ self._returnDevice = c_void_p(device) -+ self._returnErr = err -+ self._event_loop.call_soon_threadsafe(self._deviceAvailable) -+ ctypes.pythonapi.Py_DecRef(ctypes.py_object(self)) -+ -+ closure = DeviceAvailableClosure(eventLoop, future) -+ ctypes.pythonapi.Py_IncRef(ctypes.py_object(closure)) -+ self._ChipStack.Call(lambda: self._dmLib.pychip_GetConnectedDeviceByNodeId( -+ self.devCtrl, nodeid, ctypes.py_object(closure), _DeviceAvailableCallback), -+ timeoutMs).raise_on_error() -+ -+ # The callback might have been received synchronously (during self._ChipStack.Call()). -+ # In that case the Future has already been set it will return immediately -+ if (timeoutMs): -+ timeout = float(timeoutMs) / 1000 -+ await asyncio.wait_for(future, timeout=timeout) -+ else: -+ await future -+ -+ return DeviceProxyWrapper(future.result(), self._dmLib) -+ - def ComputeRoundTripTimeout(self, nodeid, upperLayerProcessingTimeoutMs: int = 0): - ''' Returns a computed timeout value based on the round-trip time it takes for the peer at the other end of the session to - receive a message, process it and send it back. This is computed based on the session type, the type of transport, -@@ -804,7 +854,7 @@ class ChipDeviceControllerBase(): - eventLoop = asyncio.get_running_loop() - future = eventLoop.create_future() - -- device = self.GetConnectedDeviceSync(nodeid, timeoutMs=None) -+ device = await self.GetConnectedDevice(nodeid, timeoutMs=None) - ClusterCommand.TestOnlySendCommandTimedRequestFlagWithNoTimedInvoke( - future, eventLoop, responseType, device.deviceProxy, ClusterCommand.CommandPath( - EndpointId=endpoint, -@@ -831,7 +881,7 @@ class ChipDeviceControllerBase(): - eventLoop = asyncio.get_running_loop() - future = eventLoop.create_future() - -- device = self.GetConnectedDeviceSync(nodeid, timeoutMs=interactionTimeoutMs) -+ device = await self.GetConnectedDevice(nodeid, timeoutMs=interactionTimeoutMs) - ClusterCommand.SendCommand( - future, eventLoop, responseType, device.deviceProxy, ClusterCommand.CommandPath( - EndpointId=endpoint, -@@ -876,7 +926,7 @@ class ChipDeviceControllerBase(): - eventLoop = asyncio.get_running_loop() - future = eventLoop.create_future() - -- device = self.GetConnectedDeviceSync(nodeid, timeoutMs=interactionTimeoutMs) -+ device = await self.GetConnectedDevice(nodeid, timeoutMs=interactionTimeoutMs) - - attrs = [] - for v in attributes: -@@ -1097,7 +1147,7 @@ class ChipDeviceControllerBase(): - eventLoop = asyncio.get_running_loop() - future = eventLoop.create_future() - -- device = self.GetConnectedDeviceSync(nodeid) -+ device = await self.GetConnectedDevice(nodeid) - attributePaths = [self._parseAttributePathTuple( - v) for v in attributes] if attributes else None - clusterDataVersionFilters = [self._parseDataVersionFilterTuple( --- -2.44.0 -