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.