Bleak and Applications with GUI
See original GitHub issue- bleak version: 0.7.1
- Python version: 3.8
- Operating System: macOS Catalina 10.15.6
Description
So before anything, I know that this “issue” that I am writing is not actually Bleak’s issue/bug. It is more of a question than a bug report. In summary, I want to use Bleak in an application that has a graphical user interface and I am having issues with the asynchronous nature of Bleak. I explained the steps I’ve taken and the errors I faced in detail below:
What I Did
Since I already had a GUI written in Kivy, I tried to use Bleak and integrate it into the Kivy’s Button callbacks.
For the search (discovery) part, I wrote async def search_for_bles()
in which I call await discover()
. To call this function from the button’s callback I had to use asyncio.run()
method, which worked fine!
I used the same strategy (await
, async def
, and asyncio.run
) connect()
, here is a part of the code (I removed the pointless lines)
def connect_btn_callback(self,......):
self.ble_obj=BLE(found_client, ...... )
asyncio.run(self.ble_obj.connect()) # [1] Works fine.
asyncio.run(self.ble_obj.ask_control()) # [2] Runtime Error: 'Event loop is closed'
in the BLE class:
def __init__ (self, client, .....):
self.client=client
....
async def connect (self):
await self.client.connect() # [3] works fine
await self.ask_control() # [4] works fine
async def ask_control(self):
await self.client.write_gatt_char(constants.CONTROL_HANDLE, bytearray([0x02, 0x73, 0x0a]), False)
The comments in the code are showing where the error occurs (this also happens for the disconnect, and other methods)
What is interesting for me is that the ask_control
inside [1], i.e. [4], works without an issue (this means that the ask_control
function is healthy). However, [2] gives me an error, RunTime error: 'event loop is closed'
Other things that I have tried:
After a few days working on these issues full-time, I found many related issues but none of the solutions worked:
from asgiref.sync import async_to_sync
- Using
loop=asyncio.get_event_loop()
- Using
loop=asyncio.get_running_loop()
- Using
loop=asyncio.new_event_loop
andasyncio.set_event_loop(loop)
- Using
nest_asyncio
What I am asking
So I am presenting this issue to you not (specifically) as the developers of Bleak, but as experienced python users/developers. I want to have Bleak and a cross-platform GUI in one app. Even if you think that using another GUI makes using Bleak easier, please let me know.
Thank you.
Issue Analytics
- State:
- Created 3 years ago
- Comments:5 (2 by maintainers)
Top GitHub Comments
Thank you, @hbldh for your response. So the reason I didn’t use
async_run()
(Kivy) was that it was only available on therc
versions (not the stable 1.11.1). Anyway, I updated Kivy to 2.0.0rc3 and tried running the Bleak functions usingloop=asyncio.get_event_loop()
andloop.run_until_complete
. Of course, another problem arose; apparentlyrun_until_complete
closes theloop
after the future function returns, and because the loop is shared with UI, the applictation crashes.For future reference: the issue can be solved by having these two lines at the beginning of the code:
Thank you for answering my question, everything is working fine now. I am closing this thread.
P.S. @Carglglz Thanks for your comment. As I mentioned in the “Other things that I have tried” section of my initial post, getting the currently running loop (with
asyncio.get_event_loop()
) gave me the same error. The reason is that the Kivy does not lwt go of the running thread and thus there is not any event loop for asyncio to extract.@bardiabarabadi
The reason for this is explained in the
asyncio.run
docstring. The important part:(do
help(asyncio.run)
to see the complete version)So I use
loop.run_until_complete
instead and it works great. (at least with PyQt5) 👍