Bleak: Bluetooth Low Energy Client

3.0.1 · active · verified Sat Apr 11

Bleak (Bluetooth Low Energy platform Agnostic Klient) is an asynchronous, cross-platform Python library that acts as a GATT client. It enables scanning for BLE devices, connecting to them, and communicating by reading/writing GATT characteristics and descriptors, and subscribing to notifications/indications. Bleak is actively maintained, with the current version being 3.0.1, and typically releases updates as needed for bug fixes and new features.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to scan for nearby Bluetooth Low Energy devices using `BleakScanner` and then connect to a specific device using `BleakClient` to read a GATT characteristic, such as the battery level. It highlights the asynchronous nature of Bleak operations, requiring `asyncio` to run. Remember to replace placeholder UUIDs and addresses with those relevant to your device.

import asyncio
from bleak import BleakScanner, BleakClient

# Replace with the actual address of your BLE device
# For macOS, this might be a UUID. For Linux/Windows, a MAC address.
# You can find the address by running the discovery part first.
DEVICE_ADDRESS = "XX:XX:XX:XX:XX:XX" # Example for a generic device
SERVICE_UUID = "0000180f-0000-1000-8000-00805f9b34fb" # Battery Service UUID
BATTERY_LEVEL_CHAR_UUID = "00002a19-0000-1000-8000-00805f9b34fb" # Battery Level Characteristic UUID

async def discover_devices():
    print("Scanning for 5 seconds...")
    devices = await BleakScanner.discover(timeout=5.0)
    for d in devices:
        print(f"Device: {d.name} ({d.address})")
    print("\nDiscovery complete.")
    return devices

async def connect_and_read(address: str):
    try:
        async with BleakClient(address) as client:
            if not client.is_connected:
                print(f"Failed to connect to {address}")
                return
            print(f"Connected to {client.address}")

            # Read a characteristic (e.g., Battery Level)
            try:
                battery_level = await client.read_gatt_char(BATTERY_LEVEL_CHAR_UUID)
                print(f"Battery Level: {int.from_bytes(battery_level, 'little')}%")
            except Exception as e:
                print(f"Could not read battery level characteristic: {e}")
            
            # List all services and characteristics (optional)
            print("\nServices and Characteristics:")
            for service in client.services:
                print(f"  Service: {service.uuid} ({service.description})")
                for char in service.characteristics:
                    print(f"    Characteristic: {char.uuid} ({char.description}) - Properties: {char.properties}")
                    for descriptor in char.descriptors:
                        print(f"      Descriptor: {descriptor.uuid}")

    except Exception as e:
        print(f"An error occurred: {e}")

async def main():
    # First, discover devices to find the address
    # devices = await discover_devices()
    # For direct connection, replace DEVICE_ADDRESS with your target's address
    
    await connect_and_read(DEVICE_ADDRESS)

if __name__ == "__main__":
    # Make sure not to name your script 'bleak.py' to avoid circular import errors.
    asyncio.run(main())

view raw JSON →