|
26 | 26 |
|
27 | 27 | from __future__ import absolute_import, print_function
|
28 | 28 |
|
| 29 | +import asyncio |
29 | 30 | import builtins
|
30 | 31 | import logging
|
31 | 32 | import os
|
@@ -164,6 +165,30 @@ def Wait(self, timeoutMs: int = None):
|
164 | 165 | return self._res
|
165 | 166 |
|
166 | 167 |
|
| 168 | +class AsyncSimpleCallableHandle: |
| 169 | + """Class which handles Matter SDK Calls asyncio friendly""" |
| 170 | + def __init__(self, callback, loop, future): |
| 171 | + self._callback = callback |
| 172 | + self._loop = loop |
| 173 | + self._future = future |
| 174 | + self._result = None |
| 175 | + self._exception = None |
| 176 | + |
| 177 | + def _done(self): |
| 178 | + if self._exception: |
| 179 | + self._future.set_exception(self._exception) |
| 180 | + else: |
| 181 | + self._future.set_result(self._result) |
| 182 | + |
| 183 | + def __call__(self): |
| 184 | + try: |
| 185 | + self._result = self._callback() |
| 186 | + except Exception as ex: |
| 187 | + self._exception = ex |
| 188 | + self._loop.call_soon_threadsafe(self._done) |
| 189 | + pythonapi.Py_DecRef(py_object(self)) |
| 190 | + |
| 191 | + |
167 | 192 | _CompleteFunct = CFUNCTYPE(None, c_void_p, c_void_p)
|
168 | 193 | _ErrorFunct = CFUNCTYPE(None, c_void_p, c_void_p,
|
169 | 194 | c_ulong, POINTER(DeviceStatusStruct))
|
@@ -367,6 +392,24 @@ def Call(self, callFunct, timeoutMs: int = None):
|
367 | 392 | return self.callbackRes
|
368 | 393 | return res
|
369 | 394 |
|
| 395 | + async def CallAsync(self, callFunct, timeoutMs: int = None): |
| 396 | + '''Run a Python function on CHIP stack, and wait for the response. |
| 397 | + This function will post a task on CHIP mainloop and waits for the call response in a asyncio friendly manner. |
| 398 | + ''' |
| 399 | + loop = asyncio.get_event_loop() |
| 400 | + future = loop.create_future() |
| 401 | + callObj = AsyncSimpleCallableHandle(callFunct, loop, future) |
| 402 | + pythonapi.Py_IncRef(py_object(callObj)) |
| 403 | + |
| 404 | + res = self._ChipStackLib.pychip_DeviceController_PostTaskOnChipThread( |
| 405 | + self.cbHandleChipThreadRun, py_object(callObj)) |
| 406 | + |
| 407 | + if not res.is_success: |
| 408 | + pythonapi.Py_DecRef(py_object(callObj)) |
| 409 | + raise res.to_exception() |
| 410 | + |
| 411 | + return await asyncio.wait_for(future, timeoutMs / 1000 if timeoutMs else None) |
| 412 | + |
370 | 413 | def CallAsyncWithCallback(self, callFunct):
|
371 | 414 | '''Run a Python function on CHIP stack, and wait for the application specific response.
|
372 | 415 | This function is a wrapper of PostTaskOnChipThread, which includes some handling of application specific logics.
|
|
0 commit comments