question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Any way of using bleak in a non blocking way?

See original GitHub issue
  • bleak version:0.14.3
  • Python version:3.9
  • Operating System:Android
  • BlueZ version (bluetoothctl -v) in case of Linux:

Description

Bleak commands are working perfectly but while it is in process it blocks the whole app, any way to use bleak in a non blocking way .Tried threading at first but didnt work . any other way it can be done?

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:5

github_iconTop GitHub Comments

2reactions
dlechcommented, May 18, 2022

To start, there should be one top-level asyncio.run() to run the entire app as in https://github.com/hbldh/bleak/blob/develop/examples/kivy/main.py. There should be no other calls that start a new event loop. Instead, there are functions like asyncio.create_task() that can start running an async coroutine from a non-async function.

Since the popup code is not awaitabile, it doesn’t need to be in an async function.

Maybe something like this?

import asyncio
from kivy.uix.image import Image
from kivy.uix.popup import Popup
from kivymd.uix.floatlayout import MDFloatLayout
from kivymd.uix.label import MDLabel
import bleak
from kivy.uix.screenmanager import Screen

class TestScreen(Screen):
    aa=''
    def on_enter(self, *args):
        self.ids.b1.disabled = False

    def create_popup(self):
        box = MDFloatLayout()
        i = Image(source='2.gif',size_hint=(.8, .8), pos_hint={'x': 0, 'y': 0.1})

        box.add_widget(i)

        popup = Popup(title=' ', content=box,separator_height=0,
                              size_hint=(.6, .7), auto_dismiss=False, title_size=30,background_color=(0,0,0,0))

        popup.open()

        return popup

    def on_button_press(self):
        asyncio.create_task(self.scan())
   
    async def scan(self):
        def handler(sender, data):
            print(data)
            self.val=data

        hr_uuid = "0000dfb1-0000-1000-8000-00805f9b34fb"
        ADDRESS = "C4:BE:84:20:19:3F"
        a = []
        self.ids.p_fat.text=' '

        popup = self.create_popup()

        try:
            scanned_devices = await bleak.BleakScanner.discover(1)
         
            if len(scanned_devices) == 0:
                print("NO DEVICES")
                self.main_pop.dismiss()
            scanned_devices.sort(key=lambda device: -device.rssi)
            for device in scanned_devices:
                device1 = f"{device.name}"
                print(device1)
            
                if device1 == "Bluno":
                    try:           
                        async with bleak.BleakClient(device) as client:    
                            uu = '1'
                            write_value = bytearray([int(uu)])
                            await client.write_gatt_char(hr_uuid, write_value)
                            await asyncio.sleep(3.0)
                
                            await client.start_notify(hr_uuid, handler)
                            await asyncio.sleep(10.0)
                            await client.stop_notify(hr_uuid)
                         
                        
                    except:
                        await asyncio.sleep(3.0)
                        toast('Error 101')
                else:
                    toast('No device',duration=1)
        finally:
            popup.dismiss()

class ExampleApp(App):
    ...


async def main():
    app = ExampleApp()
    await app.async_run("asyncio")


if __name__ == "__main__":
    asyncio.run(main())
0reactions
NewAge12commented, May 18, 2022
import asyncio
from kivy.uix.image import Image
from kivy.uix.popup import Popup
from kivymd.uix.floatlayout import MDFloatLayout
from kivymd.uix.label import MDLabel
import bleak
from kivy.uix.screenmanager import Screen

class TestScreen(Screen):
    aa=''
    def on_enter(self, *args):
        self.ids.b1.disabled = False

   
   async  def scanPOP(self):
        box = MDFloatLayout()
        i = Image(source='2.gif',size_hint=(.8, .8), pos_hint={'x': 0, 'y': 0.1})

        box.add_widget(i)

        self.main_pop = Popup(title=' ', content=box,separator_height=0,
                              size_hint=(.6, .7), auto_dismiss=False, title_size=30,background_color=(0,0,0,0))

        self.main_pop.open()

    def scan1(self):
         loop1 = asyncio.get_event_loop()
        loop1.run_until_complete(self.scanPOP())
        loop = asyncio.get_event_loop()
        loop.run_until_complete(self.begin_scan1())
   
    async def begin_scan1(self):
        def handler(sender, data):
            print(data)
            self.val=data
        hr_uuid = "0000dfb1-0000-1000-8000-00805f9b34fb"
        ADDRESS = "C4:BE:84:20:19:3F"
        a = []
        self.ids.p_fat.text=' '
        scanned_devices = await bleak.BleakScanner.discover(1)
         
        if len(scanned_devices) == 0:
            print("NO DEVICES")
            self.main_pop.dismiss()
        scanned_devices.sort(key=lambda device: -device.rssi)
        for device in scanned_devices:
            device1 = f"{device.name}"
            print(device1)
            
            if device1 == "Bluno":
                try:           
                    async with bleak.BleakClient(device) as client:    
                        uu = '1'
                        write_value = bytearray([int(uu)])
                        await client.write_gatt_char(hr_uuid, write_value)
                        await asyncio.sleep(3.0)
                
                        await client.start_notify(hr_uuid, handler)
                        await asyncio.sleep(10.0)
                        await client.stop_notify(hr_uuid)
                         
                        
                except:
                    await asyncio.sleep(3.0)
                    toast('Error 101')
            else:
                toast('No device',duration=1)
                self.main_pop.dismiss()

The scan1() is called on the press of a button. What happens is the scan is done and after that the popup is called which is wrong. Cant really figure out a way to do both these things simultaneously. Is there anything wrong in the code??

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to Send Data between PC and Arduino using ...
A how-to guide on connecting your PC to an Arduino using Bluetooth LE and Python. To make it easier, we will use bleak...
Read more >
Run bleak (python library) in background with asyncio
Be aware that in asyncio you're not allowed to call anything that might block. All blocking calls must be async and called using...
Read more >
Troubleshooting — bleak 0.20.0a1 documentation
The easiest way to enable logging is to set the BLEAK_LOGGING environment variable. Setting the variable depends on what type of terminal you...
Read more >
Asyncio with Threading and Bleak : r/learnpython
I'm trying to write a script that will connect to a BLE device (using bleak), receive uart data, and then be able to...
Read more >
Bookforum and a Bleak Year for Literary Magazines
Criticism has a way of surviving without infrastructure, but there is no replacement for institutions that cultivate a point of view over time....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found