ubluepy — periferic și central Bluetooth LE

Modulul ubluepy este vechea API Bluetooth LE livrată cu portul nRF al MicroPython. Este modelat în linii mari după biblioteca Python Linux bluepy și se află direct deasupra Nordic SoftDevice — nu există un back-end portabil, așa că modulul este disponibil doar pe ținte Nordic (Arduino Nano 33 BLE Sense din gama OpenMV). Noile API-uri bluetooth / aioble nu sunt activate în acest build, deci ubluepy este singura modalitate de a controla radioul integrat în cip.

Setul de funcționalități disponibile depinde de SoftDevice-ul scris în firmware:

  • s140 (Nano 33 BLE Sense) — atât rolul de periferic cât și cel de central (scaner). Acesta este cel livrat cu firmware-ul OpenMV.

  • s132 — atât periferic, cât și central.

  • s110 — doar periferic; metodele de scanare / conectare sunt excluse la compilare.

Exemplu de periferic

Anunță-te ca periferic Bluetooth LE cu un singur serviciu de detectare a mediului și notifică o caracteristică de temperatură la fiecare scriere în Client Characteristic Configuration Descriptor (CCCD) al acesteia:

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

Exemplu central

Scanează dispozitivele care fac advertising din apropiere timp de 100 ms și decodează datele de advertising ale fiecărui 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))

Conținutul modulului

Clase

class ubluepy.UUID(value)

Construiește un UUID Bluetooth pe 16 sau 128 de biți.

value

Una dintre:

  • int — un UUID numeric pe 16 biți (UUID(0x180A)).

  • șir de 6 caractere "0xXXXX" — un UUID pe 16 biți, de exemplu UUID("0x181A").

  • șir de 36 de caractere "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" — un UUID complet pe 128 de biți. Partea specifică furnizorului este înregistrată cu SoftDevice-ul la construire.

  • O altă instanță UUID — realizează o copie.

Orice altă lungime generează ValueError("Invalid UUID string length").

binVal() int

Returnează cei mai puțin semnificativi 16 biți ai UUID-ului ca int. Pentru UUID-urile pe 128 de biți se returnează doar câmpul de 16 biți încorporat în UUID-ul specific furnizorului (valoarea completă pe 128 de biți este accesibilă numai prin indexul specific furnizorului al SoftDevice-ului).

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

Definește un serviciu GATT care va fi înregistrat cu SoftDevice-ul atunci când este adăugat la un Peripheral.

uuid

O instanță UUID. Transmiterea unui obiect care nu este UUID generează ValueError.

type

Fie Service.PRIMARY (implicit), fie Service.SECONDARY. Alte valori generează ValueError.

uuid() UUID

Returnează instanța UUID a serviciului.

addCharacteristic(characteristic: Characteristic) None

Înregistrează o Characteristic în serviciu. Handle-ul GATT al caracteristicii este atribuit în timpul acestui apel.

getCharacteristic(uuid: UUID) Characteristic | None

Caută după UUID o Characteristic adăugată anterior. Returnează instanța caracteristicii sau None dacă nu se găsește nicio potrivire.

getCharacteristics() list

Returnează lista tuturor caracteristicilor adăugate serviciului.

PRIMARY: int

Constantă de tip de serviciu pentru servicii primare (1).

SECONDARY: int

Constantă de tip de serviciu pentru servicii secundare (2).

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

Definește o caracteristică GATT. Adaug-o la un Service cu Service.addCharacteristic() înainte ca Peripheral-ul părinte să înceapă advertising-ul.

uuid

O instanță UUID.

props (doar cuvânt-cheie)

Mască de biți cu una sau mai multe valori Characteristic.PROP_* care descriu ce operații suportă caracteristica.

attrs (doar cuvânt-cheie)

Mască de biți cu atribute GATT suplimentare. Folosiți Characteristic.ATTR_CCCD pentru a atașa un Client Characteristic Configuration Descriptor — necesar pentru a face să funcționeze caracteristicile PROP_NOTIFY / PROP_INDICATE.

uuid() UUID

Returnează instanța UUID a caracteristicii.

properties() int

Returnează masca de biți props setată la momentul construirii.

read() bytearray

Numai rolul central. Citește valoarea caracteristicii de la peer-ul conectat. Returnează un bytearray cu cea mai recentă valoare. Pe un periferic aceasta nu face nimic și returnează None.

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

Scrie în caracteristică.

  • Pe un periferic, dacă PROP_NOTIFY este setat în proprietățile caracteristicii, valoarea este trimisă ca notificare GATT către centralul conectat; în caz contrar, valoarea atributului local este actualizată.

  • Pe un central, valoarea este scrisă în peer-ul de la distanță. Setați with_response=True pentru a emite o cerere de scriere și a aștepta confirmarea peer-ului în loc de o comandă de scriere.

data este orice obiect compatibil cu protocolul buffer (bytes, bytearray, memoryview).

PROP_BROADCAST: int

Caracteristica își poate difuza valoarea (0x01).

PROP_READ: int

Caracteristica suportă citiri (0x02).

PROP_WRITE_WO_RESP: int

Caracteristica suportă scrieri fără răspuns (0x04).

PROP_WRITE: int

Caracteristica suportă scrieri cu răspuns (0x08).

PROP_NOTIFY: int

Caracteristica poate trimite notificări către un central abonat (0x10).

PROP_INDICATE: int

Caracteristica poate trimite indicații (notificări confirmate) către un central abonat (0x20).

PROP_AUTH_SIGNED_WR: int

Caracteristica suportă scrieri semnate autentificate (0x40).

ATTR_CCCD: int

Adaugă caracteristicii un Client Characteristic Configuration Descriptor (0x01). Necesar pentru ca clienții să se poată abona la notificări/indicații.

class ubluepy.Descriptor(uuid: UUID)

Clasă stub pentru reprezentarea descriptorilor GATT. Implementarea actuală stochează doar UUID-ul și nu expune nicio metodă — este furnizată pentru compatibilitatea ulterioară cu viitoarele revizii ale modulului.

class ubluepy.Peripheral

Dispozitivul Bluetooth LE local. Aceeași clasă este folosită atât pentru rolul de periferic, cât și pentru cel de central; rolul este selectat de metodele pe care le apelați (advertise() selectează perifericul, connect() selectează centralul).

addService(service: Service) None

Înregistrează un Service (și toate caracteristicile adăugate anterior la acesta) cu serverul GATT local.

getServices() list

Returnează lista serviciilor înregistrate în prezent cu acest Peripheral.

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

Începe advertising-ul în rolul de periferic.

device_name

Numele local complet anunțat în payload-ul GAP.

services

Lista instanțelor Service de anunțat. UUID-ul fiecărui serviciu este inclus în advertising.

data

Payload brut opțional de advertising (bytes / bytearray) atașat antetului generat automat. Folosiți acest lucru pentru payload-uri specifice furnizorului sau de tip beacon, cum ar fi Eddystone.

connectable

Când este True (implicit), anunță ca dispozitiv conectabil și înregistrează gestionari de evenimente GAP / GATTS, astfel încât funcția de retroapelare (callback) configurată prin setConnectionHandler() să se declanșeze la conectare, deconectare și scrieri CCCD. Când este False, anunță ca beacon — niciun gestionar nu este atașat, iar dispozitivul nu poate fi conectat.

advertise_stop() None

Oprește orice advertising în curs de desfășurare.

setConnectionHandler(func) None

Înregistrează o funcție de retroapelare (callback) invocată la evenimente GAP și GATTS. Funcția de retroapelare este apelată ca func(event_id, conn_handle, data), unde event_id este una dintre valorile constants.EVT_GAP_CONNECTED, constants.EVT_GAP_DISCONNECTED sau constants.EVT_GATTS_WRITE, conn_handle este handle-ul de conexiune SoftDevice (sau handle-ul de atribut pentru scrierile GATTS), iar data este payload-ul brut al evenimentului sub forma unui bytearray (sau None pentru conectare / deconectare).

setNotificationHandler(func) None

Înregistrează o funcție de retroapelare (callback) pentru evenimentele de notificare primite în rolul de central.

withDelegate(delegate: DefaultDelegate) None

Atașează o instanță DefaultDelegate pentru a primi evenimente GATT decodate.

disconnect() None

Întrerupe conexiunea activă (în prezent un stub care nu face nimic în acest build).

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

Numai rolul central. Se conectează la peer-ul cu adresa dată și descoperă sincron serviciile și caracteristicile sale primare. Blochează până când conexiunea este stabilită și descoperirea se finalizează; serviciile descoperite sunt apoi disponibile prin getServices().

addr

Adresa peer-ului sub forma unui șir de 17 caractere "xx:xx:xx:xx:xx:xx" (de exemplu, preluată din ScanEntry.addr()).

addr_type (doar cuvânt-cheie)

Fie constants.ADDR_TYPE_PUBLIC (implicit), fie constants.ADDR_TYPE_RANDOM_STATIC.

class ubluepy.Scanner

Observator GAP pentru descoperirea dispozitivelor din apropiere care fac advertising. Disponibil numai atunci când firmware-ul este construit cu un SoftDevice cu suport pentru rolul central (s132 / s140).

scan(timeout: int) list

Rulează o scanare pasivă timp de timeout milisecunde și returnează o listă de instanțe ScanEntry — una pentru fiecare raport de advertising primit în timpul ferestrei.

class ubluepy.ScanEntry

Un singur raport de advertising capturat de Scanner.scan(). Instanțele sunt returnate de scaner — nu există un constructor public.

addr() str

Returnează adresa peer-ului sub forma unui șir de 17 caractere "xx:xx:xx:xx:xx:xx".

addr_type() int

Returnează tipul adresei peer-ului (constants.ADDR_TYPE_PUBLIC sau constants.ADDR_TYPE_RANDOM_STATIC).

rssi() int

Returnează indicatorul de putere a semnalului în dBm.

getScanData() list

Decodează payload-ul de advertising într-o listă de tupluri (ad_type, description, value). ad_type este octetul numeric al tipului AD (consultați constants.ad_types), description este numele constantei corespunzătoare sub formă de șir (sau None dacă tipul este necunoscut), iar value este corpul înregistrării AD sub forma unui bytearray.

class ubluepy.DefaultDelegate

Clasă de bază pentru obiectele transmise către Peripheral.withDelegate(). Creați o subclasă a acesteia și suprascrieți handleConnection() / handleNotification() pentru a reacționa la evenimente GATT.

handleConnection() None

Apelată la evenimente GAP de conectare / deconectare. Implementarea implicită este goală.

handleNotification() None

Apelată la notificările GATT primite. Implementarea implicită este goală.

Constante

Atributul constants al modulului este un spațiu de nume care conține identificatori de evenimente GAP/GATT, valori de tip de adresă și spațiul de nume imbricat ad_types.

ubluepy.constants: type

Container care expune constantele de mai jos.

constants.EVT_GAP_CONNECTED: int

Valoarea event_id a gestionarului de conexiune al Peripheral pentru conectare GAP (16).

constants.EVT_GAP_DISCONNECTED: int

Valoarea event_id a gestionarului de conexiune al Peripheral pentru deconectare GAP (17).

constants.EVT_GATTS_WRITE: int

Valoarea event_id a gestionarului de conexiune al Peripheral pentru o scriere într-un atribut GATT local, inclusiv scrieri într-un CCCD care activează/dezactivează notificările (80).

constants.UUID_CCCD: int

UUID Bluetooth standard pentru Client Characteristic Configuration Descriptor (0x2902).

constants.ADDR_TYPE_PUBLIC: int

Adresă publică de dispozitiv Bluetooth (0).

constants.ADDR_TYPE_RANDOM_STATIC: int

Adresă aleatorie statică de dispozitiv Bluetooth (1).

constants.ad_types: type

Spațiu de nume al constantelor de tip AD pentru datele de advertising din Bluetooth Core Specification Supplement. Fiecare nume se mapează la tipul AD corespunzător de 1 octet:

Nume

Valoare

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