aioble — Async BLE
aioble is a high-level asyncio-friendly wrapper around the
bluetooth module. It provides clean coroutines for scanning,
connecting, advertising, GATT services, and L2CAP channels.
All remote operations (connect, disconnect, client read/write, server indicate, l2cap recv/send, pair) are awaitable and support timeouts.
Supported roles:
Broadcaster (advertiser) — generate advertising and scan-response payloads for common fields, automatically split payload across advertising and scan response, advertise indefinitely or for a fixed duration.
Peripheral — wait for connection from a central, wait for MTU exchange.
Observer (scanner) — passive and active scanning, combine advertising and scan-response payloads for the same device, parse common fields from advertising payloads.
Central — connect to a peripheral, initiate MTU exchange.
GATT Client — discover services / characteristics / descriptors (optionally by UUID); read / write / write-with-response on characteristics and descriptors; subscribe to notifications and indications (via the CCCD); wait for notifications and indications.
GATT Server — register services / characteristics / descriptors; wait for writes on characteristics and descriptors; intercept read requests; send notifications and indications (and wait on response).
L2CAP — accept and connect L2CAP connection-oriented channels, manage channel flow control.
Security — JSON-backed key/secret management, initiate pairing, query encryption / authentication state.
The package is delivered as a meta-package built from several optional sub-packages, any combination of which may be installed:
aioble-core— core BLE functionality required by every aioble user.aioble-central— Central (and Observer) role: scanning and connecting.aioble-client— GATT client (typically used by central-role devices, but can also be used on peripherals).aioble-peripheral— Peripheral (and Broadcaster) role: advertising.aioble-server— GATT server (typically used by peripheral-role devices, but can also be used on centrals).aioble-l2cap— L2CAP connection-oriented-channel support.aioble-security— pairing and bonding support.
Installing the meta-package aioble pulls all of them in.
Requires MicroPython v1.17 or higher.
Module-level functions
- aioble.config(*args, **kwargs) Any
Forwards to
bluetooth.BLE.config(), ensuring the BLE radio is active first.- args
Optional single parameter name to query.
- kwargs
Keyword arguments to set configuration values.
- aioble.stop() None
Deactivate the underlying BLE radio and run any registered sub-module shutdown handlers. After calling this, scanners, advertisers, connections and L2CAP channels are all torn down.
- aioble.scan(duration_ms: int, interval_us: int | None = None, window_us: int | None = None, active: bool = False) scan
Returns a
scanasync context-manager / async-iterator that yieldsScanResultinstances for each unique device discovered (or for each new piece of advertising data from a known device).- duration_ms
How long to scan, in milliseconds. Pass
0to scan indefinitely until the context manager exits.- interval_us
Scan interval in microseconds. Defaults to 1,280,000.
- window_us
Scan window in microseconds (must be less than or equal to interval_us). Defaults to 11,250.
- active
If
True, perform an active scan (request scan response data). Defaults toFalse.
- aioble.advertise(interval_us: int, adv_data: bytes | None = None, resp_data: bytes | None = None, connectable: bool = True, limited_disc: bool = False, br_edr: bool = False, name: str | None = None, services: list | None = None, appearance: int = 0, manufacturer: tuple | None = None, timeout_ms: int | None = None) DeviceConnection
Async coroutine that begins advertising and waits for an incoming central connection. Returns a
DeviceConnectionrepresenting the connected central, or raisesasyncio.TimeoutErroron timeout.- interval_us
Advertising interval, in microseconds.
- adv_data
Raw advertising payload. If unset, adv_data is built from the remaining keyword arguments.
- resp_data
Raw scan response payload. Auto-populated to overflow from adv_data if needed.
- connectable
If
True, this is a connectable advertisement.- limited_disc
Use the limited-discoverable flag instead of general.
- br_edr
Set the BR/EDR-supported flag.
- name
Optional complete local name to embed.
- services
Iterable of
bluetooth.UUIDto advertise.- appearance
16-bit appearance value (see Bluetooth assigned numbers).
- manufacturer
Tuple of
(company_id, data_bytes)to advertise as manufacturer specific data.- timeout_ms
Stop advertising after this many milliseconds without a connection.
Nonemeans advertise until connected.
Module-level constants
- aioble.ADDR_PUBLIC
Public BLE device address type (
0).
- aioble.ADDR_RANDOM
Random BLE device address type (
1).
Exceptions
- exception aioble.GattError
Raised when a remote GATT operation (read / write / indicate) completes with a non-zero status. The status code is available on the
_statusattribute.
- exception aioble.DeviceDisconnectedError
Raised inside an async operation (e.g. read, write, notified) when the underlying connection drops while waiting.
- exception aioble.L2CAPDisconnectedError
Raised when an L2CAP channel send/recv/flush operation is attempted on (or interrupted by) a disconnected channel.
- exception aioble.L2CAPConnectionError
Raised by
DeviceConnection.l2cap_connectwhen establishing the channel fails. The Bluetooth status code is the first argument.
Classes
- class aioble.Device(addr_type: int, addr: bytes | str)
Represents a remote BLE device by address. Two
Deviceinstances compare equal if both addr_type and addr match. Used as the handle for initiating connections.- addr_type
Either
ADDR_PUBLICorADDR_RANDOM.- addr
Six-byte address as
bytes, or a colon-separated hex string (e.g."aa:bb:cc:dd:ee:ff").
- addr_type
The address type the device was constructed with.
- addr
The raw six-byte device address.
- connect(timeout_ms: int = 10000, scan_duration_ms: int | None = None, min_conn_interval_us: int | None = None, max_conn_interval_us: int | None = None) Awaitable[DeviceConnection]
Async. Initiate a GAP connection to this device and return the resulting
DeviceConnection. Cancels any in-progress scan.- timeout_ms
How long to wait for the connection to complete.
- scan_duration_ms
Initial scan duration before connecting (controller specific).
- min_conn_interval_us / max_conn_interval_us
Optional connection interval bounds, in microseconds.
- class aioble.DeviceConnection
An active GAP connection to a
Device. Returned byDevice.connect()oradvertise. Supports use as anasync withcontext manager that auto-disconnects on exit.Do not construct directly.
- encrypted
Trueonce the link is encrypted (e.g. after pairing).
- authenticated
Trueif the link was authenticated (MITM-protected pair).
- bonded
Trueif pairing produced bonding keys.
- key_size
Negotiated encryption key size in bytes, or
Falseif not encrypted.
- mtu
Negotiated ATT MTU after
exchange_mtu, orNoneuntil set.
- disconnect(timeout_ms: int = 2000) Awaitable[None]
Async. Disconnect and wait for the disconnection IRQ.
- timeout_ms
Maximum time to wait for the disconnection.
- disconnected(timeout_ms: int | None = None, disconnect: bool = False) Awaitable[None]
Async. Wait for the connection to be terminated by either side. If disconnect is
Trueit actively disconnects first.- timeout_ms
Maximum time to wait.
Nonemeans wait forever.- disconnect
If
True, initiate disconnection.
- timeout(timeout_ms: int | None) DeviceTimeout
Return a context manager that cancels its body if either the timeout elapses (raising
asyncio.TimeoutError) or the device disconnects (raisingDeviceDisconnectedError).- timeout_ms
Timeout in milliseconds, or
Nonefor no timeout.
- exchange_mtu(mtu: int | None = None, timeout_ms: int = 1000) Awaitable[int]
Async. Initiate an ATT MTU exchange and return the negotiated MTU.
- mtu
Optional preferred MTU to set on the underlying BLE interface before the exchange.
- timeout_ms
Timeout for the exchange.
- service(uuid: bluetooth.UUID, timeout_ms: int = 2000) Awaitable[ClientService | None]
Async. Discover a single remote service matching uuid, or
Noneif not found.
- services(uuid: bluetooth.UUID | None = None, timeout_ms: int = 2000) ClientDiscover
Return an async iterator of remote
ClientServiceobjects. Use withasync forand run the loop to completion.- uuid
Optional UUID filter.
Nonereturns every service.- timeout_ms
Per-discovery timeout.
- pair(bond: bool = True, le_secure: bool = True, mitm: bool = False, io: int = 3, timeout_ms: int = 20000) Awaitable[None]
Async. Initiate pairing on this connection. Updates the
encrypted/authenticated/bonded/key_sizeattributes when complete.- bond
Persist pairing keys.
- le_secure
Use LE Secure Connections.
- mitm
Require man-in-the-middle protection.
- io
IO capability constant (e.g.
3for no input/output).- timeout_ms
Pairing timeout.
- l2cap_accept(psm: int, mtu: int, timeout_ms: int | None = None) Awaitable[L2CAPChannel]
Async. Listen on the given PSM and return an
L2CAPChannelonce the remote opens it.- psm
Protocol/Service Multiplexer to listen on.
- mtu
Maximum receive size, in bytes.
- timeout_ms
Maximum time to wait for the remote to connect.
- l2cap_connect(psm: int, mtu: int, timeout_ms: int = 1000) Awaitable[L2CAPChannel]
Async. Open an L2CAP channel to the remote on the given PSM.
- psm
Protocol/Service Multiplexer to connect to.
- mtu
Maximum receive size, in bytes.
- timeout_ms
Connection timeout.
- class aioble.ScanResult
A single device discovered during
scan. The same instance is re-yielded as new advertising data arrives.Do not construct directly.
- rssi
Last reported RSSI, in dBm.
- adv_data
Raw advertising payload (
bytesorNone).
- resp_data
Raw scan response payload (
bytesorNone), if active scanning is enabled.
- connectable
Trueif the most recent advertisement was connectable.
- name() str | None
Decode the complete (or shortened) advertised local name from the payload, or
Noneif not present.
- services() Iterator[bluetooth.UUID]
Generator yielding each
bluetooth.UUIDadvertised in the 16/32/128-bit service-list fields.
- class aioble.Service(uuid: bluetooth.UUID)
A local GATT service. Build a service with one or more
Characteristicinstances, then pass it toregister_services.- uuid
The service UUID.
- uuid
The service UUID.
- characteristics
List of
Characteristicobjects bound to this service.
- class aioble.Characteristic(service: Service, uuid: bluetooth.UUID, read: bool = False, write: bool = False, write_no_response: bool = False, notify: bool = False, indicate: bool = False, initial: bytes | None = None, capture: bool = False)
A local GATT characteristic. Constructing one automatically appends it to service.
- service
The owning
Service.- uuid
The characteristic UUID.
- read, write, write_no_response, notify, indicate
Booleans selecting the supported GATT operations.
- initial
Optional initial value (
bytes).- capture
If
True, written values are queued (up to 10 deep) so that rapid back-to-back writes are not lost. Eachwrittencall then returns a(connection, data)tuple.
- uuid
The characteristic UUID.
- flags
Bitmask of the GATT property flags built from the constructor.
- descriptors
List of
Descriptorobjects bound to this characteristic.
- write(data: bytes, send_update: bool = False) None
Update the value in the local GATT database.
- data
New value bytes.
- send_update
If
True, also notify/indicate every subscribed connection.
- notify(connection: DeviceConnection, data: bytes | None = None) None
Send a GATT Notify to connection.
- connection
The target client connection.
- data
Payload to send. If
None, the current local value is sent.
- indicate(connection: DeviceConnection, data: bytes | None = None, timeout_ms: int = 1000) Awaitable[None]
Async. Send a GATT Indicate to connection and wait for the client confirmation. Raises
GattErroron a non-zero status.- connection
The target client connection.
- data
Payload to indicate, or
Noneto send the local value.- timeout_ms
Maximum time to wait for confirmation.
- written(timeout_ms: int | None = None) Awaitable[DeviceConnection | tuple[DeviceConnection, bytes]]
Async. Wait for a remote write. Returns the writing
DeviceConnection, or(connection, data)if the characteristic was created withcapture=True.- timeout_ms
Maximum time to wait.
Nonewaits forever.
- on_read(connection: DeviceConnection) int
Override hook invoked synchronously when a remote read is received. Return
0to allow the read or a non-zero ATT error code to reject it. Default implementation returns0.
- class aioble.BufferedCharacteristic(service: Service, uuid: bluetooth.UUID, max_len: int = 20, append: bool = False, **kwargs)
A
Characteristicwhose backing GATT buffer can be configured. Useful for receiving values larger than the default attribute size, or for queuing back-to-back writes.- max_len
Buffer size, in bytes.
- append
If
True, sequential writes append into the buffer instead of overwriting.
Other arguments forward to
Characteristic.
- class aioble.Descriptor(characteristic: Characteristic, uuid: bluetooth.UUID, read: bool = False, write: bool = False, initial: bytes | None = None)
A local GATT descriptor. Constructing one automatically appends it to characteristic. Inherits
read,writeandwrittenfromCharacteristic.- characteristic
The owning
Characteristic.- uuid
The descriptor UUID.
- read, write
Booleans selecting the supported GATT operations.
- initial
Optional initial value (
bytes).
- class aioble.ClientService
A remote GATT service discovered on a peer. Returned by
DeviceConnection.service()or iterated fromDeviceConnection.services().Do not construct directly.
- connection
The owning
DeviceConnection.
- uuid
The remote service UUID.
- characteristic(uuid: bluetooth.UUID, timeout_ms: int = 2000) Awaitable[ClientCharacteristic | None]
Async. Discover a single characteristic by UUID, or
Noneif not found.
- characteristics(uuid: bluetooth.UUID | None = None, timeout_ms: int = 2000) ClientDiscover
Return an async iterator of
ClientCharacteristicobjects. Use withasync forand run the loop to completion.- uuid
Optional UUID filter.
- timeout_ms
Per-discovery timeout.
- class aioble.ClientCharacteristic
A remote GATT characteristic discovered on a peer. Returned by
ClientService.characteristic()or iterated fromClientService.characteristics().Do not construct directly.
- service
The owning
ClientService.
- uuid
The characteristic UUID.
- properties
Bitmask of supported GATT operations as reported by the peer.
- read(timeout_ms: int = 1000) Awaitable[bytes]
Async. Issue a GATT Read and return the value. Raises
GattErroron a non-zero status.- timeout_ms
Read timeout.
- write(data: bytes, response: bool | None = None, timeout_ms: int = 1000) Awaitable[None]
Async. Issue a GATT Write.
- data
Value to write.
- response
Trueto require a write-response (and raiseGattErroron failure).Falsefor write-without- response.None(default) auto-selects based on what the peer advertises.- timeout_ms
Write timeout (only relevant if response is
True).
- notified(timeout_ms: int | None = None) Awaitable[bytes]
Async. Wait for the next notification on this characteristic and return its payload. Returns immediately if a notification is already queued.
- timeout_ms
Maximum time to wait.
Nonewaits forever.
- indicated(timeout_ms: int | None = None) Awaitable[bytes]
Async. Wait for the next indication on this characteristic and return its payload.
- timeout_ms
Maximum time to wait.
- subscribe(notify: bool = True, indicate: bool = False) Awaitable[None]
Async. Write the Client Characteristic Configuration Descriptor (CCCD) to subscribe (or unsubscribe) for notifications and/or indications.
- notify
Enable notifications.
- indicate
Enable indications.
- descriptor(uuid: bluetooth.UUID, timeout_ms: int = 2000) Awaitable[ClientDescriptor | None]
Async. Discover a single descriptor by UUID, or
Noneif not found.
- descriptors(timeout_ms: int = 2000) ClientDiscover
Return an async iterator of
ClientDescriptorobjects. Use withasync forand run the loop to completion.
- class aioble.ClientDescriptor
A remote GATT descriptor discovered on a peer. Inherits
readandwritefromClientCharacteristic.Do not construct directly.
- characteristic
The owning
ClientCharacteristic.
- uuid
The descriptor UUID.
- class aioble.L2CAPChannel
An active L2CAP connection-oriented channel. Returned by
DeviceConnection.l2cap_accept()orDeviceConnection.l2cap_connect(). Supports use as anasync withcontext manager that auto-disconnects on exit.Do not construct directly.
- our_mtu
Maximum size, in bytes, that the peer may send to us in a single SDU.
- peer_mtu
Maximum size, in bytes, that we may send to the peer in a single SDU.
- available() bool
Synchronously return
Trueif buffered receive data is ready (i.e.recvintowill not block).
- recvinto(buf: bytearray, timeout_ms: int | None = None) Awaitable[int]
Async. Receive into buf, returning the number of bytes read. Awaits new data if the channel is empty.
- buf
Pre-allocated buffer to fill.
- timeout_ms
Maximum time to wait.
Nonewaits forever.
- send(buf: bytes, timeout_ms: int | None = None, chunk_size: int | None = None) Awaitable[None]
Async. Send buf on the channel, fragmenting larger payloads into MTU-sized chunks. Awaits flow-control credits as needed.
- buf
Bytes-like object to send.
- timeout_ms
Maximum time to wait per chunk.
- chunk_size
Optional override for the per-call chunk size. Capped to
min(our_mtu * 2, peer_mtu).
- flush(timeout_ms: int | None = None) Awaitable[None]
Async. Wait until any stalled
sendhas been drained by the controller.- timeout_ms
Maximum time to wait.