ubluepy — périphérique et central Bluetooth LE

Le module ubluepy est l’ancienne API Bluetooth LE livrée avec le portage nRF de MicroPython. Il est vaguement calqué sur la bibliothèque Python Linux bluepy et repose directement sur le SoftDevice de Nordic — il n’y a pas de back-end portable, ce module n’est donc disponible que sur les cibles Nordic (l’Arduino Nano 33 BLE Sense dans la gamme OpenMV). Les API plus récentes bluetooth / aioble ne sont pas activées dans cette version, ubluepy est donc le seul moyen de piloter la radio intégrée à la puce.

L’ensemble de fonctionnalités disponibles dépend du SoftDevice flashé par le micrologiciel :

  • s140 (Nano 33 BLE Sense) — à la fois les rôles périphérique et central (scanner). C’est ce que livre le micrologiciel OpenMV.

  • s132 — à la fois périphérique et central.

  • s110 — périphérique uniquement ; les méthodes de scan / connexion sont exclues à la compilation.

Exemple de périphérique

Diffuse en tant que périphérique Bluetooth LE avec un seul service de détection environnementale et notifie une caractéristique de température à chaque écriture dans son 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])

Exemple de central

Recherche les appareils diffusant à proximité pendant 100 ms et décode les données d’annonce de chaque 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))

Contenu du module

Classes

class ubluepy.UUID(value)

Construit un UUID Bluetooth 16 ou 128 bits.

value

Parmi :

  • int — un UUID numérique 16 bits (UUID(0x180A)).

  • une chaîne "0xXXXX" de 6 caractères — un UUID 16 bits, par exemple UUID("0x181A").

  • une chaîne "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" de 36 caractères — un UUID 128 bits complet. La partie spécifique au fournisseur est enregistrée auprès du SoftDevice lors de la construction.

  • une autre instance de UUID — effectue une copie.

Toute autre longueur déclenche ValueError("Invalid UUID string length").

binVal() int

Renvoie les 16 bits de poids faible de l’UUID sous forme d”int. Pour les UUID 128 bits, seul le champ 16 bits intégré dans l’UUID spécifique au fournisseur est renvoyé (la valeur complète sur 128 bits n’est accessible que via l’index spécifique au fournisseur du SoftDevice).

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

Définit un service GATT qui sera enregistré auprès du SoftDevice lorsqu’il est ajouté à un Peripheral.

uuid

Une instance de UUID. Passer un objet qui n’est pas un UUID déclenche ValueError.

type

Soit Service.PRIMARY (par défaut), soit Service.SECONDARY. Les autres valeurs déclenchent ValueError.

uuid() UUID

Renvoie l’instance UUID du service.

addCharacteristic(characteristic: Characteristic) None

Enregistre une Characteristic auprès du service. Le handle GATT de la caractéristique est attribué pendant cet appel.

getCharacteristic(uuid: UUID) Characteristic | None

Recherche une Characteristic précédemment ajoutée par son UUID. Renvoie l’instance de la caractéristique, ou None si aucune correspondance n’est trouvée.

getCharacteristics() list

Renvoie la liste de toutes les caractéristiques ajoutées au service.

PRIMARY: int

Constante de type de service pour les services primaires (1).

SECONDARY: int

Constante de type de service pour les services secondaires (2).

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

Définit une caractéristique GATT. Ajoutez-la à un Service avec Service.addCharacteristic() avant que le Peripheral parent ne commence à diffuser.

uuid

Une instance de UUID.

props (nommé uniquement)

Masque de bits d’une ou plusieurs valeurs Characteristic.PROP_* décrivant les opérations prises en charge par la caractéristique.

attrs (nommé uniquement)

Masque de bits d’attributs GATT supplémentaires. Utilisez Characteristic.ATTR_CCCD pour attacher un Client Characteristic Configuration Descriptor — requis pour faire fonctionner les caractéristiques PROP_NOTIFY / PROP_INDICATE.

uuid() UUID

Renvoie l’instance UUID de la caractéristique.

properties() int

Renvoie le masque de bits props défini lors de la construction.

read() bytearray

Rôle central uniquement. Lit la valeur de la caractéristique depuis le pair connecté. Renvoie un bytearray contenant la dernière valeur. Sur un périphérique, c’est une opération sans effet qui renvoie None.

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

Écrit dans la caractéristique.

  • Sur un périphérique, si PROP_NOTIFY est défini dans les propriétés de la caractéristique, la valeur est envoyée sous forme de notification GATT au central connecté ; sinon, la valeur de l’attribut local est mise à jour.

  • Sur un central, la valeur est écrite vers le pair distant. Définissez with_response=True pour émettre une requête d’écriture et attendre l’accusé de réception du pair au lieu d’une commande d’écriture.

data est n’importe quel objet conforme au protocole tampon (bytes, bytearray, memoryview).

PROP_BROADCAST: int

La caractéristique peut diffuser sa valeur (0x01).

PROP_READ: int

La caractéristique prend en charge les lectures (0x02).

PROP_WRITE_WO_RESP: int

La caractéristique prend en charge les écritures sans réponse (0x04).

PROP_WRITE: int

La caractéristique prend en charge les écritures avec réponse (0x08).

PROP_NOTIFY: int

La caractéristique peut envoyer des notifications à un central abonné (0x10).

PROP_INDICATE: int

La caractéristique peut envoyer des indications (notifications avec accusé de réception) à un central abonné (0x20).

PROP_AUTH_SIGNED_WR: int

La caractéristique prend en charge les écritures signées authentifiées (0x40).

ATTR_CCCD: int

Ajoute un Client Characteristic Configuration Descriptor à la caractéristique (0x01). Requis pour que les clients puissent s’abonner aux notifications/indications.

class ubluepy.Descriptor(uuid: UUID)

Classe stub représentant les descripteurs GATT. L’implémentation actuelle ne stocke que l’UUID et n’expose aucune méthode — elle est fournie pour assurer la compatibilité ascendante avec de futures révisions du module.

class ubluepy.Peripheral

Le périphérique Bluetooth LE local. La même classe est utilisée pour les rôles périphérique et central ; le rôle est sélectionné selon les méthodes que vous appelez (advertise() sélectionne le rôle périphérique, connect() sélectionne le rôle central).

addService(service: Service) None

Enregistre un Service (et toutes les caractéristiques ajoutées précédemment) auprès du serveur GATT local.

getServices() list

Renvoie la liste des services actuellement enregistrés auprès de ce Peripheral.

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

Démarre la diffusion en rôle périphérique.

device_name

Nom local complet diffusé dans la charge utile GAP.

services

Liste d’instances de Service à diffuser. L’UUID de chaque service est inclus dans l’annonce.

data

Charge utile d’annonce brute optionnelle (bytes / bytearray) ajoutée à l’en-tête généré automatiquement. Utilisez ceci pour des charges utiles spécifiques au fournisseur ou de balise telles qu’Eddystone.

connectable

Lorsque True (par défaut), diffuse en tant qu’appareil connectable et enregistre les gestionnaires d’événements GAP / GATTS afin que la fonction de rappel setConnectionHandler() configurée se déclenche lors de la connexion, de la déconnexion et des écritures CCCD. Lorsque False, diffuse en tant que balise — aucun gestionnaire n’est attaché et l’appareil ne peut pas être connecté.

advertise_stop() None

Arrête toute diffusion en cours.

setConnectionHandler(func) None

Enregistre une fonction de rappel invoquée lors des événements GAP et GATTS. La fonction de rappel est appelée sous la forme func(event_id, conn_handle, data)event_id est l’une des valeurs constants.EVT_GAP_CONNECTED, constants.EVT_GAP_DISCONNECTED ou constants.EVT_GATTS_WRITE, conn_handle est le handle de connexion du SoftDevice (ou le handle d’attribut pour les écritures GATTS), et data est la charge utile brute de l’événement sous forme de bytearray (ou None pour les connexions / déconnexions).

setNotificationHandler(func) None

Enregistre une fonction de rappel pour les événements de notification reçus en rôle central.

withDelegate(delegate: DefaultDelegate) None

Attache une instance de DefaultDelegate pour recevoir les événements GATT décodés.

disconnect() None

Coupe la connexion active (actuellement un stub sans effet dans cette version).

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

Rôle central uniquement. Se connecte au pair à l’adresse donnée et découvre de manière synchrone ses services et caractéristiques primaires. Bloque jusqu’à ce que la connexion soit établie et que la découverte soit terminée ; les services découverts sont ensuite disponibles via getServices().

addr

Adresse du pair sous forme de chaîne "xx:xx:xx:xx:xx:xx" de 17 caractères (par exemple, issue de ScanEntry.addr()).

addr_type (nommé uniquement)

Soit constants.ADDR_TYPE_PUBLIC (par défaut), soit constants.ADDR_TYPE_RANDOM_STATIC.

class ubluepy.Scanner

Observateur GAP pour découvrir les appareils diffusant à proximité. Disponible uniquement lorsque le micrologiciel est compilé avec un SoftDevice prenant en charge le rôle central (s132 / s140).

scan(timeout: int) list

Exécute un scan passif pendant timeout millisecondes et renvoie une liste d’instances de ScanEntry — une par rapport d’annonce reçu pendant la fenêtre.

class ubluepy.ScanEntry

Un seul rapport d’annonce capturé par Scanner.scan(). Les instances sont renvoyées par le scanner — il n’y a pas de constructeur public.

addr() str

Renvoie l’adresse du pair sous forme de chaîne "xx:xx:xx:xx:xx:xx" de 17 caractères.

addr_type() int

Renvoie le type d’adresse du pair (constants.ADDR_TYPE_PUBLIC ou constants.ADDR_TYPE_RANDOM_STATIC).

rssi() int

Renvoie l’indicateur de puissance du signal en dBm.

getScanData() list

Décode la charge utile d’annonce en une liste de tuples (ad_type, description, value). ad_type est l’octet numérique du type AD (voir constants.ad_types), description est le nom de la constante correspondante sous forme de chaîne (ou None si le type est inconnu), et value est le corps de l’enregistrement AD sous forme de bytearray.

class ubluepy.DefaultDelegate

Classe de base pour les objets passés à Peripheral.withDelegate(). Sous-classez-la et redéfinissez handleConnection() / handleNotification() pour réagir aux événements GATT.

handleConnection() None

Appelée lors des événements de connexion / déconnexion GAP. L’implémentation par défaut est vide.

handleNotification() None

Appelée lors des notifications GATT entrantes. L’implémentation par défaut est vide.

Constantes

L’attribut constants du module est un espace de noms contenant les identifiants d’événements GAP/GATT, les valeurs de type d’adresse et l’espace de noms imbriqué ad_types.

ubluepy.constants: type

Conteneur exposant les constantes ci-dessous.

constants.EVT_GAP_CONNECTED: int

Valeur event_id du gestionnaire de connexion Peripheral pour la connexion GAP (16).

constants.EVT_GAP_DISCONNECTED: int

Valeur event_id du gestionnaire de connexion Peripheral pour la déconnexion GAP (17).

constants.EVT_GATTS_WRITE: int

Valeur event_id du gestionnaire de connexion Peripheral pour une écriture dans un attribut GATT local, y compris les écritures dans un CCCD qui activent/désactivent les notifications (80).

constants.UUID_CCCD: int

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

constants.ADDR_TYPE_PUBLIC: int

Adresse d’appareil Bluetooth publique (0).

constants.ADDR_TYPE_RANDOM_STATIC: int

Adresse d’appareil Bluetooth aléatoire statique (1).

constants.ad_types: type

Espace de noms des constantes de type AD de données d’annonce issues du Bluetooth Core Specification Supplement. Chaque nom correspond au type AD 1 octet associé :

Nom

Valeur

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