ubluepy --- Bluetooth LE のペリフェラルとセントラル

ubluepy モジュールは、MicroPython の nRF port に付属するレガシーな 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") を送出します。

binVal() int

UUID の下位 16 ビットを int として返します。128 ビット UUID の場合、ベンダー固有 UUID 内に埋め込まれた 16 ビットフィールドのみが返されます (完全な 128 ビット値は SoftDevice のベンダー固有インデックス経由でのみアクセスできます)。

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

Peripheral に追加されたときに SoftDevice に登録される GATT サービスを定義します。

uuid

UUID インスタンス。UUID 以外のオブジェクトを渡すと ValueError が送出されます。

type

Service.PRIMARY (デフォルト) または Service.SECONDARY のいずれか。それ以外の値は ValueError を送出します。

uuid() UUID

サービスの UUID インスタンスを返します。

addCharacteristic(characteristic: Characteristic) None

Characteristic をサービスに登録します。キャラクタリスティックの GATT ハンドルはこの呼び出し中に割り当てられます。

getCharacteristic(uuid: UUID) Characteristic | None

以前に追加された Characteristic を UUID で検索します。一致するキャラクタリスティックインスタンスを返します。一致が見つからない場合は None を返します。

getCharacteristics() list

サービスに追加されたすべてのキャラクタリスティックのリストを返します。

PRIMARY: int

プライマリサービスを表すサービス種別定数 (1)。

SECONDARY: int

セカンダリサービスを表すサービス種別定数 (2)。

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

GATT キャラクタリスティックを定義します。親の Peripheral がアドバタイズを開始する前に、Service.addCharacteristic() を使って Service に追加してください。

uuid

UUID インスタンス。

props (キーワード専用)

キャラクタリスティックがサポートする操作を示す、1 つ以上の Characteristic.PROP_* 値のビットマスク。

attrs (キーワード専用)

追加の GATT 属性のビットマスク。Client Characteristic Configuration Descriptor を付加するには Characteristic.ATTR_CCCD を使用します --- これは PROP_NOTIFY / PROP_INDICATE キャラクタリスティックを動作させるために必要です。

uuid() UUID

キャラクタリスティックの UUID インスタンスを返します。

properties() int

構築時に設定された props ビットマスクを返します。

read() bytearray

セントラルロールのみ。 接続中のピアからキャラクタリスティックの値を読み取ります。最新の値を含む bytearray を返します。ペリフェラル上では何もせず、None を返します。

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

キャラクタリスティックに書き込みます。

  • ペリフェラルでは、キャラクタリスティックのプロパティに PROP_NOTIFY が設定されている場合、値は接続中のセントラルへの GATT 通知として送信されます。設定されていない場合は、ローカルの属性値が更新されます。

  • セントラルでは、値はリモートのピアに書き込まれます。書き込みコマンドの代わりに書き込み要求を発行し、ピアの確認応答を待つには with_response=True を設定します。

data は任意のバッファプロトコルオブジェクト (bytesbytearraymemoryview) です。

PROP_BROADCAST: int

キャラクタリスティックは値をブロードキャストできます (0x01)。

PROP_READ: int

キャラクタリスティックは読み取りをサポートします (0x02)。

PROP_WRITE_WO_RESP: int

キャラクタリスティックは応答なしの書き込みをサポートします (0x04)。

PROP_WRITE: int

キャラクタリスティックは応答ありの書き込みをサポートします (0x08)。

PROP_NOTIFY: int

キャラクタリスティックは購読中のセントラルに通知をプッシュできます (0x10)。

PROP_INDICATE: int

キャラクタリスティックは購読中のセントラルにインジケーション (確認応答付きの通知) をプッシュできます (0x20)。

PROP_AUTH_SIGNED_WR: int

キャラクタリスティックは認証付き署名書き込みをサポートします (0x40)。

ATTR_CCCD: int

キャラクタリスティックに Client Characteristic Configuration Descriptor を追加します (0x01)。クライアントが通知 / インジケーションを購読できるようにするために必要です。

class ubluepy.Descriptor(uuid: UUID)

GATT ディスクリプタを表すスタブクラスです。現在の実装は UUID のみを保持し、メソッドを公開しません --- 本モジュールの将来のリビジョンとの前方互換性のために提供されています。

class ubluepy.Peripheral

ローカルの Bluetooth LE デバイスです。ペリフェラルとセントラルの両ロールで同じクラスが使用されます。ロールは呼び出すメソッドによって選択されます (advertise() はペリフェラルを、connect() はセントラルを選択します)。

addService(service: Service) None

Service (および以前に追加されたそのすべてのキャラクタリスティック) をローカルの GATT サーバーに登録します。

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 イベントハンドラを登録します。これにより、接続、切断、CCCD への書き込み時に、設定された setConnectionHandler() コールバックが発火します。False の場合はビーコンとしてアドバタイズします --- ハンドラは登録されず、デバイスに接続することはできません。

advertise_stop() None

進行中のアドバタイズメントをすべて停止します。

setConnectionHandler(func) None

GAP および GATTS イベントで呼び出されるコールバックを登録します。コールバックは func(event_id, conn_handle, data) の形式で呼び出されます。event_idconstants.EVT_GAP_CONNECTEDconstants.EVT_GAP_DISCONNECTEDconstants.EVT_GATTS_WRITE のいずれかの値、conn_handle は SoftDevice の接続ハンドル (GATTS 書き込みの場合は属性ハンドル)、databytearray としての生のイベントペイロード (接続 / 切断の場合は None) です。

setNotificationHandler(func) None

セントラルロールで受信した通知イベント用のコールバックを登録します。

withDelegate(delegate: DefaultDelegate) None

デコードされた GATT イベントを受け取る DefaultDelegate インスタンスを取り付けます。

disconnect() None

アクティブな接続を切断します (このビルドでは現在何もしないスタブです)。

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) に対してビルドされている場合にのみ利用できます。

scan(timeout: int) list

timeout ミリ秒の間パッシブスキャンを実行し、ScanEntry インスタンスのリスト (期間中に受信したアドバタイズメントレポートごとに 1 つ) を返します。

class ubluepy.ScanEntry

Scanner.scan() で取得された単一のアドバタイズメントレポートです。インスタンスはスキャナーから返されます --- パブリックなコンストラクタはありません。

addr() str

ピアアドレスを 17 文字の "xx:xx:xx:xx:xx:xx" 文字列として返します。

addr_type() int

ピアアドレスの種別 (constants.ADDR_TYPE_PUBLIC または constants.ADDR_TYPE_RANDOM_STATIC) を返します。

rssi() int

信号強度インジケータを dBm で返します。

getScanData() list

アドバタイズメントペイロードを (ad_type, description, value) タプルのリストにデコードします。ad_type は数値の AD 型バイト (constants.ad_types を参照)、description は一致する定数の名前を文字列にしたもの (型が不明な場合は None)、valuebytearray としての AD レコード本体です。

class ubluepy.DefaultDelegate

Peripheral.withDelegate() に渡すオブジェクトの基底クラスです。これをサブクラス化し、handleConnection() / handleNotification() をオーバーライドして GATT イベントに反応させます。

handleConnection() None

GAP の接続 / 切断イベント時に呼び出されます。デフォルトの実装は空です。

handleNotification() None

受信した GATT 通知時に呼び出されます。デフォルトの実装は空です。

定数

モジュールの constants 属性は、GAP/GATT イベント識別子、アドレス種別の値、およびネストされた ad_types 名前空間を含む名前空間です。

ubluepy.constants: type

以下の定数を公開するコンテナです。

constants.EVT_GAP_CONNECTED: int

GAP 接続を表す Peripheral 接続ハンドラの event_id 値 (16)。

constants.EVT_GAP_DISCONNECTED: int

GAP 切断を表す Peripheral 接続ハンドラの event_id 値 (17)。

constants.EVT_GATTS_WRITE: int

ローカル GATT 属性への書き込み (通知を有効/無効にする CCCD への書き込みを含む) を表す Peripheral 接続ハンドラの event_id 値 (80)。

constants.UUID_CCCD: int

Client Characteristic Configuration Descriptor の標準 Bluetooth UUID (0x2902)。

constants.ADDR_TYPE_PUBLIC: int

パブリック Bluetooth デバイスアドレス (0)。

constants.ADDR_TYPE_RANDOM_STATIC: int

スタティックランダム Bluetooth デバイスアドレス (1)。

constants.ad_types: type

Bluetooth Core Specification Supplement に基づくアドバタイジングデータの AD 型定数の名前空間です。各名前は対応する 1 バイトの AD 型にマッピングされます:

名前

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