### Install Bleak
Source: https://github.com/hbldh/bleak/blob/develop/README.rst
Install the Bleak library using pip. Ensure you have Python installed.
```bash
pip install bleak
```
--------------------------------
### Install Stable Release of Bleak
Source: https://github.com/hbldh/bleak/blob/develop/docs/installation.md
Use this command to install the latest stable version of bleak. This is the recommended method for most users.
```console
$ pip install bleak
```
--------------------------------
### Install Bleak with Pythonista Support
Source: https://github.com/hbldh/bleak/blob/develop/docs/backends/pythonista.md
Use StaSh or Pythonista3_pip_Configration_Tool to install Bleak with Pythonista support.
```console
$ pip install bleak[pythonista]
```
--------------------------------
### Set up Python environment
Source: https://github.com/hbldh/bleak/blob/develop/CONTRIBUTING.rst
Install project dependencies using uv after navigating to the bleak directory.
```shell
cd bleak/
uv sync
```
--------------------------------
### Install Bleak from Develop Branch
Source: https://github.com/hbldh/bleak/blob/develop/docs/installation.md
Install bleak directly from the develop branch on GitHub to use the latest unreleased changes. This is useful for testing new features.
```console
$ pip install https://github.com/hbldh/bleak/archive/refs/heads/develop.zip
```
--------------------------------
### BleakScanner.start()
Source: https://github.com/hbldh/bleak/blob/develop/docs/api/scanner.md
Starts the BLE device scanning process. Raises BleakBluetoothNotAvailableError if Bluetooth is not available.
```APIDOC
## BleakScanner.start()
### Description
Start scanning for devices.
### Method
`async`
### Raises
[BleakBluetoothNotAvailableError](index.md#bleak.exc.BleakBluetoothNotAvailableError) – if Bluetooth is not currently available
```
--------------------------------
### Install Wireshark for Bluetooth Traffic Capture (Debian/Ubuntu)
Source: https://github.com/hbldh/bleak/blob/develop/docs/troubleshooting.md
Installs Wireshark on Debian/Ubuntu systems, which can be used to capture and analyze Bluetooth traffic.
```bash
sudo apt update && sudo apt install wireshark
```
--------------------------------
### Clone the bleak repository
Source: https://github.com/hbldh/bleak/blob/develop/CONTRIBUTING.rst
Clone your fork of the bleak repository locally to start development.
```shell
git clone https://github.com:your_name_here/bleak.git
```
--------------------------------
### Get Default Backend
Source: https://github.com/hbldh/bleak/blob/develop/docs/backends/index.md
Returns the preferred backend for the current platform/environment.
```APIDOC
## bleak.backends.get_default_backend() -> BleakBackend
Returns the preferred backend for the current platform/environment.
#### Versionadded
Added in version 2.0.
```
--------------------------------
### macOS Info.plist Bluetooth Permission
Source: https://github.com/hbldh/bleak/blob/develop/docs/backends/macos.md
Example of how to configure Bluetooth permissions in an application's Info.plist file on macOS.
```xml
NSBluetoothAlwaysUsageDescription
Some description why your app needs Bluetooth access
```
--------------------------------
### BleakScanner Context Manager
Source: https://github.com/hbldh/bleak/blob/develop/docs/api/scanner.md
Demonstrates using BleakScanner as an async context manager for starting and stopping scans.
```APIDOC
## Starting and stopping with `async with`
[`BleakScanner`](#bleak.BleakScanner) is an context manager so the recommended way to start and stop scanning is to use it in an `async with` statement:
```python
import asyncio
from bleak import BleakScanner
async def main():
stop_event = asyncio.Event()
# TODO: add something that calls stop_event.set()
def callback(device, advertising_data):
# TODO: do something with incoming data
pass
async with BleakScanner(callback) as scanner:
...
# Important! Wait for an event to trigger stop, otherwise scanner
# will stop immediately.
await stop_event.wait()
# scanner stops when block exits
...
asyncio.run(main())
```
```
--------------------------------
### Using BleakScanner as a Context Manager
Source: https://github.com/hbldh/bleak/blob/develop/docs/api/scanner.md
The recommended way to start and stop scanning is by using BleakScanner within an async with statement. Ensure an event is set to trigger the stop, otherwise the scanner will stop immediately upon exiting the block.
```python
import asyncio
from bleak import BleakScanner
async def main():
stop_event = asyncio.Event()
# TODO: add something that calls stop_event.set()
def callback(device, advertising_data):
# TODO: do something with incoming data
pass
async with BleakScanner(callback) as scanner:
...
# Important! Wait for an event to trigger stop, otherwise scanner
# will stop immediately.
await stop_event.wait()
# scanner stops when block exits
...
asyncio.run(main())
```
--------------------------------
### Manual Connection Management - BleakClient.connect() / disconnect()
Source: https://context7.com/hbldh/bleak/llms.txt
Manages the BLE client connection explicitly using `connect()` and `disconnect()` methods, outside of the context manager pattern. This allows for more granular control over the connection lifecycle. The example demonstrates connecting, performing operations, and then disconnecting.
```python
import asyncio
from bleak import BleakClient
async def main():
client = BleakClient("AA:BB:CC:DD:EE:FF", timeout=20.0)
await client.connect()
try:
print(f"Connected: {client.is_connected}")
# ... do work ...
finally:
await client.disconnect()
print(f"Connected after disconnect: {client.is_connected}")
asyncio.run(main())
```
--------------------------------
### Run tests
Source: https://github.com/hbldh/bleak/blob/develop/CONTRIBUTING.rst
Execute the test suite to verify your changes.
```shell
uv run pytest
```
--------------------------------
### Get Backend Identifier
Source: https://github.com/hbldh/bleak/blob/develop/docs/api/client.md
Retrieves the identifier of the backend in use.
```APIDOC
## backend_id
### Description
Gets the identifier of the backend in use.
### Property
Returns: BleakBackend | str - The identifier of the backend.
```
--------------------------------
### Run Linting and Tests
Source: https://github.com/hbldh/bleak/blob/develop/docs/contributing.md
Ensure your changes pass linting and all tests before committing. Use uv for running these commands.
```shell
uv run isort .
uv run black .
uv run flake8
uv run pytest
```
--------------------------------
### Configure BlueZ Adapter and Filters
Source: https://context7.com/hbldh/bleak/llms.txt
Select a specific BlueZ adapter and set RSSI and duplicate data filters for active scanning. Requires the 'bluez' argument.
```python
import asyncio
from bleak import BleakScanner, BleakClient
from bleak.assigned_numbers import AdvertisementDataType
async def main():
# Linux: select specific adapter, set RSSI filter for active scan
linux_scanner = BleakScanner(
bluez={
"adapter": "hci1",
"filters": {"RSSI": -80, "DuplicateData": False},
}
)
# Linux: passive scanning with or-patterns (BlueZ advertisement monitor)
passive_scanner = BleakScanner(
scanning_mode="passive",
bluez={
"or_patterns": [
(0, AdvertisementDataType.FLAGS, b"\x06"),
]
},
)
# Windows: use public address type, skip OS service cache
win_client = BleakClient(
"AA:BB:CC:DD:EE:FF",
winrt={"address_type": "public", "use_cached_services": False},
)
# macOS: use Bluetooth address instead of UUID
mac_devices = await BleakScanner.discover(
cb={"use_bdaddr": True}
)
# macOS: custom notification discriminator to separate read vs notify
async with BleakClient("AA:BB:CC:DD:EE:FF") as client:
await client.start_notify(
"00002a37-0000-1000-8000-00805f9b34fb",
lambda char, data: print(data),
cb={"notification_discriminator": lambda data: len(data) == 2},
)
await asyncio.sleep(5.0)
# Linux: force StartNotify instead of AcquireNotify
async with BleakClient("AA:BB:CC:DD:EE:FF") as client:
await client.start_notify(
"00002a37-0000-1000-8000-00805f9b34fb",
lambda char, data: print(data),
bluez={"use_start_notify": True},
)
await asyncio.sleep(5.0)
asyncio.run(main())
```
--------------------------------
### Get Device Address
Source: https://github.com/hbldh/bleak/blob/develop/docs/api/client.md
Retrieves the Bluetooth address of the device.
```APIDOC
## address
### Description
Gets the Bluetooth address of this device (UUID on macOS).
### Property
Returns: str - The Bluetooth address.
```
--------------------------------
### Get Device Name
Source: https://github.com/hbldh/bleak/blob/develop/docs/api/client.md
Retrieves a human-readable name for the peripheral device.
```APIDOC
## name
### Description
Gets a human-readable name for the peripheral device.
### Property
Returns: str - The device name.
```
--------------------------------
### Run Integration Tests with Virtual Bluetooth Controllers (VHCI)
Source: https://github.com/hbldh/bleak/blob/develop/tests/integration/README.rst
Execute integration tests using virtual Bluetooth controllers managed by Bleak and Bumble via the VHCI interface on Linux. This method avoids the need for physical hardware.
```bash
uv run pytest --bleak-bluez-vhci
```
--------------------------------
### BleakScanner.backend_id
Source: https://github.com/hbldh/bleak/blob/develop/docs/api/scanner.md
Property to get the identifier of the backend currently in use by the scanner.
```APIDOC
## BleakScanner.backend_id
### Description
Gets the identifier of the backend in use.
### NOTE
The value is one of the `BleakBackend` enum values in case of built-in backends, or a string identifying a custom backend.
### Returns
A `BleakBackend` enum value or a string identifying a custom backend.
### Versionadded
Added in version 2.0.
```
--------------------------------
### Discover and Connect to Multiple Devices
Source: https://github.com/hbldh/bleak/blob/develop/docs/troubleshooting.md
Scan for devices and then connect to each discovered device to access its services. This approach can help when direct connection attempts to multiple devices fail.
```python
import asyncio
from typing import Sequence
from bleak import BleakClient, BleakScanner
from bleak.backends.device import BLEDevice
async def find_all_devices_services():
devices: Sequence[BLEDevice] = await BleakScanner.discover(timeout=5.0)
for d in devices:
async with BleakClient(d) as client:
print(client.services)
asyncio.run(find_all_devices_services())
```
--------------------------------
### name
Source: https://github.com/hbldh/bleak/blob/develop/docs/backends/linux.md
Property to get the name of the connected device, referencing `bleak.BleakClient.name()`.
```APIDOC
## property name *: str*
See [`bleak.BleakClient.name()`](../api/client.md#bleak.BleakClient.name).
```
--------------------------------
### BleakClient.connect() / disconnect()
Source: https://context7.com/hbldh/bleak/llms.txt
Allows explicit management of the client connection lifecycle outside of the asynchronous context manager pattern. Use `await client.connect()` to establish a connection and `await client.disconnect()` to terminate it.
```APIDOC
## BleakClient.connect() / disconnect() — Manual Connection Management
`await client.connect()` and `await client.disconnect()` allow explicit connection lifecycle management when not using the context manager pattern. `connect()` also accepts kwargs for backwards compatibility.
### Parameters
- **connect()**: Accepts kwargs for backwards compatibility.
- **disconnect()**: No parameters.
### Request Example
```python
import asyncio
from bleak import BleakClient
async def main():
client = BleakClient("AA:BB:CC:DD:EE:FF", timeout=20.0)
await client.connect()
try:
print(f"Connected: {client.is_connected}")
# ... do work ...
finally:
await client.disconnect()
print(f"Connected after disconnect: {client.is_connected}")
asyncio.run(main())
```
```
--------------------------------
### BleakScanner.discovered_devices
Source: https://github.com/hbldh/bleak/blob/develop/docs/api/scanner.md
Property to get a list of discovered BLE devices after scanning has stopped.
```APIDOC
## BleakScanner.discovered_devices
### Description
Gets list of the devices that the scanner has discovered during the scanning.
### NOTE
If you also need advertisement data, use [`discovered_devices_and_advertisement_data`](#bleak.BleakScanner.discovered_devices_and_advertisement_data) instead.
### Returns
A list of `BLEDevice` objects.
```
--------------------------------
### Get MTU Size
Source: https://github.com/hbldh/bleak/blob/develop/docs/api/client.md
Retrieves the negotiated MTU size in bytes for the active connection.
```APIDOC
## mtu_size
### Description
Gets the negotiated MTU size in bytes for the active connection.
### Property
Returns: int - The negotiated MTU size.
```
--------------------------------
### Accessing GATT Services and Characteristics
Source: https://context7.com/hbldh/bleak/llms.txt
Demonstrates how to find a device, connect, and then look up a specific GATT service by its UUID. It iterates through the service's characteristics and prints their details.
```python
import asyncio
from bleak import BleakClient, BleakScanner
async def main():
device = await BleakScanner.find_device_by_address("AA:BB:CC:DD:EE:FF")
async with BleakClient(device) as client:
# Lookup service by UUID
svc = client.services.get_service("0000180f-0000-1000-8000-00805f9b34fb")
if svc:
print(f"Service: {svc.uuid}") # full 128-bit UUID
print(f" Handle: {svc.handle}") # integer handle
print(f" Description: {svc.description}") # "Battery Service"
for char in svc.characteristics:
print(f" Char: {char}") # "00002a19-...: Battery Level"
asyncio.run(main())
```
--------------------------------
### BleakScanner Class Initialization
Source: https://github.com/hbldh/bleak/blob/develop/docs/api/scanner.md
Initialize the BleakScanner with optional parameters for callbacks, service UUID filtering, scanning mode, and backend-specific arguments.
```APIDOC
## BleakScanner
### Description
Interface for Bleak Bluetooth LE Scanners. The scanner will listen for BLE advertisements, optionally filtering on advertised services or other conditions, and collect a list of `BLEDevice` objects. These can subsequently be used to connect to the corresponding BLE server.
A [`BleakScanner`](#bleak.BleakScanner) can be used as an asynchronous context manager in which case it automatically starts and stops scanning.
### Parameters:
* **detection_callback** – Optional function that will be called each time a device is discovered or advertising data has changed.
* **service_uuids** – Optional list of service UUIDs to filter on. Only advertisements containing this advertising data will be received. Required on macOS >= 12.0, < 12.3 (unless you create an app with `py2app`).
* **scanning_mode** – Set to `"passive"` to avoid the `"active"` scanning mode. Passive scanning is not supported on macOS! Will raise `BleakError` if set to `"passive"` on macOS.
* **bluez** – Dictionary of arguments specific to the BlueZ backend.
* **cb** – Dictionary of arguments specific to the CoreBluetooth backend.
* **backend** – Used to override the automatically selected backend (i.e. for a custom backend).
* **kwargs** – Additional args for backwards compatibility.
```
--------------------------------
### Using BleakGATTServiceCollection for Lookups
Source: https://context7.com/hbldh/bleak/llms.txt
Illustrates the capabilities of BleakGATTServiceCollection, including accessing all services and characteristics, looking up items by UUID or handle, and using subscript access for general item retrieval.
```python
import asyncio
from bleak import BleakClient, BleakScanner
async def main():
device = await BleakScanner.find_device_by_address("AA:BB:CC:DD:EE:FF")
async with BleakClient(device) as client:
sc = client.services
# All services (dict: handle -> BleakGATTService)
print(f"Services: {list(sc.services.keys())}")
# All characteristics (dict: handle -> BleakGATTCharacteristic)
print(f"Total characteristics: {len(sc.characteristics)}")
# Lookup characteristic by UUID
char = sc.get_characteristic("00002a19-0000-1000-8000-00805f9b34fb")
if char:
print(f"Battery Level char at handle {char.handle}")
# Lookup descriptor by handle
desc = sc.get_descriptor(20)
if desc:
print(f"Descriptor at 20: {desc.description}")
# Subscript access (returns first match among services, chars, descriptors)
item = sc["0000180f-0000-1000-8000-00805f9b34fb"]
print(f"Item: {item}")
asyncio.run(main())
```
--------------------------------
### BleakClientWinRT
Source: https://github.com/hbldh/bleak/blob/develop/docs/backends/windows.md
Native Windows Bleak Client for connecting to BLE peripherals using WinRT.
```APIDOC
## *class* bleak.backends.winrt.client.BleakClientWinRT(address_or_ble_device: [BLEDevice](../api/index.md#bleak.backends.device.BLEDevice) | str, services: set[str] | None = None, , winrt: [WinRTClientArgs](../api/args.md#bleak.args.winrt.WinRTClientArgs), **kwargs: Any)
### Description
Native Windows Bleak Client. Implemented with WinRT.
### Parameters
* **address_or_ble_device** (*str* *or* [*BLEDevice*](../api/index.md#bleak.backends.device.BLEDevice)) – The Bluetooth address of the BLE peripheral to connect to or the `BLEDevice` object representing it.
* **services** – Optional set of service UUIDs that will be used.
* **winrt** (*dict*) – A dictionary of Windows-specific configuration values.
### *async* connect(pair: bool, **kwargs: Any) -> None
Connect to the specified GATT server.
### Keyword Arguments
**timeout** (*float*) – Timeout for required `BleakScanner.find_device_by_address` call.
```
--------------------------------
### BleakScanner.discovered_devices_and_advertisement_data
Source: https://github.com/hbldh/bleak/blob/develop/docs/api/scanner.md
Property to get a dictionary mapping device addresses to discovered devices and their advertisement data.
```APIDOC
## BleakScanner.discovered_devices_and_advertisement_data
### Description
Gets a map of device address to tuples of devices and the most recently received advertisement data for that device.
### NOTE
The address keys are useful to compare the discovered devices to a set of known devices. If you don’t need to do that, consider using `discovered_devices_and_advertisement_data.values()` to just get the values instead.
### Returns
A dictionary where keys are device addresses (string) and values are tuples of (`BLEDevice`, `AdvertisementData`).
### Versionadded
Added in version 0.19.
```
--------------------------------
### start_notify
Source: https://github.com/hbldh/bleak/blob/develop/docs/backends/linux.md
Activate notifications or indications on a characteristic. Supports additional BlueZ parameters for Linux.
```APIDOC
## async start_notify(characteristic: [BleakGATTCharacteristic](../api/index.md#bleak.backends.characteristic.BleakGATTCharacteristic), callback: Callable[[bytearray], None], **kwargs: Any) -> None
Activate notifications/indications on a characteristic.
* **Parameters:**
* **characteristic** ([*BleakGATTCharacteristic*](../api/index.md#bleak.backends.characteristic.BleakGATTCharacteristic)) – The characteristic to activate notification/indication on.
* **callback** (*NotifyCallback*) – The callback to call when a notification/indication is received.
* **Keyword Arguments:**
**bluez** (*dict*) – dictionary of additional parameters, see [Enabling notification/indication with start_notify](#linux-start-notify) for more details.
```
--------------------------------
### BleakScanner.advertisement_data
Source: https://github.com/hbldh/bleak/blob/develop/docs/api/scanner.md
Asynchronously yields discovered devices and their advertisement data. Ensure scanning is started before calling this method.
```APIDOC
## BleakScanner.advertisement_data
### Description
Yields devices and associated advertising data packets as they are discovered.
### NOTE
Ensure that scanning is started before calling this method.
### Returns
An async iterator that yields tuples (`BLEDevice`, `AdvertisementData`).
### Versionadded
Added in version 0.21.
```
--------------------------------
### Get GATT Services
Source: https://github.com/hbldh/bleak/blob/develop/docs/api/client.md
Retrieves the collection of GATT services available on the device. This property is only valid while the device is connected.
```APIDOC
## services
### Description
Gets the collection of GATT services available on the device.
### Property
Returns: BleakGATTServiceCollection - The collection of GATT services.
### Raises
BleakError – if service discovery has not been performed yet during this connection.
```
--------------------------------
### Initialize and Use BleakClient as Async Context Manager
Source: https://github.com/hbldh/bleak/blob/develop/docs/api/client.md
Use BleakClient as an asynchronous context manager for automatic connection and disconnection. This is the recommended approach for managing BLE client connections.
```python
import asyncio
from bleak import BleakClient
async def main():
async with BleakClient("XX:XX:XX:XX:XX:XX") as client:
# Read a characteristic, etc.
...
# Device will disconnect when block exits.
...
# Using asyncio.run() is important to ensure that device disconnects on
# KeyboardInterrupt or other unhandled exception.
asyncio.run(main())
```
--------------------------------
### List Serial Ports on Linux
Source: https://github.com/hbldh/bleak/blob/develop/tests/integration/README.rst
Command to find available serial ports on Linux, typically starting with /dev/ttyACM.
```bash
ls /dev/ttyACM*
```
--------------------------------
### get_platform_scanner_backend_type
Source: https://github.com/hbldh/bleak/blob/develop/docs/backends/index.md
Gets the platform-specific `BaseBleakScanner` type. This function is used internally by Bleak to instantiate the correct scanner backend for the operating system.
```APIDOC
## bleak.backends.scanner.get_platform_scanner_backend_type() -> tuple[type[BaseBleakScanner], BleakBackend]
Gets the platform-specific [`BaseBleakScanner`](#bleak.backends.scanner.BaseBleakScanner) type.
```
--------------------------------
### macOS Device Identifier Example
Source: https://github.com/hbldh/bleak/blob/develop/docs/backends/macos.md
This code snippet shows how to handle device identification on macOS, using UUIDs for Bluetooth devices instead of MAC addresses.
```python
mac_addr = (
"24:71:89:cc:09:05"
if platform.system() != "Darwin"
else "243E23AE-4A99-406C-B317-18F1BD7B4CBE"
)
```
--------------------------------
### Iterating Through GATT Characteristics and Descriptors
Source: https://context7.com/hbldh/bleak/llms.txt
Shows how to iterate through all services and their characteristics on a connected device. It prints characteristic details and checks for specific properties like 'write-without-response', also demonstrating how to find a descriptor by UUID.
```python
import asyncio
from bleak import BleakClient, BleakScanner
async def main():
device = await BleakScanner.find_device_by_address("AA:BB:CC:DD:EE:FF")
async with BleakClient(device) as client:
for service in client.services:
for char in service.characteristics:
print(f"UUID: {char.uuid}")
print(f"Handle: {char.handle}")
print(f"Description: {char.description}")
print(f"Properties: {char.properties}")
# e.g. ['read', 'notify'] or ['write-without-response']
if "write-without-response" in char.properties:
print(f"Max WoR size: {char.max_write_without_response_size} bytes")
# Get descriptor by UUID
cccd = char.get_descriptor("00002902-0000-1000-8000-00805f9b34fb")
if cccd:
print(f" CCCD handle: {cccd.handle}")
asyncio.run(main())
```
--------------------------------
### Run code formatters and linters
Source: https://github.com/hbldh/bleak/blob/develop/CONTRIBUTING.rst
Ensure your code adheres to project standards by running isort, black, and flake8.
```shell
uv run isort .
uv run black .
uv run flake8
```
--------------------------------
### Handling Notifications with Discriminator
Source: https://github.com/hbldh/bleak/blob/develop/docs/backends/pythonista.md
This example demonstrates how to use a `notification_discriminator` callback to differentiate between notification data and read data when using `start_notify` on Pythonista, as the _cb module does not distinguish between them.
```python
event = asyncio.Event()
async def notification_handler(char, data):
event.set()
def notification_check_handler(data):
# We can identify notifications on this characteristic because they
# only contain 1 byte of data. Read responses will have more than
# 1 byte.
return len(data) == 1
await client.start_notify(
char,
notification_handler,
cb={"notification_discriminator": notification_check_handler},
)
while True:
await event.wait()
# We received a notification - prepare to receive another
event.clear()
# Then read the characteristic to get the full value
data = await client.read_gatt_char(char)
# Do stuff with data
```
--------------------------------
### Connect and Disconnect using Async Context Manager
Source: https://github.com/hbldh/bleak/blob/develop/docs/api/client.md
The recommended way to connect and disconnect a BleakClient is by using it as an asynchronous context manager. This ensures the client is properly connected before entering the block and automatically disconnected upon exiting.
```APIDOC
## Connecting and disconnecting
[`bleak.BleakClient`](#bleak.BleakClient) is a an async context manager, so the recommended
way of connecting is to use it as such:
```default
import asyncio
from bleak import BleakClient
async def main():
async with BleakClient("XX:XX:XX:XX:XX:XX") as client:
# Read a characteristic, etc.
...
# Device will disconnect when block exits.
...
# Using asyncio.run() is important to ensure that device disconnects on
# KeyboardInterrupt or other unhandled exception.
asyncio.run(main())
```
```
--------------------------------
### Start GATT Characteristic Notifications
Source: https://github.com/hbldh/bleak/blob/develop/docs/api/client.md
Activate notifications or indications on a GATT characteristic. A callback function is required to handle incoming data. The callback receives the characteristic and a bytearray of data.
```python
def callback(sender: BleakGATTCharacteristic, data: bytearray):
print(f"{sender}: {data}")
client.start_notify(char_uuid, callback)
```
--------------------------------
### Avoid Multiple asyncio.run() Calls (Python)
Source: https://github.com/hbldh/bleak/blob/develop/docs/troubleshooting.md
Ensure asyncio.run() is called only once at the program's start. Wrapping individual async functions in separate asyncio.run() calls leads to errors.
```python
async def scan():
return await BleakScanner.find_device_by_name("My Device")
async def connect(device):
async with BleakClient(device) as client:
data = await client.read_gatt_char(MY_CHAR_UUID)
print("received:" data)
# Do not wrap each function call in asyncio.run() like this!
device = asyncio.run(scan())
if not device:
print("Device not found")
else:
asyncio.run(connect(device))
```
```python
async def scan():
return await BleakScanner.find_device_by_name("My Device")
async def connect(device):
async with BleakClient(device) as client:
data = await client.read_gatt_char(MY_CHAR_UUID)
print("received:" data)
# Do have one async main function that does everything.
async def main():
device = await scan()
if not device:
print("Device not found")
return
await connect(device)
asyncio.run(main())
```
```python
async def scan_and_connect():
device = await BleakScanner.find_device_by_name("My Device")
if not device:
print("Device not found")
return
async with BleakClient(device) as client:
data = await client.read_gatt_char(MY_CHAR_UUID)
print("received:" data)
while True:
# Don't call asyncio.run() multiple times like this!
asyncio.run(scan_and_connect())
# Never use blocking sleep in an asyncio programs!
time.sleep(5)
```
```python
async def scan_and_connect():
device = await BleakScanner.find_device_by_name("My Device")
if not device:
print("Device not found")
return
async with BleakClient(device) as client:
data = await client.read_gatt_char(MY_CHAR_UUID)
print("received:" data)
# Do have one async main function that does everything.
async def main():
while True:
await scan_and_connect()
# Do use asyncio.sleep() in an asyncio program.
await asyncio.sleep(5)
asyncio.run(main())
```
--------------------------------
### unpair
Source: https://github.com/hbldh/bleak/blob/develop/docs/backends/linux.md
Unpair with the peripheral.
```APIDOC
## async unpair() -> None
Unpair with the peripheral.
```
--------------------------------
### Enable Bleak Logging (Windows CMD)
Source: https://github.com/hbldh/bleak/blob/develop/docs/troubleshooting.md
Set the BLEAK_LOGGING environment variable to 1 in the Windows Command Prompt to enable detailed logging for troubleshooting.
```batch
set BLEAK_LOGGING=1
```
--------------------------------
### Stream Advertisements - BleakScanner.advertisement_data
Source: https://context7.com/hbldh/bleak/llms.txt
Provides an asynchronous iterator to receive BLE advertisement data in real-time. This is useful for processing advertisement packets as they arrive without using callbacks. The example shows how to collect the first 5 advertisement packets.
```python
import asyncio
from bleak import BleakScanner
async def main():
async with BleakScanner() as scanner:
# Collect the first 5 advertisement packets
count = 0
async for device, adv in scanner.advertisement_data():
print(f"{device.address}: RSSI={adv.rssi}, name={adv.local_name}")
count += 1
if count >= 5:
break
asyncio.run(main())
```
--------------------------------
### Clean Recipe Build Command
Source: https://github.com/hbldh/bleak/blob/develop/examples/kivy/README.md
Command to clean the recipe build for Bleak when using local source changes. This is necessary because changes to `bleak/**` are not automatically detected during rebuilds.
```bash
buildozer android p4a -- clean_recipe_build --local-recipes $(pwd)/../../bleak/backends/p4android/recipes bleak
```
--------------------------------
### BleakClient.start_notify
Source: https://github.com/hbldh/bleak/blob/develop/docs/api/client.md
Activate notifications/indications on a characteristic. Callbacks are invoked when data is received.
```APIDOC
## BleakClient.start_notify
### Description
Activate notifications/indications on a characteristic. Callbacks are invoked when data is received.
### Method
`async`
### Parameters
#### Path Parameters
* **char_specifier** (BleakGATTCharacteristic | int | str | UUID) - Required - The characteristic to activate notifications/indications on, specified by either integer handle, UUID or directly by the BleakGATTCharacteristic object representing it.
* **callback** (Callable[[BleakGATTCharacteristic, bytearray], None | Awaitable[None]]) - Required - The function to be called on notification. Can be a regular function or an async function.
* **bluez** (BlueZNotifyArgs) - Optional - BlueZ backend-specific arguments.
* **cb** (CBStartNotifyArgs) - Optional - CoreBluetooth backend-specific arguments.
### Request Example
```python
def callback(sender: BleakGATTCharacteristic, data: bytearray):
print(f"{sender}: {data}")
client.start_notify(char_uuid, callback)
```
### Response
#### Success Response (None)
This method does not return a value upon success.
#### Errors
* **BleakCharacteristicNotFoundError**: If a characteristic with the handle or UUID specified by `char_specifier` could not be found.
* **backend-specific exceptions**: If the start notification operation failed.
```
--------------------------------
### BleakScanner.discover()
Source: https://github.com/hbldh/bleak/blob/develop/docs/api/scanner.md
Scan for a specified duration and return discovered devices, optionally including their advertising data.
```APIDOC
## BleakScanner.discover
### Description
Scan continuously for `timeout` seconds and return discovered devices.
### Parameters:
* **timeout** – Time, in seconds, to scan for.
* **return_adv** – If `True`, the return value will include advertising data.
* **kwargs** – Additional arguments will be passed to the [`BleakScanner`](#bleak.BleakScanner) constructor.
### Returns:
The value of [`discovered_devices_and_advertisement_data`](#bleak.BleakScanner.discovered_devices_and_advertisement_data) if `return_adv` is `True`, otherwise the value of [`discovered_devices`](#bleak.BleakScanner.discovered_devices).
### Example:
```python
# Example for return_adv=False
await BleakScanner.discover(timeout=5.0)
# Example for return_adv=True
await BleakScanner.discover(timeout=5.0, return_adv=True)
```
```
--------------------------------
### BLE Error Handling
Source: https://context7.com/hbldh/bleak/llms.txt
Demonstrates how to catch and handle various Bleak-specific exceptions, providing insights into Bluetooth availability, device discovery, GATT protocol errors, and general BLE issues.
```APIDOC
## Exception Hierarchy — Handling BLE Errors
Bleak defines a hierarchy of exceptions in `bleak.exc`. `BleakError` is the base. `BleakBluetoothNotAvailableError` is raised when Bluetooth hardware is off or permission is denied (with `.reason` property). `BleakCharacteristicNotFoundError` when a UUID/handle lookup fails. `BleakDeviceNotFoundError` when the OS has never seen the requested device. `BleakGATTProtocolError` (v3.0+) wraps GATT ATT protocol errors with a `.code` property of type `BleakGATTProtocolErrorCode`.
```python
import asyncio
from bleak import BleakClient, BleakScanner
from bleak.exc import (
BleakError,
BleakBluetoothNotAvailableError,
BleakBluetoothNotAvailableReason,
BleakCharacteristicNotFoundError,
BleakDeviceNotFoundError,
BleakGATTProtocolError,
BleakGATTProtocolErrorCode,
)
async def main():
try:
device = await BleakScanner.find_device_by_address("AA:BB:CC:DD:EE:FF")
async with BleakClient(device) as client:
await client.read_gatt_char("00002a19-0000-1000-8000-00805f9b34fb")
except BleakBluetoothNotAvailableError as e:
if e.reason == BleakBluetoothNotAvailableReason.POWERED_OFF:
print("Please turn on Bluetooth")
elif e.reason == BleakBluetoothNotAvailableReason.DENIED_BY_USER:
print("Bluetooth permission denied")
else:
print(f"Bluetooth unavailable: {e.reason}")
except BleakDeviceNotFoundError as e:
print(f"Device {e.identifier} not found by OS")
except BleakCharacteristicNotFoundError as e:
print(f"Characteristic not found: {e.char_specifier}")
except BleakGATTProtocolError as e:
if e.code == BleakGATTProtocolErrorCode.READ_NOT_PERMITTED:
print("Read not permitted on this characteristic")
else:
print(f"GATT protocol error: {e.code} ({e.code.name})")
except BleakError as e:
print(f"Generic BLE error: {e}")
asyncio.run(main())
```
```