src.bluetooth_sig.advertising.base

Base classes for advertising data interpreters.

Advertising data interpretation follows a two-layer architecture:

  1. PDU Parsing (AdvertisingPDUParser): Raw bytes → AD structures - Extracts manufacturer_data, service_data, flags, local_name, etc. - Framework-agnostic, works with raw BLE PDU bytes

  2. Data Interpretation (AdvertisingDataInterpreter): AD structures → typed results - Interprets vendor-specific protocols (BTHome, Xiaomi, RuuviTag, etc.) - Returns strongly-typed sensor data (temperature, humidity, etc.) - Maintains per-device state (encryption counters, packet IDs)

Attributes

Name

Description

T

Classes

Name

Description

AdvertisingDataInterpreter

Base class for vendor-specific advertising data interpretation.

AdvertisingInterpreterInfo

Interpreter metadata for routing and identification.

DataSource

Primary data source for interpreter routing.

Module Contents

class src.bluetooth_sig.advertising.base.AdvertisingDataInterpreter(mac_address: str, bindkey: bytes | None = None)

Bases: abc.ABC, Generic[T]

Base class for vendor-specific advertising data interpretation.

Interprets manufacturer_data and service_data from BLE advertisements into strongly-typed domain objects (sensor readings, device state, etc.).

Workflow:

  1. Registry routes advertisement to interpreter class via supports()

  2. Device creates/reuses interpreter instance per (mac_address, interpreter_type)

  3. interpreter.interpret() decodes payload, returns typed result

  4. Interpreter maintains internal state (counters, flags) across calls

Example

class BTHomeInterpreter(AdvertisingDataInterpreter[BTHomeData]):
_info = AdvertisingInterpreterInfo(

service_uuid=BluetoothUUID(“0000fcd2-0000-1000-8000-00805f9b34fb”), name=”BTHome”, data_source=DataSource.SERVICE,

)

@classmethod def supports(cls, manufacturer_data, service_data, local_name):

return “0000fcd2-0000-1000-8000-00805f9b34fb” in service_data

def interpret(self, manufacturer_data, service_data, local_name, rssi):

# Parse BTHome service data and return BTHomeData …

abstractmethod interpret(manufacturer_data: dict[int, bytes], service_data: dict[bluetooth_sig.types.uuid.BluetoothUUID, bytes], local_name: str | None, rssi: int) T

Interpret advertisement data and return typed result.

Parameters:
  • manufacturer_data – Company ID → payload bytes mapping

  • service_data – Service UUID → payload bytes mapping

  • local_name – Device local name (may contain protocol info)

  • rssi – Signal strength in dBm

Returns:

Typed result specific to this interpreter (e.g., SensorData)

classmethod supports(manufacturer_data: dict[int, bytes], service_data: dict[bluetooth_sig.types.uuid.BluetoothUUID, bytes], local_name: str | None) bool
Abstractmethod:

Check if this interpreter handles the advertisement.

Called by registry for fast routing. Should be a quick check based on company_id, service_uuid, or local_name pattern.

property bindkey: bytes | None

Encryption key for this device.

property info: AdvertisingInterpreterInfo

Interpreter metadata.

property mac_address: str

Device MAC address.

property state: dict[str, Any]

Return the protocol-specific state dictionary.

class src.bluetooth_sig.advertising.base.AdvertisingInterpreterInfo

Bases: msgspec.Struct

Interpreter metadata for routing and identification.

company_id: int | None = None
data_source: DataSource
name: str = ''
service_uuid: bluetooth_sig.types.uuid.BluetoothUUID | None = None
class src.bluetooth_sig.advertising.base.DataSource(*args, **kwds)

Bases: enum.Enum

Primary data source for interpreter routing.

LOCAL_NAME = 'local_name'
MANUFACTURER = 'manufacturer'
SERVICE = 'service'
src.bluetooth_sig.advertising.base.T