ubluepy --- Bluetooth LE 周邊與中央¶
ubluepy 模組是隨 MicroPython nRF 移植版一同提供的傳統 Bluetooth LE API。它大致仿照 Linux bluepy Python 函式庫,並直接架構於 Nordic SoftDevice 之上——它沒有可移植的後端,因此本模組僅在 Nordic 目標裝置上可用(在 OpenMV 產品線中即 Arduino Nano 33 BLE Sense)。較新的 bluetooth / aioble API 在此建置中並未啟用,因此 ubluepy 是驅動晶片內無線電的唯一方式。
可用的功能集取決於韌體所燒錄的 SoftDevice:
s140(Nano 33 BLE Sense)——同時支援周邊與中央(掃描器)角色。這正是 OpenMV 韌體所提供的版本。
s132——同時支援周邊與中央。
s110——僅支援周邊;掃描器/連線方法已被編譯排除。
周邊範例¶
作為 Bluetooth LE 周邊進行廣播,提供單一環境感測服務,並在每次寫入其用戶端特徵組態描述子(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])
中央範例¶
掃描附近正在廣播的裝置 100 ms,並解碼每個 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))。6 字元的
"0xXXXX"字串 —— 16 位元 UUID,例如UUID("0x181A")。36 字元的
"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"字串 —— 完整的 128 位元 UUID。供應商特定部分會在建構時向 SoftDevice 註冊。另一個
UUID實例 —— 執行複製。
其他任何長度都會引發
ValueError("Invalid UUID string length")。
- class ubluepy.Service(uuid: UUID, type: int = Service.PRIMARY)¶
定義一個 GATT 服務,當其加入
Peripheral時會向 SoftDevice 註冊。uuid一個
UUID實例。傳入非 UUID 物件會引發ValueError。type可為
Service.PRIMARY(預設)或Service.SECONDARY。其他值會引發ValueError。
- addCharacteristic(characteristic: Characteristic) None¶
向服務註冊一個
Characteristic。該特徵的 GATT 控制代碼會在此呼叫期間指派。
- getCharacteristic(uuid: UUID) Characteristic | None¶
依 UUID 查詢先前已加入的
Characteristic。傳回該特徵實例,若找不到相符項目則傳回None。
- class ubluepy.Characteristic(uuid: UUID, *, props: int = PROP_READ | PROP_WRITE, attrs: int = 0)¶
定義一個 GATT 特徵。請先以
Service.addCharacteristic()將它加入Service,再讓父Peripheral開始廣播。uuid一個
UUID實例。props(僅限關鍵字)由一個或多個
Characteristic.PROP_*值組成的位元遮罩,描述該特徵支援哪些操作。attrs(僅限關鍵字)額外 GATT 屬性的位元遮罩。使用
Characteristic.ATTR_CCCD來附加用戶端特徵組態描述子——這是讓PROP_NOTIFY/PROP_INDICATE特徵運作的必要條件。
- class ubluepy.Descriptor(uuid: UUID)¶
用於表示 GATT 描述子的存根類別。目前的實作只儲存 UUID 並且不公開任何方法——提供它是為了與本模組未來版本的向前相容性。
- class ubluepy.Peripheral¶
本機 Bluetooth LE 裝置。同一個類別同時用於周邊與中央角色;角色由您呼叫的方法決定(
advertise()選擇周邊,connect()選擇中央)。- 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時,作為信標廣播——不附加任何處理常式,且該裝置無法被連線。
- 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)。
- withDelegate(delegate: DefaultDelegate) None¶
附加一個
DefaultDelegate實例以接收已解碼的 GATT 事件。
- connect(addr, *, addr_type: int = constants.ADDR_TYPE_PUBLIC) None¶
僅限中央角色。 連線至具有給定位址的對端,並同步探索其主要服務與特徵。會封鎖直到連線建立且探索完成;探索到的服務隨後可透過
getServices()取得。addr對端位址,為 17 字元的
"xx:xx:xx:xx:xx:xx"字串(例如取自ScanEntry.addr())。addr_type(僅限關鍵字)可為
constants.ADDR_TYPE_PUBLIC(預設)或constants.ADDR_TYPE_RANDOM_STATIC。
- class ubluepy.Scanner¶
用於探索附近正在廣播裝置的 GAP 觀察者。僅在韌體針對具有中央支援的 SoftDevice(s132 / s140)建置時可用。
- class ubluepy.ScanEntry¶
由
Scanner.scan()擷取的單一廣播報告。實例由掃描器傳回——沒有公開的建構函式。- addr_type() int¶
傳回對端位址類型(
constants.ADDR_TYPE_PUBLIC或constants.ADDR_TYPE_RANDOM_STATIC)。
- 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 事件做出反應。
常數¶
本模組的 constants 屬性是一個命名空間,包含 GAP/GATT 事件識別碼、位址類型值,以及巢狀的 ad_types 命名空間。
- constants.EVT_GATTS_WRITE: int¶
寫入本機 GATT 屬性(包括啟用/停用通知的 CCCD 寫入)時
Peripheral連線處理常式的event_id值(80)。
- constants.ad_types: type¶
來自 Bluetooth Core Specification Supplement 的廣播資料 AD 類型常數命名空間。每個名稱對應到相應的 1 位元組 AD 類型:
名稱
值
AD_TYPE_FLAGS0x01AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE0x02AD_TYPE_16BIT_SERVICE_UUID_COMPLETE0x03AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE0x04AD_TYPE_32BIT_SERVICE_UUID_COMPLETE0x05AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE0x06AD_TYPE_128BIT_SERVICE_UUID_COMPLETE0x07AD_TYPE_SHORT_LOCAL_NAME0x08AD_TYPE_COMPLETE_LOCAL_NAME0x09AD_TYPE_TX_POWER_LEVEL0x0AAD_TYPE_CLASS_OF_DEVICE0x0DAD_TYPE_SIMPLE_PAIRING_HASH_C0x0EAD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R0x0FAD_TYPE_SECURITY_MANAGER_TK_VALUE0x10AD_TYPE_SECURITY_MANAGER_OOB_FLAGS0x11AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE0x12AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT0x14AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT0x15AD_TYPE_SERVICE_DATA0x16AD_TYPE_PUBLIC_TARGET_ADDRESS0x17AD_TYPE_RANDOM_TARGET_ADDRESS0x18AD_TYPE_APPEARANCE0x19AD_TYPE_ADVERTISING_INTERVAL0x1AAD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS0x1BAD_TYPE_LE_ROLE0x1CAD_TYPE_SIMPLE_PAIRING_HASH_C2560x1DAD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R2560x1EAD_TYPE_SERVICE_DATA_32BIT_UUID0x20AD_TYPE_SERVICE_DATA_128BIT_UUID0x21AD_TYPE_URI0x24AD_TYPE_3D_INFORMATION_DATA0x3DAD_TYPE_MANUFACTURER_SPECIFIC_DATA0xFF