hbldh / bleak

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

macOS client.start_notify fails after reconnect #1645

Open dakhnod opened 1 month ago

dakhnod commented 1 month ago

Description

When running client.start_notify on a device that has previously been connected to and that disconnected and connected again, it throws the exception ValueError: Characteristic notifications already started.

Not calling the function a second time causes no notifications to arrive.

dlech commented 1 month ago

Can you give an example program and the exact steps to reproduce the problem?

dakhnod commented 1 month ago

Yep, sorry. Attached is a minimal demo program. Somehow, bleak or some other component seems to remember a notification subscription, even if the device disconnected...

import bleak
import asyncio

# replace this with anything suiting on your device
notify_uuid = '00002a56-0000-1000-8000-00805f9b34fb'

async def main():
    scanner = bleak.BleakScanner()

    disconnect_event = asyncio.Event()
    client = bleak.BleakClient(
        await scanner.find_device_by_name('BLEnky demo'),
        lambda client: disconnect_event.set()
    )
    await client.connect()
    await client.start_notify(notify_uuid, print)

    print('connected, please restart device')

    await disconnect_event.wait()

    print('reconnecting...')

    await client.connect()
    # this will throw on macOS, not on linux
    await client.start_notify(notify_uuid, print)

    print('reconnected.')

asyncio.run(main())

Steps to reproduce:

  1. Put in the name of a test device you can connect to and restart
  2. Put in the UUID of some notification that can be subscribed to
  3. Run script
  4. When prompted, restart device
  5. Watch exception get thrown, but only on mac

Besides, great work on this! This library is a pleasure to use, I wish there was something comperable for js! Thank you!

MAKOMO commented 1 month ago

I experience this too for v0.22.3 on macOS 15.0.1

dlech commented 1 month ago

Calling connect() a second time on the same BleakClient object is something that has never worked well in Bleak. We recommend to create a new BleakClient object in order to connect again.

MAKOMO commented 1 month ago

Thanks David for this hint! Not reusing that client resolves the reconnect issues for me. Keep going!