Examples
September 4, 2025 ยท View on GitHub
Here are some practical examples of using bleak_bumble with different transport layers.
Zephyr RTOS
Zephyr RTOS supports a Virtual HCI over a TCP client. To connect your application with Zephyr you need to define a TCP server transport for bumble:
from bleak_bumble import BumbleTransportCfg, TransportScheme
from bleak import BleakScanner, BleakClient
from bleak_bumble.scanner import BleakScannerBumble
from bleak_bumble.client import BleakClientBumble
# Create TCP server transport configuration
cfg = BumbleTransportCfg(TransportScheme.TCP_SERVER, "127.0.0.1:1000")
# Create scanner with the transport
scanner = BleakScanner(backend=BleakScannerBumble, cfg=cfg)
async for device, advertisement_data in scanner.advertisement_data():
client = BleakClient(device, backend=BleakClientBumble, cfg=cfg)
await client.connect()
# ... interact with the device
await client.disconnect()
Note: The Zephyr application must be compiled for the
native/posix/64board. The Bumble controller does not support all HCI LE Commands. For this reason the following configs must be disabled in the Zephyr firmware:CONFIG_BT_EXT_ADV,CONFIG_BT_AUTO_PHY_UPDATE,CONFIG_BT_HCI_ACL_FLOW_CONTROL.
Android Emulator
The Android Emulator supports virtualization of the Bluetooth Controller over gRPC with the android netsim tool:
from bleak_bumble import BumbleTransportCfg, TransportScheme
from bleak import BleakScanner, BleakClient
from bleak_bumble.scanner import BleakScannerBumble
from bleak_bumble.client import BleakClientBumble
# Create Android netsim transport configuration
cfg = BumbleTransportCfg(TransportScheme.ANDROID_NETSIM)
# Create scanner with the transport
scanner = BleakScanner(backend=BleakScannerBumble, cfg=cfg)
async for device, advertisement_data in scanner.advertisement_data():
client = BleakClient(device, backend=BleakClientBumble, cfg=cfg)
await client.connect()
# ... interact with the device
await client.disconnect()
Serial/USB HCI Controller
To use a serial or USB HCI controller that may not be natively supported:
from bleak_bumble import BumbleTransportCfg, TransportScheme
from bleak import BleakScanner, BleakClient
from bleak_bumble.scanner import BleakScannerBumble
from bleak_bumble.client import BleakClientBumble
# Create serial transport configuration
cfg = BumbleTransportCfg(TransportScheme.SERIAL, "/dev/ttyUSB0")
# Enable host mode for physical controllers
scanner = BleakScanner(backend=BleakScannerBumble, cfg=cfg, host_mode=True)
async for device, advertisement_data in scanner.advertisement_data():
client = BleakClient(device, backend=BleakClientBumble, cfg=cfg, host_mode=True)
await client.connect()
# ... interact with the device
await client.disconnect()
Virtual HCI Controller (VHCI)
For Linux systems with VHCI support:
from bleak_bumble import BumbleTransportCfg, TransportScheme
from bleak import BleakScanner, BleakClient
from bleak_bumble.scanner import BleakScannerBumble
from bleak_bumble.client import BleakClientBumble
# Create VHCI transport configuration
cfg = BumbleTransportCfg(TransportScheme.VHCI)
scanner = BleakScanner(backend=BleakScannerBumble, cfg=cfg)
async for device, advertisement_data in scanner.advertisement_data():
client = BleakClient(device, backend=BleakClientBumble, cfg=cfg)
await client.connect()
# ... interact with the device
await client.disconnect()
Simple Device Discovery
A minimal example for device discovery:
import asyncio
from bleak_bumble import BumbleTransportCfg, TransportScheme
from bleak_bumble.scanner import BleakScannerBumble
async def scan_for_devices():
cfg = BumbleTransportCfg(TransportScheme.TCP_SERVER, "127.0.0.1:1000")
async def detection_callback(device, advertisement_data):
print(f"Found device: {device.name} ({device.address})")
scanner = BleakScannerBumble(
detection_callback=detection_callback,
cfg=cfg
)
await scanner.start()
await asyncio.sleep(10.0) # Scan for 10 seconds
await scanner.stop()
# Run the scan
asyncio.run(scan_for_devices())
Environment Variable Configuration
Using environment variables for configuration:
import os
import asyncio
from bleak import BleakScanner, BleakClient
from bleak_bumble.scanner import BleakScannerBumble
from bleak_bumble.client import BleakClientBumble
# Set environment variables
os.environ["BLEAK_BUMBLE"] = "tcp-server:127.0.0.1:1000"
os.environ["BLEAK_BUMBLE_HOST"] = "1"
async def scan_and_connect():
# Use environment variable configuration
scanner = BleakScanner(backend=BleakScannerBumble)
async for device, advertisement_data in scanner.advertisement_data():
print(f"Connecting to {device.name} ({device.address})")
client = BleakClient(device, backend=BleakClientBumble)
await client.connect()
# Read device information
services = await client.get_services()
print(f"Found {len(services)} services")
await client.disconnect()
break # Connect to first device found
asyncio.run(scan_and_connect())