ubluepy — периферійний пристрій та центральний вузол Bluetooth LE

Модуль ubluepy є застарілим API Bluetooth LE, що постачається з MicroPython nRF port. Він приблизно змодельований на основі Python-бібліотеки Linux bluepy та розташований безпосередньо поверх Nordic SoftDevice — немає портативного бекенду, тому модуль доступний лише на цільових платформах Nordic (Arduino Nano 33 BLE Sense у лінійці OpenMV). Новіші API bluetooth / aioble не ввімкнені у цій збірці, тому ubluepy — єдиний спосіб керувати вбудованим радіо.

Доступний набір функцій залежить від SoftDevice, прошитого мікропрограмою:

  • s140 (Nano 33 BLE Sense) — обидві ролі: периферійного пристрою та центрального вузла (сканера). Саме це постачає мікропрограма OpenMV.

  • s132 — обидві ролі: периферійного пристрою та центрального вузла.

  • s110 — лише периферійний пристрій; методи сканера / підключення відключені під час компіляції.

Приклад периферійного пристрою

Рекламувати пристрій як периферійний Bluetooth LE з одним сервісом моніторингу середовища та надсилати сповіщення про температурну характеристику при кожному записі до його Дескриптора конфігурації клієнтської характеристики (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])

Приклад центрального вузла

Сканувати навколишні рекламуючі пристрої протягом 100 мс та декодувати рекламні дані кожного ScanEntry

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))

Вміст модуля

Класи

class ubluepy.UUID(value)

Створити 16- або 128-бітний Bluetooth UUID.

value

Одне з:

  • int — 16-бітний числовий UUID (UUID(0x180A)).

  • Рядок "0xXXXX" з 6 символів — 16-бітний UUID, наприклад UUID("0x181A").

  • Рядок "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" з 36 символів — повний 128-бітний UUID. Специфічна для постачальника частина реєструється в SoftDevice під час створення.

  • Інший екземпляр UUID — виконує копіювання.

Будь-яка інша довжина призводить до ValueError("Invalid UUID string length").

binVal() int

Повертає молодші 16 біт UUID як int. Для 128-бітних UUID повертається лише 16-бітне поле, вбудоване всередині специфічного для постачальника UUID (повне 128-бітне значення доступне лише через специфічний для постачальника індекс SoftDevice).

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

Визначити GATT-сервіс, який буде зареєстрований в SoftDevice при додаванні до Peripheral.

uuid

Екземпляр UUID. Передача не-UUID об’єкта призводить до ValueError.

type

Або Service.PRIMARY (за замовчуванням), або Service.SECONDARY. Інші значення призводять до ValueError.

uuid() UUID

Повертає екземпляр UUID сервісу.

addCharacteristic(characteristic: Characteristic) None

Реєструє Characteristic в сервісі. Дескриптор GATT характеристики призначається під час цього виклику.

getCharacteristic(uuid: UUID) Characteristic | None

Шукає раніше додану Characteristic за UUID. Повертає екземпляр характеристики або None, якщо збіг не знайдено.

getCharacteristics() list

Повертає список усіх характеристик, доданих до сервісу.

PRIMARY: int

Константа типу сервісу для основних сервісів (1).

SECONDARY: int

Константа типу сервісу для вторинних сервісів (2).

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

Визначити GATT-характеристику. Додайте її до Service за допомогою Service.addCharacteristic() до того, як батьківський Peripheral почне рекламуватись.

uuid

Екземпляр UUID.

props (лише ключові слова)

Бітова маска одного або кількох значень Characteristic.PROP_*, що описують, які операції підтримує характеристика.

attrs (лише ключові слова)

Бітова маска додаткових атрибутів GATT. Використовуйте Characteristic.ATTR_CCCD для прикріплення Дескриптора конфігурації клієнтської характеристики — необхідно для роботи характеристик PROP_NOTIFY / PROP_INDICATE.

uuid() UUID

Повертає екземпляр UUID характеристики.

properties() int

Повертає бітову маску props, встановлену під час створення.

read() bytearray

Лише для центрального вузла. Читає значення характеристики від підключеного пристрою. Повертає bytearray з останнім значенням. На периферійному пристрої це операція без дії та повертає None.

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

Записати до характеристики.

  • На периферійному пристрої, якщо в властивостях характеристики встановлено PROP_NOTIFY, значення надсилається як GATT-сповіщення підключеному центральному вузлу; інакше оновлюється локальне значення атрибута.

  • На центральному вузлі значення записується до віддаленого пристрою. Встановіть with_response=True, щоб видати запит на запис та чекати підтвердження від пристрою, а не команду запису.

data — будь-який об’єкт буферного протоколу (bytes, bytearray, memoryview).

PROP_BROADCAST: int

Характеристика може транслювати своє значення (0x01).

PROP_READ: int

Характеристика підтримує читання (0x02).

PROP_WRITE_WO_RESP: int

Характеристика підтримує записи без відповіді (0x04).

PROP_WRITE: int

Характеристика підтримує записи з відповіддю (0x08).

PROP_NOTIFY: int

Характеристика може надсилати сповіщення підписаному центральному вузлу (0x10).

PROP_INDICATE: int

Характеристика може надсилати індикації (підтверджені сповіщення) підписаному центральному вузлу (0x20).

PROP_AUTH_SIGNED_WR: int

Характеристика підтримує автентифіковані підписані записи (0x40).

ATTR_CCCD: int

Додати Дескриптор конфігурації клієнтської характеристики до характеристики (0x01). Необхідно для того, щоб клієнти могли підписуватись на сповіщення/індикації.

class ubluepy.Descriptor(uuid: UUID)

Клас-заглушка для представлення GATT-дескрипторів. Поточна реалізація лише зберігає UUID та не надає жодних методів — він надається для перспективної сумісності з майбутніми версіями модуля.

class ubluepy.Peripheral

Локальний пристрій Bluetooth LE. Один і той самий клас використовується для обох ролей: периферійного пристрою та центрального вузла; роль обирається в залежності від того, які методи ви викликаєте (advertise() обирає периферійну роль, connect() — центральну).

addService(service: Service) None

Реєструє Service (та всі його раніше додані характеристики) на локальному GATT-сервері.

getServices() list

Повертає список сервісів, зараз зареєстрованих у цьому Peripheral.

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

Розпочати рекламу у ролі периферійного пристрою.

device_name

Повне локальне ім’я, що рекламується в GAP-корисному навантаженні.

services

Список екземплярів Service для реклами. UUID кожного сервісу включається до оголошення.

data

Необов’язкове необроблене рекламне корисне навантаження (bytes / bytearray), яке додається до автоматично створеного заголовка. Використовуйте це для специфічних для постачальника або маякових корисних навантажень, таких як Eddystone.

connectable

Якщо True (за замовчуванням), рекламувати як пристрій, до якого можна підключитись, та реєструвати обробники подій GAP / GATTS, щоб налаштований setConnectionHandler() зворотний виклик спрацьовував при підключенні, відключенні та записах CCCD. Якщо False, рекламувати як маяк — обробники не приєднуються та до пристрою не можна підключитись.

advertise_stop() None

Зупинити будь-яку рекламу, що виконується.

setConnectionHandler(func) None

Реєструє зворотний виклик, що спрацьовує на події GAP та GATTS. Зворотний виклик викликається як func(event_id, conn_handle, data), де event_id — одне зі значень constants.EVT_GAP_CONNECTED, constants.EVT_GAP_DISCONNECTED або constants.EVT_GATTS_WRITE, conn_handle — дескриптор підключення SoftDevice (або дескриптор атрибута для записів GATTS), а data — необроблений корисний вміст події як bytearray (або None для підключення / відключення).

setNotificationHandler(func) None

Реєструє зворотний виклик для подій сповіщень, отриманих у ролі центрального вузла.

withDelegate(delegate: DefaultDelegate) None

Приєднує екземпляр DefaultDelegate для отримання декодованих подій GATT.

disconnect() None

Розриває активне підключення (наразі заглушка без дії у цій збірці).

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

Лише для центрального вузла. Підключається до пристрою за вказаною адресою та синхронно виявляє його основні сервіси та характеристики. Блокує виконання до встановлення підключення та завершення виявлення; виявлені сервіси потім доступні через getServices().

addr

Адреса пристрою у вигляді рядка "xx:xx:xx:xx:xx:xx" з 17 символів (наприклад, отримана з ScanEntry.addr()).

addr_type (лише ключові слова)

Або constants.ADDR_TYPE_PUBLIC (за замовчуванням), або constants.ADDR_TYPE_RANDOM_STATIC.

class ubluepy.Scanner

GAP-спостерігач для виявлення навколишніх рекламуючих пристроїв. Доступний лише тоді, коли мікропрограма зібрана з SoftDevice з підтримкою центрального вузла (s132 / s140).

scan(timeout: int) list

Виконує пасивне сканування протягом timeout мілісекунд та повертає список екземплярів ScanEntry — по одному на кожен отриманий рекламний звіт протягом вікна.

class ubluepy.ScanEntry

Один рекламний звіт, захоплений Scanner.scan(). Екземпляри повертаються зі сканера — публічний конструктор відсутній.

addr() str

Повертає адресу пристрою у вигляді рядка "xx:xx:xx:xx:xx:xx" з 17 символів.

addr_type() int

Повертає тип адреси пристрою (constants.ADDR_TYPE_PUBLIC або constants.ADDR_TYPE_RANDOM_STATIC).

rssi() int

Повертає індикатор потужності сигналу в дБм.

getScanData() list

Декодує рекламне корисне навантаження у список кортежів (ad_type, description, value). ad_type — числовий байт типу AD (дивіться constants.ad_types), description — ім’я відповідної константи у вигляді рядка (або None, якщо тип невідомий), а value — тіло запису AD як bytearray.

class ubluepy.DefaultDelegate

Базовий клас для об’єктів, що передаються до Peripheral.withDelegate(). Створіть підклас та перевизначте handleConnection() / handleNotification() для реагування на події GATT.

handleConnection() None

Викликається при подіях GAP підключення / відключення. Типова реалізація порожня.

handleNotification() None

Викликається при вхідних GATT-сповіщеннях. Типова реалізація порожня.

Константи

Атрибут constants модуля — це простір імен, що містить ідентифікатори подій GAP/GATT, значення типів адрес та вкладений простір імен ad_types.

ubluepy.constants: type

Контейнер, що надає константи нижче.

constants.EVT_GAP_CONNECTED: int

Значення event_id обробника підключення Peripheral для підключення GAP (16).

constants.EVT_GAP_DISCONNECTED: int

Значення event_id обробника підключення Peripheral для відключення GAP (17).

constants.EVT_GATTS_WRITE: int

Значення event_id обробника підключення Peripheral для запису до локального атрибута GATT, включаючи записи до CCCD, що вмикають/вимикають сповіщення (80).

constants.UUID_CCCD: int

Стандартний Bluetooth UUID для Дескриптора конфігурації клієнтської характеристики (0x2902).

constants.ADDR_TYPE_PUBLIC: int

Публічна адреса Bluetooth-пристрою (0).

constants.ADDR_TYPE_RANDOM_STATIC: int

Статична випадкова адреса Bluetooth-пристрою (1).

constants.ad_types: type

Простір імен констант типів AD рекламних даних зі специфікації Bluetooth Core Specification Supplement. Кожне ім’я відповідає однобайтовому типу AD:

Ім’я

Значення

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