hbldh / bleak

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

On Raspberry pi bleakscanner scanning not working :BleakDBusError[org.bluez.Error.InProgress] Operation already in progress . #1603

Open wahadatjan opened 3 months ago

wahadatjan commented 3 months ago

Description

when i tried to scan the ble devices it gives me this error while running code on Raspberry pi

Internal Server Error: /scan-devices/
Traceback (most recent call last):
  File "/srv/envs/hermes_device/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/srv/envs/hermes_device/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/envs/hermes_device/lib/python3.11/site-packages/asgiref/sync.py", line 254, in __call__
    return call_result.result()
           ^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/concurrent/futures/_base.py", line 449, in result
    return self.__get_result()
           ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/concurrent/futures/_base.py", line 401, in __get_result
    raise self._exception
  File "/srv/envs/hermes_device/lib/python3.11/site-packages/asgiref/sync.py", line 331, in main_wrap
    result = await self.awaitable(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/device_interface/bledevice/views.py", line 22, in scan_devices
    devices = await scanner.discover()
              ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/envs/hermes_device/lib/python3.11/site-packages/bleak/__init__.py", line 320, in discover
    async with cls(**kwargs) as scanner:
  File "/srv/envs/hermes_device/lib/python3.11/site-packages/bleak/__init__.py", line 158, in __aenter__
    await self._backend.start()
  File "/srv/envs/hermes_device/lib/python3.11/site-packages/bleak/backends/bluezdbus/scanner.py", line 185, in start
    self._stop = await manager.active_scan(
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/srv/envs/hermes_device/lib/python3.11/site-packages/bleak/backends/bluezdbus/manager.py", line 438, in active_scan
    assert_reply(reply)
  File "/srv/envs/hermes_device/lib/python3.11/site-packages/bleak/backends/bluezdbus/utils.py", line 20, in assert_reply
    raise BleakDBusError(reply.error_name, reply.body)
bleak.exc.BleakDBusError: [org.bluez.Error.InProgress] Operation already in progress
[30/May/2024 10:17:31] "GET /scan-devices/ HTTP/1.1" 500 90195
dlech commented 3 months ago

Can you please share a minimal reproducible test case?

Likely, you are doing exactly what the error says and trying to start a scanner while another scanner is still running.

wahadatjan commented 3 months ago

@dlech it is a django project which i am trying to run on raspberry pi where i am trying to call a django view for scanning the ble devices but it crashes

async def scan_devices(request):
    async def scan_callback(device, advertising_data):
        # Process advertising data here
        print("Device:", device.address)
        print("Advertisement Data:", advertising_data)
        # You can extract specific data based on keys or parsing formats

    devices = []
    async with BleakScanner(scan_callback) as scanner:
        await scanner.start()  # Start scanning for devices
        # Wait for a short duration (adjust as needed)
        await asyncio.sleep(5)
        await scanner.stop()  # Stop scanning after the wait time
        devices = scanner.discovered_devices  # Get discovered devices

    formatted_devices = [{
        'uuid': str(device.address),
        'name': device.name if device.name else 'Unknown',
        'adv_data': "advertising_data"  # Include advertising data in the response
    } for device in devices]

    return JsonResponse({'devices': formatted_devices})
dlech commented 3 months ago

If two requests can come in within the 5 second scan time, this could cause the problem. You could protect against concurrent scanning by using an asyncio.Lock (maybe a good idea to return a busy error if the lock is held because of the long wait time?).

gudnimg commented 3 months ago

When using BlueZ, running btmon in a separate terminal may help reveal what is happening. It can show a more verbose meaning to the error message as multiple things can produce org.bluez.Error.InProgress.

wahadatjan commented 3 months ago

@dlech connecting to multiple device is working fine but when it comes to get data from characteristics from different connected devices it gives data from a single device only .

dlech commented 3 months ago

when it comes to get data from characteristics from different connected devices it gives data from a single device only .

Can you please start a new issue with a minimal reproducible test case and Bluetooth packet capture logs and Bleak debug logs showing the issue?

denravonska commented 1 month ago

We're having the same problem on bleak-0.21.1 and 0.22.2. It can work a few times before we get the error. The process exits before the next run starts so there shouldn't be any stray scanners laying around.

btmon:

@ MGMT Command: Start Service Discovery (0x003a) plen 4
        Address type: 0x06
          LE Public
          LE Random
        RSSI: invalid (0x7f)
        UUIDs: 0
< HCI Command: LE Set Random Address (0x08|0x0005) plen 6
        Address: 2A:F1:57:42:D3:68 (Non-Resolvable)
< HCI Command: LE Set Scan Parameters (0x08|0x000b) plen 7
        Type: Active (0x01)
        Interval: 11.250 msec (0x0012)
        Window: 11.250 msec (0x0012)
        Own address type: Public (0x00)
        Filter policy: Accept all advertisement (0x00)
@ MGMT Event: Command Complete (0x0001) plen 4
      Start Service Discovery (0x003a) plen 1
        Status: Authentication Failed (0x05)
        Address type: 0x06
          LE Public
          LE Random
denravonska commented 1 month ago

Updating the firmware using rpi-update seems to have solved it on our end. I haven't been able to trigger it anymore.