sockets - Python Bluetooth unable to connect - Stack Overflow

admin2025-04-20  0

I am facing a problem using pybluez2 for searching via bluetooth my device. So I used bleak and find it automatically, but I am not able to connect. Why?

I try to find my device and connect using only bleak, but it doesn't.

Main class that manages the connectio, open, searching the device,...

Everything is working, but not the connection with the device. s you can see in the print, the program tries many times to connect unsuccessfully.

# Import necessary libraries for Bluetooth scanning and communication
from bleak import BleakScanner, BleakClient
from bleak.exc import BleakDeviceNotFoundError, BleakError

# Import custom classes for Bluetooth communication and exceptions
import ...bluetooth_communication.bluetooth_interface as bti
import ...bluetooth_communication.bluetooth_exceptions as bte


class BluetoothWrapper(bti.BluetoothInterface):
    # Constants for device connection attempts and device identification prefix
    BT_TENTATIVE: int = 3
    START_ID: str = "BM..."

    def __init__(self, mac_address: str = "", notify_characteristic: str = "", notify_callback=None):
        # Initialize instance variables
        self._mac_address: str = mac_address  # MAC address of the target device
        self._id: str = ""                   # Device identification string
        self._devices_list: list = []        # List to hold discovered devices
        self._is_open: bool = False           # Connection status
        self._client: None | BleakClient = None  # Client for communicating with the device
        self.loop = asyncio.new_event_loop()  # Set up the asyncio event loop
        asyncio.set_event_loop(self.loop)      # Set the current event loop
        self.connection_enabled: bool = True   # Flag to enable/disable connection attempts
        self.connected: bool = False            # Indicates if the device is connected
        self.notify_characteristic: str = notify_characteristic  # Characteristic for notifications
        self.notify_callback = notify_callback  # Callback function for notifications

    def _find_ff_id(self):
        # Method to search for the target device in the discovered devices
        if not self._devices_list:  # Check if devices have been discovered
            raise bte.BTNoDevices()  # Raise exception if no devices found
        for ble_dev in self._devices_list:  # Iterate over discovered devices
            mac_adr: str = ble_dev.address  # Get MAC address of the device
            id: str = ble_dev.name if ble_dev.name else ""  # Get device name (if available)
            # Check if the MAC address matches or if the device name contains the START_ID prefix
            if (mac_adr == self._mac_address) or (self.START_ID in id):
                print(f"[Device found] Adr = {mac_adr}, id = {id}")  # Print found device info
                self._mac_address, self._id = mac_adr, id  # Store MAC address and device ID
                return
        print(f"Devices found, but not Faast Flex:\\n{self._devices_list}")  # Log devices found
        if self._mac_address:  # If a MAC address was specified but not found
            raise bte.BTDeviceNoFound(self._mac_address)  # Raise device not found exception
        raise bte.BTNoDevices()  # Raise exception if no devices were discovered

    def discover_devices(self) -> list:
        # Method to discover Bluetooth devices
        async def run():
            return await BleakScanner.discover()  # Use Bleak to scan for devices
        return self.loop.run_until_complete(run())  # Run the scanning coroutine until complete

    def on_disconnect(self, client):
        # Callback for when the device disconnects
        print("Disconnected from device")  # Log disconnection
        self.connected = False  # Update connection status

    async def connect_to_device(self):
        # Method to connect to the specified Bluetooth device
        while True:
            if self.connection_enabled:
                try:
                    self._client = BleakClient(self._mac_address)  # Create a BleakClient with the device MAC address
                    await self._client.connect()  # Attempt to connect to the device
                    self.connected = await self._client.is_connected()  # Check if connected
                    if self.connected:
                        print("Connected to Device")  # Log successful connection
                        self._client.set_disconnected_callback(self.on_disconnect)  # Set the disconnect callback
                        # Start notifications from the specified characteristic
                        await self._client.start_notify(
                            self.notify_characteristic, self.notify_callback,
                        )
                        while True:  # Loop to keep the connection open
                            if not self.connected:  # Break if not connected
                                break
                            await asyncio.sleep(1.0)  # Sleep to avoid busy waiting
                    else:
                        print("Failed to connect to Device")  # Log failure to connect
                except Exception as e:
                    print(f"Connection error: {e}")  # Log any exceptions during connection
            else:
                await asyncio.sleep(1.0)  # Sleep if connection is not enabled

    def _set_ff_address(self):
        # Method to determine the MAC address of the target device
        for tent in range(1, self.BT_TENTATIVE + 1):  # Loop for a number of attempts
            print(f"Tentative {tent}")  # Log the current attempt number
            self._devices_list = self.discover_devices()  # Discover devices
            try:
                self._find_ff_id()  # Attempt to find the target device
                if self._mac_address:  # If the MAC address was found
                    break
            except (bte.BTNoDevices, bte.BTDeviceNoFound) as err:
                print(str(err))  # Log any errors encountered

    def open(self) -> None:
        # Method to open a connection to the target device
        if self._is_open and self._client:  # If connection is already open
            raise bte.BTAlreadyOpen()  # Raise an exception

        self._set_ff_address()  # Attempt to find and set the target device's MAC address

        # Attempt to connect to the device
        for tent in range(1, self.BT_TENTATIVE + 1):
            print(f"Tentative {tent}")  # Log the current attempt
            try:
                self.loop.run_until_complete(self.connect_to_device())  # Attempt to connect
                self._is_open = True  # Update connection status
            except (bte.BTNoDevices, BleakDeviceNotFoundError, BleakError) as btnd:
                self._is_open = False  # Update connection status to closed
                print(str(btnd))  # Log any connection errors
            finally:
                print(f"Bluetooth is {'correctly' if self._is_open else 'not'} connected!")  # Log connection status

Errors:

Tentative 1
Devices found, but not Faast Flex:
[BLEDevice(2C:C8:BA:6A:06:6B, None), BLEDevice(66:E0:97:D6:D5:B0, None), BLEDevice(01:10:65:E7:C4:87, None), BLEDevice(21:D6:03:A9:B6:7D, None), BLEDevice(DF:62:A9:65:79:A6, None), BLEDevice(2D:BF:86:53:38:FD, None), BLEDevice(1A:CC:C5:58:C0:B7, None), BLEDevice(11:3A:EB:25:8D:B6, None), BLEDevice(37:61:4A:C4:9B:0A, None), BLEDevice(37:5F:E0:20:C7:EE, None), BLEDevice(B8:A2:5D:A3:9F:91, None), BLEDevice(03:22:DB:F7:60:52, None), BLEDevice(1C:43:FB:4D:14:30, None), BLEDevice(24:4B:03:F9:9E:C1, None), BLEDevice(7C:FD:EA:99:4A:F2, None), BLEDevice(46:EA:98:12:1B:0C, None), BLEDevice(61:B1:77:A0:AB:BC, None), BLEDevice(74:45:AF:00:0F:7C, None)]
No devices found!
Tentative 2
Devices found, but not Faast Flex:
[BLEDevice(21:D6:03:A9:B6:7D, None), BLEDevice(1A:CC:C5:58:C0:B7, None), BLEDevice(2C:C8:BA:6A:06:6B, None), BLEDevice(01:10:65:E7:C4:87, None), BLEDevice(D1:68:42:77:F8:23, None), BLEDevice(1C:43:FB:4D:14:30, None), BLEDevice(0C:2F:D1:02:9A:1F, None), BLEDevice(26:3D:2E:F7:E4:22, None), BLEDevice(24:4B:03:F9:9E:C1, None), BLEDevice(11:3A:EB:25:8D:B6, None), BLEDevice(E8:52:3D:00:E6:ED, None), BLEDevice(03:22:DB:F7:60:52, None), BLEDevice(2D:BF:86:53:38:FD, None), BLEDevice(37:5F:E0:20:C7:EE, None), BLEDevice(7C:FD:EA:99:4A:F2, None), BLEDevice(1E:25:40:FA:8D:95, None), BLEDevice(66:E0:97:D6:D5:B0, None), BLEDevice(B8:A2:5D:A3:9F:91, None), BLEDevice(61:B1:77:A0:AB:BC, None)]
No devices found!
Tentative 3
[Device found] Adr = 00:21:7E:BF:D2:DF, id = BMxxxx
Tentative 1
C:\...\lib\common\communication_protocols\bluetooth_communication\bluetooth_wrapper.py:58: FutureWarning: is_connected has been changed to a property. Calling it as an async method will be removed in a future version
  self.connected = await self._client.is_connected()
C:\...\lib\common\communication_protocols\bluetooth_communication\bluetooth_wrapper.py:61: FutureWarning: This method will be removed future version, pass the callback to the BleakClient constructor instead.
  self._client.set_disconnected_callback(self.on_disconnect)
Connected to Device
Connection error: badly formed hexadecimal UUID string
Connection error: Device with address 00:21:7E:BF:D2:DF was not found.
Connection error: Device with address 00:21:7E:BF:D2:DF was not found.
Connection error: Device with address 00:21:7E:BF:D2:DF was not found.
Connection error: Device with address 00:21:7E:BF:D2:DF was not found.
Connection error: Device with address 00:21:7E:BF:D2:DF was not found.

Below I tried to connect to my smartphone (a motorola). Using this simple program below, I am not able to find my phone that starts with "moto":

import asyncio
from bleak import BleakScanner, BleakClient


BATTERY_SERVICE_UUID = "0000180F-0000-1000-8000-00805f9b34fb"
BATTERY_LEVEL_UUID = "00002A19-0000-1000-8000-00805f9b34fb"


async def battery_handler(address):
    async with BleakClient(address) as client:
        battery_level = await client.read_gatt_char(BATTERY_LEVEL_UUID)
        print(f"Bactery charge: {battery_level[0]}%")


async def main():
    selected_device = None
    while selected_device is None:
        print("\nSanning the Bluetooth devices...")
        devices = await BleakScanner.discover()
        for device in devices:
            print(f"Device found: {device.name} ({device.address})")
            if device.name and ("moto" in device.name):
                selected_device = device

    # Scegli un dispositivo a cui connettersi (puoi anche usare un input dell'utente qui)
    # selected_device = devices[0]  # Ad esempio, prendi il primo dispositivo trovato
    print(f"Linking with {selected_device.name} ({selected_device.address})...")
    await battery_handler(selected_device.address)

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

Is it a problem of my computer bt module? Because I used another smartphone to check if mine was available and it worked.

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1745084502a284057.html

最新回复(0)