hbldh / bleak

A cross platform Bluetooth Low Energy Client for Python using asyncio
MIT License
1.84k stars 303 forks source link

A way to detect BT module not being present or disabled at all #320

Open SteKme opened 4 years ago

SteKme commented 4 years ago

Description

Discovery service - BleakScanner.discover() - returns [] no matter if there are no devices the PC can connect to (which is fine, indeed), but also when the BT module of the PC is turned off (my case, notebook's BT module off in the right hand command control center of Windows) ** ? or the BT module not present at all (can't check if this applies as well at the moment).

I can't seem to find any way to detect the BT module of the PC not being present / disabled in the Windows. Would it be perhaps possible to throw an exception or something in this discover() when there is no BTLE hardware connected to the PC at all? Any other working solution is fine, of course.

Thank You so much!

hbldh commented 4 years ago

Currently, Bleak has no capability to check if your computer's Bluetooth adapter is on or off. There are API methods that can check it, and in one case it seems it can also switch them on and off (BlueZ).

It is not a priority task for me I am afraid. You are more than welcome to do the implementation and make a PR, because I approve of the functionality being present.

dlech commented 4 years ago

We are actually already monitoring this in CoreBluetooth:

https://github.com/hbldh/bleak/blob/9ff5ed8ccbb0493e2994a0bbfe9ebf26810878fb/bleak/backends/corebluetooth/CentralManagerDelegate.py#L178-L195

And the suggested exception is already implemented:

https://github.com/hbldh/bleak/blob/1d6c4031790abed4efe7008c36c8d9b1861856db/bleak/backends/corebluetooth/discovery.py#L18-L29

https://github.com/hbldh/bleak/blob/9ff5ed8ccbb0493e2994a0bbfe9ebf26810878fb/bleak/backends/corebluetooth/scanner.py#L42-L46

We should also revisit the use of wait_for_powered_on() in CoreBluetooth when we look at this. According to the CoreBluetooth docs, we should be waiting for this to be resolved before calling any other APIs, but I don't think we are doing that in all cases. (Note to self: we can probably use a threading.Event instead of asyncio.Event and make the __init__() method blocking when we create a new central manager - it shouldn't block for long.)

0ge commented 2 years ago

We have ran into this for a tool we developed. One user frequently turned off his Bluetooth radio (because of other reasons) but the tool has no way of informing him that the radio is turned off. For our use case, it would work with either an exception when attempting to scan, but preferably a separate method/property/function that we could check so that the user can be informed before attempting to scan.

Our current workaround is to display a reminder to check if the radio is off when no devices are discovered.