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