hbldh / bleak

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

bleak.exc.BleakError: Not connected #1459

Open dxdate opened 10 months ago

dxdate commented 10 months ago

Description

the connection closes 30-120 seconds after the script is run

Code

import time
import colorsys
import asyncio
from bleak import BleakClient, BleakScanner

BLEDOM_CHARACTERISTIC = "0000fff3-0000-1000-8000-00805f9b34fb"
import logging
logging.basicConfig(level=logging.DEBUG, filename="py_log.log",filemode="w")

class BleLedDevice:
    def __init__(self, peripheral, characteristics):
        self.peripheral = peripheral
        self.characteristics = characteristics

    @staticmethod
    async def new(device_address: str) -> "BleLedDevice":
        bt_client = BleakClient(device_address)
        device = BleLedDevice(bt_client, [])
        await device.connect()
        await device.discover_characteristics()
        await device.power_on()
        return device

    async def connect(self):
        await self.peripheral.connect()

    async def discover_characteristics(self):
        services = await self.peripheral.get_services()
        for service in services:
            for characteristic in service.characteristics:
                if characteristic.uuid == BLEDOM_CHARACTERISTIC:
                    self.characteristics.append(characteristic)
        if not self.characteristics:
            raise Exception(f"Couldn't find the BLEDOM characteristic on the device.")

    def _characteristic(self):
        return self.characteristics[0]

    async def power_on(self):
        """
        Power LED strip on.
        """

        await self.generic_command(0x04, 0xF0, 0x00, 0x01, 0xFF)

    async def power_off(self):
        """
        Power LED strip off.
        """

        await self.generic_command(0x04, 0x00, 0x00, 0x00, 0xFF)

    async def set_color(self, red: int, green: int, blue: int):
        """
        Show a solid colour.

        The values for `red`, `green` and `blue` are expected to be integers
        with values between 0 and 255 (inclusive).
        """

        await self.generic_command(0x05, 0x03, red, green, blue)

    async def set_brightness(self, value: int):
        """
        Show a solid brightness.

        The value for `value` is expected to be an integer between 0 and 100
        (inclusive).
        """

        await self.generic_command(0x01, min(value, 100), 0, 0, 0)

    async def generic_command(
        self,
        id: int,
        arg0: int = 0x00,
        arg1: int = 0x00,
        arg2: int = 0x00,
        arg3: int = 0x00,
        arg4: int = 0x00,
    ):
        data = bytearray([0x7E, 0x00, id, arg0, arg1, arg2, arg3, arg4, 0xEF])

        print("sending message %s" % list(data))
        await self.peripheral.write_gatt_char(self._characteristic(), data)

async def main():
    address = "BE:FF:F0:50:74:63"  # Replace with the actual device address
    device = await BleLedDevice.new(address)
    await device.power_on()

    transition_time = 1  # Время перехода между цветами, в секундах

    await device.set_brightness(10)
    while True:
        for hue in range(0, 360):
            hue_normalized = hue / 20.0
            r, g, b = colorsys.hsv_to_rgb(hue_normalized, 1, 1)

            await device.set_color(int(r*255), int(g*255), int(b*255))
            print(f"R: {int(r * 255)}, G: {int(g * 255)}, B: {int(b * 255)}")
            await asyncio.sleep(transition_time)

if __name__ == "__main__":
    asyncio.run(main())

Logs

Traceback:
Traceback (most recent call last):
  File "C:\pythonProject\pythonProject1\2.py", line 121, in <module>
    asyncio.run(main())
  File "C:\Program Files\Python311\Lib\asyncio\runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "C:\Program Files\Python311\Lib\asyncio\runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Program Files\Python311\Lib\asyncio\base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "C:\pythonProject\pythonProject1\2.py", line 114, in main
    await device.set_color(int(r*255), int(g*255), int(b*255))
  File "C:\pythonProject\pythonProject1\2.py", line 61, in set_color
    await self.generic_command(0x05, 0x03, red, green, blue)
  File "C:\pythonProject\pythonProject1\2.py", line 86, in generic_command
    await self.peripheral.write_gatt_char(self._characteristic(), data)
  File "C:\Program Files\Python311\Lib\site-packages\bleak\__init__.py", line 776, in write_gatt_char
    await self._backend.write_gatt_char(characteristic, data, response)
  File "C:\Program Files\Python311\Lib\site-packages\bleak\backends\winrt\client.py", line 887, in write_gatt_char
    raise BleakError("Not connected")
bleak.exc.BleakError: Not connected

Process finished with exit code 1

logging:

DEBUG:asyncio:Using proactor: IocpProactor
DEBUG:bleak.backends.winrt.scanner:Received 28:2B:B9:41:06:91: .
DEBUG:bleak.backends.winrt.scanner:Received 28:2B:B9:41:06:91: SberBoom Mini 1848.
DEBUG:bleak.backends.winrt.scanner:Received 17:44:73:9A:68:A2: .
DEBUG:bleak.backends.winrt.scanner:Received 28:2B:B9:41:06:91: .
DEBUG:bleak.backends.winrt.scanner:Received 28:2B:B9:41:06:91: SberBoom Mini 1848.
DEBUG:bleak.backends.winrt.scanner:Received BE:FF:F0:50:74:63: ELK-BLEDOM   .
DEBUG:bleak.backends.winrt.scanner:3 devices found. Watcher status: <BluetoothLEAdvertisementWatcherStatus.STOPPED: 3>.
DEBUG:bleak.backends.winrt.client:Connecting to BLE device @ BE:FF:F0:50:74:63
DEBUG:bleak.backends.winrt.client:getting services (service_cache_mode=None, cache_mode=None)...
DEBUG:bleak.backends.winrt.client:session_status_changed_event_handler: id: BluetoothLE#BluetoothLE04:7f:0e:43:b1:2c-be:ff:f0:50:74:63, error: <BluetoothError.SUCCESS: 0>, status: <GattSessionStatus.ACTIVE: 1>
DEBUG:bleak.backends.winrt.client:BE:FF:F0:50:74:63: services changed
DEBUG:bleak.backends.winrt.client:session_status_changed_event_handler: id: BluetoothLE#BluetoothLE04:7f:0e:43:b1:2c-be:ff:f0:50:74:63, error: <BluetoothError.SUCCESS: 0>, status: <GattSessionStatus.CLOSED: 0>
DEBUG:bleak.backends.winrt.client:closing requester
DEBUG:bleak.backends.winrt.client:closing session
dxdate commented 10 months ago

https://drive.google.com/file/d/1oy1qX4LAdwKY1Cy99h_JUNulIjL_4T3a/view?usp=sharing wireshark log

dxdate commented 10 months ago

@hbldh how fix this?

dlech commented 10 months ago

According to the logs, the disconnect happened because the device failed to respond.

image

So maybe the device is going to sleep after a while or something like that?