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")를 발생시킵니다.

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#

기본(primary) 서비스에 대한 서비스 타입 상수(1).

SECONDARY: int#

보조(secondary) 서비스에 대한 서비스 타입 상수(2).

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

GATT 특성을 정의합니다. 상위 Peripheral이 광고를 시작하기 전에 Service.addCharacteristic()으로 Service에 추가하세요.

uuid

UUID 인스턴스입니다.

props (키워드 전용)

특성이 지원하는 작업을 설명하는 하나 이상의 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 통지로 전송됩니다. 그렇지 않으면 로컬 속성 값이 업데이트됩니다.

  • 센트럴에서는 값이 원격 피어에 기록됩니다. write 명령 대신 write 요청을 발행하고 피어의 확인 응답을 기다리려면 with_response=True를 설정하세요.

data는 버퍼 프로토콜을 따르는 임의의 객체(bytes, bytearray, memoryview)입니다.

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 이벤트 핸들러를 등록하여 구성된 setConnectionHandler() 콜백이 연결, 연결 해제, CCCD 쓰기 시 호출되도록 합니다. False이면 비콘으로 광고하며, 핸들러가 연결되지 않고 장치에 연결할 수 없습니다.

advertise_stop() None#

진행 중인 광고를 중지합니다.

setConnectionHandler(func) None#

GAP 및 GATTS 이벤트에서 호출되는 콜백을 등록합니다. 콜백은 func(event_id, conn_handle, data)로 호출되며, 여기서 event_idconstants.EVT_GAP_CONNECTED, constants.EVT_GAP_DISCONNECTED, constants.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 인스턴스의 목록을 반환합니다 — 윈도우 동안 수신된 광고 보고마다 하나씩입니다.

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)이며, value는 AD 레코드 본문을 bytearray로 나타낸 것입니다.

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