ubluepy — periférico e central Bluetooth LE

O módulo ubluepy é a API legada de Bluetooth LE fornecida com a port nRF do MicroPython. Ele é vagamente modelado a partir da biblioteca Python bluepy do Linux e fica diretamente sobre o Nordic SoftDevice — não há back-end portável, então o módulo está disponível apenas em alvos Nordic (a Arduino Nano 33 BLE Sense na linha da OpenMV). As APIs mais novas bluetooth / aioble não estão habilitadas nesta build, então ubluepy é a única forma de controlar o rádio integrado ao chip.

O conjunto de recursos disponível depende do SoftDevice gravado pelo firmware:

  • s140 (Nano 33 BLE Sense) — ambos os papéis, periférico e central (scanner). É isto que o firmware da OpenMV fornece.

  • s132 — tanto periférico quanto central.

  • s110 — apenas periférico; os métodos de scanner / conexão são removidos na compilação.

Exemplo de periférico

Anuncia-se como um periférico Bluetooth LE com um único serviço de sensoriamento ambiental e notifica uma característica de temperatura a cada escrita em seu 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])

Exemplo de central

Procura por dispositivos próximos que estejam anunciando durante 100 ms e decodifica os dados de anúncio de cada 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))

Conteúdo do módulo

Classes

class ubluepy.UUID(value)

Constrói um UUID Bluetooth de 16 ou 128 bits.

value

Um de:

  • int — um UUID numérico de 16 bits (UUID(0x180A)).

  • string "0xXXXX" de 6 caracteres — um UUID de 16 bits, por exemplo, UUID("0x181A").

  • string "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" de 36 caracteres — um UUID completo de 128 bits. A parte específica do fabricante é registrada com o SoftDevice na construção.

  • Outra instância de UUID — realiza uma cópia.

Qualquer outro comprimento gera ValueError("Invalid UUID string length").

binVal() int

Retorna os 16 bits inferiores do UUID como um int. Para UUIDs de 128 bits, apenas o campo de 16 bits embutido dentro do UUID específico do fabricante é retornado (o valor completo de 128 bits é acessível apenas através do índice específico do fabricante do SoftDevice).

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

Define um serviço GATT que será registrado com o SoftDevice quando adicionado a um Peripheral.

uuid

Uma instância de UUID. Passar um objeto que não seja UUID gera ValueError.

type

Ou Service.PRIMARY (padrão) ou Service.SECONDARY. Outros valores geram ValueError.

uuid() UUID

Retorna a instância de UUID do serviço.

addCharacteristic(characteristic: Characteristic) None

Registra uma Characteristic com o serviço. O handle GATT da característica é atribuído durante esta chamada.

getCharacteristic(uuid: UUID) Characteristic | None

Procura uma Characteristic previamente adicionada pelo UUID. Retorna a instância da característica, ou None se nenhuma correspondência for encontrada.

getCharacteristics() list

Retorna a lista de todas as características adicionadas ao serviço.

PRIMARY: int

Constante de tipo de serviço para serviços primários (1).

SECONDARY: int

Constante de tipo de serviço para serviços secundários (2).

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

Define uma característica GATT. Adicione-a a um Service com Service.addCharacteristic() antes que o Peripheral pai comece a anunciar.

uuid

Uma instância de UUID.

props (somente nomeado)

Máscara de bits de um ou mais valores Characteristic.PROP_* que descrevem quais operações a característica suporta.

attrs (somente nomeado)

Máscara de bits de atributos GATT adicionais. Use Characteristic.ATTR_CCCD para anexar um Client Characteristic Configuration Descriptor — necessário para fazer as características PROP_NOTIFY / PROP_INDICATE funcionarem.

uuid() UUID

Retorna a instância de UUID da característica.

properties() int

Retorna a máscara de bits props definida no momento da construção.

read() bytearray

Apenas no papel de central. Lê o valor da característica do peer conectado. Retorna um bytearray com o valor mais recente. Em um periférico, isto não tem efeito e retorna None.

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

Escreve na característica.

  • Em um periférico, se PROP_NOTIFY estiver definido nas propriedades da característica, o valor é enviado como uma notificação GATT à central conectada; caso contrário, o valor do atributo local é atualizado.

  • Em uma central, o valor é escrito no peer remoto. Defina with_response=True para emitir uma requisição de escrita e aguardar a confirmação do peer em vez de um comando de escrita.

data é qualquer objeto que siga o protocolo de buffer (bytes, bytearray, memoryview).

PROP_BROADCAST: int

A característica pode difundir seu valor (0x01).

PROP_READ: int

A característica suporta leituras (0x02).

PROP_WRITE_WO_RESP: int

A característica suporta escritas sem resposta (0x04).

PROP_WRITE: int

A característica suporta escritas com resposta (0x08).

PROP_NOTIFY: int

A característica pode enviar notificações a uma central inscrita (0x10).

PROP_INDICATE: int

A característica pode enviar indicações (notificações confirmadas) a uma central inscrita (0x20).

PROP_AUTH_SIGNED_WR: int

A característica suporta escritas assinadas autenticadas (0x40).

ATTR_CCCD: int

Adiciona um Client Characteristic Configuration Descriptor à característica (0x01). Necessário para que os clientes possam se inscrever em notificações/indicações.

class ubluepy.Descriptor(uuid: UUID)

Classe stub para representar descritores GATT. A implementação atual apenas armazena o UUID e não expõe métodos — ela é fornecida para compatibilidade futura com revisões posteriores do módulo.

class ubluepy.Peripheral

O dispositivo Bluetooth LE local. A mesma classe é usada para os papéis de periférico e de central; o papel é selecionado pelos métodos que você chama (advertise() seleciona periférico, connect() seleciona central).

addService(service: Service) None

Registra um Service (e todas as suas características previamente adicionadas) com o servidor GATT local.

getServices() list

Retorna a lista de serviços atualmente registrados com este Peripheral.

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

Começa a anunciar no papel de periférico.

device_name

Nome local completo anunciado no payload GAP.

services

Lista de instâncias de Service a serem anunciadas. O UUID de cada serviço é incluído no anúncio.

data

Payload de anúncio bruto opcional (bytes / bytearray) anexado ao cabeçalho gerado automaticamente. Use isto para payloads específicos do fabricante ou de beacon, como o Eddystone.

connectable

Quando True (padrão), anuncia como um dispositivo conectável e registra handlers de eventos GAP / GATTS, de modo que o callback setConnectionHandler() configurado seja disparado na conexão, desconexão e escritas em CCCD. Quando False, anuncia como um beacon — nenhum handler é anexado e o dispositivo não pode ser conectado.

advertise_stop() None

Para qualquer anúncio em andamento.

setConnectionHandler(func) None

Registra um callback invocado em eventos GAP e GATTS. O callback é chamado como func(event_id, conn_handle, data) onde event_id é um dos valores constants.EVT_GAP_CONNECTED, constants.EVT_GAP_DISCONNECTED ou constants.EVT_GATTS_WRITE, conn_handle é o handle de conexão do SoftDevice (ou o handle de atributo para escritas GATTS), e data é o payload bruto do evento como um bytearray (ou None para conexão / desconexão).

setNotificationHandler(func) None

Registra um callback para eventos de notificação recebidos no papel de central.

withDelegate(delegate: DefaultDelegate) None

Anexa uma instância de DefaultDelegate para receber eventos GATT decodificados.

disconnect() None

Encerra a conexão ativa (atualmente um stub sem efeito nesta build).

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

Apenas no papel de central. Conecta-se ao peer com o endereço fornecido e descobre de forma síncrona seus serviços e características primários. Bloqueia até que a conexão seja estabelecida e a descoberta seja concluída; os serviços descobertos ficam então disponíveis via getServices().

addr

Endereço do peer como uma string "xx:xx:xx:xx:xx:xx" de 17 caracteres (por exemplo, obtido de ScanEntry.addr()).

addr_type (somente nomeado)

Ou constants.ADDR_TYPE_PUBLIC (padrão) ou constants.ADDR_TYPE_RANDOM_STATIC.

class ubluepy.Scanner

Observador GAP para descobrir dispositivos próximos que estejam anunciando. Disponível apenas quando o firmware é compilado com um SoftDevice que tenha suporte a central (s132 / s140).

scan(timeout: int) list

Executa uma varredura passiva por timeout milissegundos e retorna uma lista de instâncias de ScanEntry — uma por relatório de anúncio recebido durante a janela.

class ubluepy.ScanEntry

Um único relatório de anúncio capturado por Scanner.scan(). As instâncias são retornadas pelo scanner — não há construtor público.

addr() str

Retorna o endereço do peer como uma string "xx:xx:xx:xx:xx:xx" de 17 caracteres.

addr_type() int

Retorna o tipo de endereço do peer (constants.ADDR_TYPE_PUBLIC ou constants.ADDR_TYPE_RANDOM_STATIC).

rssi() int

Retorna o indicador de intensidade do sinal em dBm.

getScanData() list

Decodifica o payload de anúncio em uma lista de tuplas (ad_type, description, value). ad_type é o byte numérico de tipo AD (consulte constants.ad_types), description é o nome da constante correspondente como uma string (ou None se o tipo for desconhecido), e value é o corpo do registro AD como um bytearray.

class ubluepy.DefaultDelegate

Classe base para objetos passados para Peripheral.withDelegate(). Crie uma subclasse e sobrescreva handleConnection() / handleNotification() para reagir a eventos GATT.

handleConnection() None

Chamado em eventos GAP de conexão / desconexão. A implementação padrão é vazia.

handleNotification() None

Chamado em notificações GATT recebidas. A implementação padrão é vazia.

Constantes

O atributo constants do módulo é um namespace contendo identificadores de eventos GAP/GATT, valores de tipo de endereço e o namespace aninhado ad_types.

ubluepy.constants: type

Container que expõe as constantes abaixo.

constants.EVT_GAP_CONNECTED: int

Valor de event_id do handler de conexão do Peripheral para conexão GAP (16).

constants.EVT_GAP_DISCONNECTED: int

Valor de event_id do handler de conexão do Peripheral para desconexão GAP (17).

constants.EVT_GATTS_WRITE: int

Valor de event_id do handler de conexão do Peripheral para uma escrita em um atributo GATT local, incluindo escritas em um CCCD que habilitam/desabilitam notificações (80).

constants.UUID_CCCD: int

UUID Bluetooth padrão para o Client Characteristic Configuration Descriptor (0x2902).

constants.ADDR_TYPE_PUBLIC: int

Endereço de dispositivo Bluetooth público (0).

constants.ADDR_TYPE_RANDOM_STATIC: int

Endereço de dispositivo Bluetooth aleatório estático (1).

constants.ad_types: type

Namespace de constantes de tipo AD de dados de anúncio do Bluetooth Core Specification Supplement. Cada nome mapeia para o tipo AD de 1 byte correspondente:

Nome

Valor

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