bleak icon indicating copy to clipboard operation
bleak copied to clipboard

Cannot notify/write to a characteristic

Open raghumulukutla opened this issue 3 years ago • 1 comments

  • bleak version: 0.15.1
  • Python version: 3.8.0
  • Operating System: Windows 11
  • BlueZ version (bluetoothctl -v) in case of Linux:

Description

I would like to scan for a bluetooth device using BleakClient, notify and write to two different characteristics

What I Did

import asyncio
from bleak import BleakScanner, BleakClient
from bleak.backends.winrt.client import BleakClientWinRT
from bleak.backends.winrt.scanner import BleakScannerWinRT


class BLDevice:
    async def scan(self):
        devices = await BleakScanner.discover()
        for d in devices:
            print(d)

    def __init__(self, mac_addr: str):
        self.mac_addr = mac_addr
        self.client = None

    async def connect(self):
        if not self.client:
            device = await BleakScannerWinRT.find_device_by_address(self.mac_addr, 20)
            self.client = BleakClientWinRT(address_or_ble_device=device)
            if not self.client.is_connected:
                await self.client.connect()

    async def write(self):
        def response_handler(sender, data):
            print("{}: {}".format(sender, data))

        await self.connect()
        await self.client.write_gatt_char("0000xxxxx-xxxxx-xxxxx-xxxxx-xxxxxxxxxxxx", str.encode("hello world!"))

    async def get_sc(self):
        await self.connect()
        for svc in await self.client.get_services():
            for ch in svc.characteristics:
                print(ch)


if __name__ == '__main__':
    MAC_ADDR = "FF:FF:FF:FF:FF:FF"
    my_device = BLDevice(MAC_ADDR)
    loop = asyncio.get_event_loop()
    loop.run_until_complete(my_device.connect())
    loop.run_until_complete(my_device.write())

I rant the above code and the following error:

Traceback (most recent call last):
  File "C:/workstation/repos/bleak_demo/bleak_demo/run.py", line 32, in write
    await self.client.write_gatt_char("0000xxxxx-xxxxx-xxxxx-xxxxx-xxxxxxxxxxxx", str.encode("hello world!"))
  File "C:\Users\raghu\AppData\Local\pypoetry\Cache\virtualenvs\bleak-demo-xIb3w8Wb-py3.8\lib\site-packages\bleak\backends\winrt\client.py", line 665, in write_gatt_char
    _ensure_success(
  File "C:\Users\raghu\AppData\Local\pypoetry\Cache\virtualenvs\bleak-demo-xIb3w8Wb-py3.8\lib\site-packages\bleak\backends\winrt\client.py", line 107, in _ensure_success
    raise BleakError(f"{fail_msg}: Unreachable")
bleak.exc.BleakError: Could not write value b'hello world!' to characteristic 000A: Unreachable

here is the output from Windows bluetooth virtual sniffer

87	29.147761	TexasIns_ (XXXX-XXX)	localhost ()	SMP	11	Rcvd Security Request: AuthReq: No Bonding

raghumulukutla avatar Aug 22 '22 19:08 raghumulukutla

The program is doing a bunch of things it shouldn't. Bleak expects the use of one and only one asyncio.run() instead of the deprecated asyncio.get_event_loop() and multiple run_until_complete()s. Also connect is called multiple times which could be confusing the OS Bluetooth stack.

If the problem still persists after fixing the program, I would suggest logging Bluetooth packets as described in the troubleshooting page of the docs to see what is going on.

dlech avatar Aug 26 '22 21:08 dlech