ubluepy — Bluetooth LE peripheral and central

The ubluepy module is the legacy Bluetooth LE API shipped with the MicroPython nRF port. It is loosely modelled on the Linux bluepy Python library and sits directly on top of the Nordic SoftDevice — there is no portable back-end, so the module is only available on Nordic targets (the Arduino Nano 33 BLE Sense in OpenMV’s lineup). The newer bluetooth / aioble APIs are not enabled in this build, so ubluepy is the only way to drive the on-die radio.

The available feature set depends on the SoftDevice flashed by the firmware:

  • s140 (Nano 33 BLE Sense) — both peripheral and central (scanner) roles. This is what the OpenMV firmware ships.

  • s132 — both peripheral and central.

  • s110 — peripheral only; scanner / connect methods are compiled out.

Peripheral example

Advertise as a Bluetooth LE peripheral with a single environmental sensing service and notify a temperature characteristic on every write to its Client Characteristic Configuration Descriptor (CCCD):

from ubluepy import Service, Characteristic, UUID, Peripheral, constants
from machine import LED

notif_enabled = False

def event_handler(event_id, handle, data):
    global notif_enabled
    if event_id == constants.EVT_GAP_CONNECTED:
        LED("LED_GREEN").on()
    elif event_id == constants.EVT_GAP_DISCONNECTED:
        LED("LED_GREEN").off()
        periph.advertise(device_name="Nano 33", services=[svc])
    elif event_id == constants.EVT_GATTS_WRITE:
        notif_enabled = bool(data[0])

svc = Service(UUID("181A"))            # Environmental Sensing
char = Characteristic(UUID("2A6E"),
                      props=Characteristic.PROP_NOTIFY | Characteristic.PROP_READ,
                      attrs=Characteristic.ATTR_CCCD)
svc.addCharacteristic(char)

periph = Peripheral()
periph.addService(svc)
periph.setConnectionHandler(event_handler)
periph.advertise(device_name="Nano 33", services=[svc])

Central example

Scan for nearby advertising devices for 100 ms and decode each ScanEntry’s advertisement data:

from ubluepy import Scanner, constants

s = Scanner()
for entry in s.scan(100):
    print(entry.addr(), entry.rssi(), "dBm")
    for ad_type, name, value in entry.getScanData():
        print(" ", ad_type, name, bytes(value))

Module contents

Classes

class ubluepy.UUID(value)

Construct a 16- or 128-bit Bluetooth UUID.

value

One of:

  • int — a 16-bit numeric UUID (UUID(0x180A)).

  • 6-character "0xXXXX" string — a 16-bit UUID, e.g. UUID("0x181A").

  • 36-character "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" string — a full 128-bit UUID. The vendor-specific portion is registered with the SoftDevice on construction.

  • Another UUID instance — performs a copy.

Any other length raises ValueError("Invalid UUID string length").

binVal() int

Return the low 16 bits of the UUID as an int. For 128-bit UUIDs only the 16-bit field embedded inside the vendor-specific UUID is returned (the full 128-bit value is accessible only via the SoftDevice’s vendor-specific index).

class ubluepy.Service(uuid: UUID, type: int = Service.PRIMARY)

Define a GATT service that will be registered with the SoftDevice when added to a Peripheral.

uuid

A UUID instance. Passing a non-UUID object raises ValueError.

type

Either Service.PRIMARY (default) or Service.SECONDARY. Other values raise ValueError.

uuid() UUID

Return the service’s UUID instance.

addCharacteristic(characteristic: Characteristic) None

Register a Characteristic with the service. The characteristic’s GATT handle is assigned during this call.

getCharacteristic(uuid: UUID) Characteristic | None

Look up a previously added Characteristic by UUID. Returns the characteristic instance, or None if no match is found.

getCharacteristics() list

Return the list of every characteristic added to the service.

PRIMARY: int

Service-type constant for primary services (1).

SECONDARY: int

Service-type constant for secondary services (2).

class ubluepy.Characteristic(uuid: UUID, *, props: int = PROP_READ | PROP_WRITE, attrs: int = 0)

Define a GATT characteristic. Add it to a Service with Service.addCharacteristic() before the parent Peripheral starts advertising.

uuid

A UUID instance.

props (keyword-only)

Bitmask of one or more Characteristic.PROP_* values describing what operations the characteristic supports.

attrs (keyword-only)

Bitmask of additional GATT attributes. Use Characteristic.ATTR_CCCD to attach a Client Characteristic Configuration Descriptor — required to make PROP_NOTIFY / PROP_INDICATE characteristics work.

uuid() UUID

Return the characteristic’s UUID instance.

properties() int

Return the props bitmask set at construction time.

read() bytearray

Central role only. Read the characteristic’s value from the connected peer. Returns a bytearray with the latest value. On a peripheral this is a no-op and returns None.

write(data, *, with_response: bool = False) None

Write to the characteristic.

  • On a peripheral, if PROP_NOTIFY is set in the characteristic’s properties the value is sent as a GATT notification to the connected central; otherwise the local attribute value is updated.

  • On a central, the value is written to the remote peer. Set with_response=True to issue a write request and wait for the peer’s acknowledgement instead of a write command.

data is any buffer-protocol object (bytes, bytearray, memoryview).

PROP_BROADCAST: int

Characteristic can broadcast its value (0x01).

PROP_READ: int

Characteristic supports reads (0x02).

PROP_WRITE_WO_RESP: int

Characteristic supports writes without response (0x04).

PROP_WRITE: int

Characteristic supports writes with response (0x08).

PROP_NOTIFY: int

Characteristic can push notifications to a subscribed central (0x10).

PROP_INDICATE: int

Characteristic can push indications (acknowledged notifications) to a subscribed central (0x20).

PROP_AUTH_SIGNED_WR: int

Characteristic supports authenticated signed writes (0x40).

ATTR_CCCD: int

Add a Client Characteristic Configuration Descriptor to the characteristic (0x01). Required for clients to be able to subscribe to notifications/indications.

class ubluepy.Descriptor(uuid: UUID)

Stub class for representing GATT descriptors. The current implementation only stores the UUID and exposes no methods — it is provided for forward compatibility with future revisions of the module.

class ubluepy.Peripheral

The local Bluetooth LE device. The same class is used for both peripheral and central roles; the role is selected by which methods you call (advertise() selects peripheral, connect() selects central).

addService(service: Service) None

Register a Service (and all its previously added characteristics) with the local GATT server.

getServices() list

Return the list of services currently registered with this Peripheral.

advertise(*, device_name: str | None = None, services: list | None = None, data: bytes | None = None, connectable: bool = True) None

Start advertising in peripheral role.

device_name

Complete local name advertised in the GAP payload.

services

List of Service instances to advertise. Each service’s UUID is included in the advertisement.

data

Optional raw advertisement payload (bytes / bytearray) appended to the auto-generated header. Use this for vendor-specific or beacon payloads such as Eddystone.

connectable

When True (default), advertise as a connectable device and register GAP / GATTS event handlers so the configured setConnectionHandler() callback fires on connect, disconnect, and CCCD writes. When False, advertise as a beacon — no handlers are attached and the device cannot be connected to.

advertise_stop() None

Stop any in-progress advertisement.

setConnectionHandler(func) None

Register a callback invoked on GAP and GATTS events. The callback is called as func(event_id, conn_handle, data) where event_id is one of the constants.EVT_GAP_CONNECTED, constants.EVT_GAP_DISCONNECTED, or constants.EVT_GATTS_WRITE values, conn_handle is the SoftDevice connection handle (or attribute handle for GATTS writes), and data is the raw event payload as a bytearray (or None for connect / disconnect).

setNotificationHandler(func) None

Register a callback for notification events received in central role.

withDelegate(delegate: DefaultDelegate) None

Attach a DefaultDelegate instance to receive decoded GATT events.

disconnect() None

Drop the active connection (currently a no-op stub in this build).

connect(addr, *, addr_type: int = constants.ADDR_TYPE_PUBLIC) None

Central role only. Connect to the peer with the given address and synchronously discover its primary services and characteristics. Blocks until the connection is established and discovery completes; the discovered services are then available via getServices().

addr

Peer address as a 17-character "xx:xx:xx:xx:xx:xx" string (e.g. taken from ScanEntry.addr()).

addr_type (keyword-only)

Either constants.ADDR_TYPE_PUBLIC (default) or constants.ADDR_TYPE_RANDOM_STATIC.

class ubluepy.Scanner

GAP observer for discovering nearby advertising devices. Available only when the firmware is built against a SoftDevice with central support (s132 / s140).

scan(timeout: int) list

Run a passive scan for timeout milliseconds and return a list of ScanEntry instances — one per advertisement report received during the window.

class ubluepy.ScanEntry

A single advertisement report captured by Scanner.scan(). Instances are returned from the scanner — there is no public constructor.

addr() str

Return the peer address as a 17-character "xx:xx:xx:xx:xx:xx" string.

addr_type() int

Return the peer address type (constants.ADDR_TYPE_PUBLIC or constants.ADDR_TYPE_RANDOM_STATIC).

rssi() int

Return the signal-strength indicator in dBm.

getScanData() list

Decode the advertisement payload into a list of (ad_type, description, value) tuples. ad_type is the numeric AD type byte (see constants.ad_types), description is the matching constant’s name as a string (or None if the type is unknown), and value is the AD record body as a bytearray.

class ubluepy.DefaultDelegate

Base class for objects passed to Peripheral.withDelegate(). Subclass it and override handleConnection() / handleNotification() to react to GATT events.

handleConnection() None

Called on GAP connect / disconnect events. The default implementation is empty.

handleNotification() None

Called on incoming GATT notifications. The default implementation is empty.

Constants

The constants attribute of the module is a namespace containing GAP/GATT event identifiers, address-type values, and the nested ad_types namespace.

ubluepy.constants: type

Container exposing the constants below.

constants.EVT_GAP_CONNECTED: int

Peripheral connection handler event_id value for GAP connect (16).

constants.EVT_GAP_DISCONNECTED: int

Peripheral connection handler event_id value for GAP disconnect (17).

constants.EVT_GATTS_WRITE: int

Peripheral connection handler event_id value for a write to a local GATT attribute, including writes to a CCCD that enable/disable notifications (80).

constants.UUID_CCCD: int

Standard Bluetooth UUID for the Client Characteristic Configuration Descriptor (0x2902).

constants.ADDR_TYPE_PUBLIC: int

Public Bluetooth Device Address (0).

constants.ADDR_TYPE_RANDOM_STATIC: int

Static random Bluetooth Device Address (1).

constants.ad_types: type

Namespace of advertising-data AD-type constants from the Bluetooth Core Specification Supplement. Each name maps to the corresponding 1-byte AD type:

Name

Value

AD_TYPE_FLAGS

0x01

AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE

0x02

AD_TYPE_16BIT_SERVICE_UUID_COMPLETE

0x03

AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE

0x04

AD_TYPE_32BIT_SERVICE_UUID_COMPLETE

0x05

AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE

0x06

AD_TYPE_128BIT_SERVICE_UUID_COMPLETE

0x07

AD_TYPE_SHORT_LOCAL_NAME

0x08

AD_TYPE_COMPLETE_LOCAL_NAME

0x09

AD_TYPE_TX_POWER_LEVEL

0x0A

AD_TYPE_CLASS_OF_DEVICE

0x0D

AD_TYPE_SIMPLE_PAIRING_HASH_C

0x0E

AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R

0x0F

AD_TYPE_SECURITY_MANAGER_TK_VALUE

0x10

AD_TYPE_SECURITY_MANAGER_OOB_FLAGS

0x11

AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE

0x12

AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT

0x14

AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT

0x15

AD_TYPE_SERVICE_DATA

0x16

AD_TYPE_PUBLIC_TARGET_ADDRESS

0x17

AD_TYPE_RANDOM_TARGET_ADDRESS

0x18

AD_TYPE_APPEARANCE

0x19

AD_TYPE_ADVERTISING_INTERVAL

0x1A

AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS

0x1B

AD_TYPE_LE_ROLE

0x1C

AD_TYPE_SIMPLE_PAIRING_HASH_C256

0x1D

AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256

0x1E

AD_TYPE_SERVICE_DATA_32BIT_UUID

0x20

AD_TYPE_SERVICE_DATA_128BIT_UUID

0x21

AD_TYPE_URI

0x24

AD_TYPE_3D_INFORMATION_DATA

0x3D

AD_TYPE_MANUFACTURER_SPECIFIC_DATA

0xFF