src.bluetooth_sig.core.translator

Core Bluetooth SIG standards translator functionality.

Attributes

Classes

Name

Description

BluetoothSIGTranslator

Pure Bluetooth SIG standards translator for characteristic and service interpretation.

Module Contents

class src.bluetooth_sig.core.translator.BluetoothSIGTranslator

Pure Bluetooth SIG standards translator for characteristic and service interpretation.

This class provides the primary API surface for Bluetooth SIG standards translation, covering characteristic parsing, service discovery, UUID resolution, and registry management.

Singleton Pattern:

This class is implemented as a singleton to provide a global registry for custom characteristics and services. Access the singleton instance using BluetoothSIGTranslator.get_instance() or the module-level translator variable.

Key features: - Parse raw BLE characteristic data using Bluetooth SIG specifications - Resolve UUIDs to [CharacteristicInfo][bluetooth_sig.types.CharacteristicInfo]

and [ServiceInfo][bluetooth_sig.types.ServiceInfo]

  • Create BaseGattService instances from service UUIDs

  • Access comprehensive registry of supported characteristics and services

Note: This class intentionally has >20 public methods as it serves as the primary API surface for Bluetooth SIG standards translation. The methods are organized by functionality and reducing them would harm API clarity.

clear_services() None

Clear all discovered services.

create_value(uuid: str, **kwargs: Any) Any

Create a properly typed value instance for a characteristic.

This is a convenience method that constructs the appropriate dataclass or value type for a characteristic, which can then be passed to encode_characteristic() or used directly.

Parameters:
  • uuid – The characteristic UUID

  • **kwargs – Field values for the characteristic’s type

Returns:

Properly typed value instance

Raises:
  • ValueError – If UUID is invalid or characteristic not found

  • TypeError – If kwargs don’t match the characteristic’s expected fields

Example

Create complex characteristic values:

from bluetooth_sig import BluetoothSIGTranslator

translator = BluetoothSIGTranslator()

# Create acceleration data
accel = translator.create_value("2C1D", x_axis=1.5, y_axis=0.5, z_axis=9.8)

# Encode and write
data = translator.encode_characteristic("2C1D", accel)
await client.write_gatt_char("2C1D", data)
encode_characteristic(char: type[src.bluetooth_sig.gatt.characteristics.base.BaseCharacteristic[T]], value: T, validate: bool = ...) bytes
encode_characteristic(char: str, value: Any, validate: bool = ...) bytes

Encode a value for writing to a characteristic.

Parameters:
  • char – Characteristic class (type-safe) or UUID string (not type-safe).

  • value – The value to encode. Type is checked when using characteristic class.

  • validate – If True, validates the value before encoding (default: True)

Returns:

Encoded bytes ready to write to the characteristic

Raises:

Example:

from bluetooth_sig import BluetoothSIGTranslator
from bluetooth_sig.gatt.characteristics import AlertLevelCharacteristic
from bluetooth_sig.gatt.characteristics.alert_level import AlertLevel

translator = BluetoothSIGTranslator()

# Type-safe: pass characteristic class and typed value
data: bytes = translator.encode_characteristic(AlertLevelCharacteristic, AlertLevel.HIGH)

# Not type-safe: pass UUID string
data = translator.encode_characteristic("2A06", 2)
async encode_characteristic_async(uuid: str | src.bluetooth_sig.types.uuid.BluetoothUUID, value: Any, validate: bool = True) bytes

Encode characteristic value in an async-compatible manner.

This is an async wrapper that allows characteristic encoding to be used in async contexts. The actual encoding is performed synchronously as it’s a fast, CPU-bound operation that doesn’t benefit from async I/O.

Parameters:
  • uuid – The characteristic UUID (string or BluetoothUUID)

  • value – The value to encode (dataclass, dict, or primitive)

  • validate – If True, validates before encoding (default: True)

Returns:

Encoded bytes ready to write

Example:

async with BleakClient(address) as client:
    data = await translator.encode_characteristic_async("2A19", 85)
    await client.write_gatt_char("2A19", data)
get_characteristic_info_by_name(name: src.bluetooth_sig.types.gatt_enums.CharacteristicName) src.bluetooth_sig.types.CharacteristicInfo | None

Get characteristic info by enum name.

Parameters:

name – CharacteristicName enum

Returns:

CharacteristicInfo if found, None otherwise

get_characteristic_info_by_uuid(uuid: str) src.bluetooth_sig.types.CharacteristicInfo | None

Get information about a characteristic by UUID.

Retrieve metadata for a Bluetooth characteristic using its UUID. This includes the characteristic’s name, description, value type, unit, and properties.

Parameters:

uuid – The characteristic UUID (16-bit short form or full 128-bit)

Returns:

[CharacteristicInfo][bluetooth_sig.CharacteristicInfo] with metadata or None if not found

Example

Get battery level characteristic info:

from bluetooth_sig import BluetoothSIGTranslator

translator = BluetoothSIGTranslator()
info = translator.get_characteristic_info_by_uuid("2A19")
if info:
    print(f"Name: {info.name}")  # Name: Battery Level
get_characteristic_uuid_by_name(name: src.bluetooth_sig.types.gatt_enums.CharacteristicName) src.bluetooth_sig.types.uuid.BluetoothUUID | None

Get the UUID for a characteristic name enum.

Parameters:

name – CharacteristicName enum

Returns:

Characteristic UUID or None if not found

get_characteristics_info_by_uuids(uuids: list[str]) dict[str, src.bluetooth_sig.types.CharacteristicInfo | None]

Get information about multiple characteristics by UUID.

Parameters:

uuids – List of characteristic UUIDs

Returns:

Dictionary mapping UUIDs to CharacteristicInfo (or None if not found)

classmethod get_instance() BluetoothSIGTranslator

Get the singleton instance of BluetoothSIGTranslator.

Returns:

The singleton BluetoothSIGTranslator instance

Example:

from bluetooth_sig import BluetoothSIGTranslator

# Get the singleton instance
translator = BluetoothSIGTranslator.get_instance()
get_service_by_uuid(uuid: str) src.bluetooth_sig.gatt.services.base.BaseGattService | None

Get a service instance by UUID.

Parameters:

uuid – The service UUID

Returns:

Service instance if found, None otherwise

get_service_characteristics(service_uuid: str) list[str]

Get the characteristic UUIDs associated with a service.

Parameters:

service_uuid – The service UUID

Returns:

List of characteristic UUIDs for this service

get_service_info_by_name(name: str) src.bluetooth_sig.types.ServiceInfo | None

Get service info by name instead of UUID.

Parameters:

name – Service name

Returns:

ServiceInfo if found, None otherwise

get_service_info_by_uuid(uuid: str) src.bluetooth_sig.types.ServiceInfo | None

Get information about a service by UUID.

Parameters:

uuid – The service UUID

Returns:

ServiceInfo with metadata or None if not found

get_service_uuid_by_name(name: str | src.bluetooth_sig.gatt.services.ServiceName) src.bluetooth_sig.types.uuid.BluetoothUUID | None

Get the UUID for a service name or enum.

Parameters:

name – Service name or enum

Returns:

Service UUID or None if not found

get_sig_info_by_name(name: str) src.bluetooth_sig.types.SIGInfo | None

Get Bluetooth SIG information for a characteristic or service by name.

Parameters:

name – Characteristic or service name

Returns:

CharacteristicInfo or ServiceInfo if found, None otherwise

get_sig_info_by_uuid(uuid: str) src.bluetooth_sig.types.SIGInfo | None

Get Bluetooth SIG information for a UUID.

Parameters:

uuid – UUID string (with or without dashes)

Returns:

CharacteristicInfo or ServiceInfo if found, None otherwise

get_value_type(uuid: str) src.bluetooth_sig.types.gatt_enums.ValueType | None

Get the expected value type for a characteristic.

Retrieves the ValueType enum indicating what type of data this characteristic produces (int, float, string, bytes, etc.).

Parameters:

uuid – The characteristic UUID (16-bit short form or full 128-bit)

Returns:

ValueType enum if characteristic is found, None otherwise

Example

Check what type a characteristic returns:

from bluetooth_sig import BluetoothSIGTranslator

translator = BluetoothSIGTranslator()
value_type = translator.get_value_type("2A19")
print(value_type)  # ValueType.INT
list_supported_characteristics() dict[str, str]

List all supported characteristics with their names and UUIDs.

Returns:

Dictionary mapping characteristic names to UUIDs

list_supported_services() dict[str, str]

List all supported services with their names and UUIDs.

Returns:

Dictionary mapping service names to UUIDs

parse_characteristic(char: type[src.bluetooth_sig.gatt.characteristics.base.BaseCharacteristic[T]], raw_data: bytes | bytearray, ctx: src.bluetooth_sig.types.CharacteristicContext | None = ...) T
parse_characteristic(char: str, raw_data: bytes | bytearray, ctx: src.bluetooth_sig.types.CharacteristicContext | None = ...) Any

Parse a characteristic’s raw data using Bluetooth SIG standards.

Parameters:
  • char – Characteristic class (type-safe) or UUID string (not type-safe).

  • raw_data – Raw bytes from the characteristic (bytes or bytearray)

  • ctx – Optional CharacteristicContext providing device-level info

Returns:

Parsed value. Return type is inferred when passing characteristic class.

  • Primitives: int, float, str, bool

  • Dataclasses: NavigationData, HeartRateMeasurement, etc.

  • Special values: SpecialValueResult (via exception)

Raises:

Example:

from bluetooth_sig import BluetoothSIGTranslator
from bluetooth_sig.gatt.characteristics import BatteryLevelCharacteristic

translator = BluetoothSIGTranslator()

# Type-safe: pass characteristic class, return type is inferred
level: int = translator.parse_characteristic(BatteryLevelCharacteristic, b"\\x64")

# Not type-safe: pass UUID string, returns Any
value = translator.parse_characteristic("2A19", b"\\x64")
async parse_characteristic_async(char: type[src.bluetooth_sig.gatt.characteristics.base.BaseCharacteristic[T]], raw_data: bytes, ctx: src.bluetooth_sig.types.CharacteristicContext | None = ...) T
async parse_characteristic_async(char: str | src.bluetooth_sig.types.uuid.BluetoothUUID, raw_data: bytes, ctx: src.bluetooth_sig.types.CharacteristicContext | None = ...) Any

Parse characteristic data in an async-compatible manner.

This is an async wrapper that allows characteristic parsing to be used in async contexts. The actual parsing is performed synchronously as it’s a fast, CPU-bound operation that doesn’t benefit from async I/O.

Parameters:
  • char – Characteristic class (type-safe) or UUID string/BluetoothUUID (not type-safe).

  • raw_data – Raw bytes from the characteristic

  • ctx – Optional context providing device-level info

Returns:

Parsed value. Return type is inferred when passing characteristic class.

Raises:

Example:

async with BleakClient(address) as client:
    data = await client.read_gatt_char("2A19")

    # Type-safe: pass characteristic class
    from bluetooth_sig.gatt.characteristics import BatteryLevelCharacteristic

    level: int = await translator.parse_characteristic_async(BatteryLevelCharacteristic, data)

    # Not type-safe: pass UUID string
    value = await translator.parse_characteristic_async("2A19", data)
parse_characteristics(char_data: dict[str, bytes], ctx: src.bluetooth_sig.types.CharacteristicContext | None = None) dict[str, Any]

Parse multiple characteristics at once with dependency-aware ordering.

This method automatically handles multi-characteristic dependencies by parsing independent characteristics first, then parsing characteristics that depend on them. The parsing order is determined by the required_dependencies and optional_dependencies attributes declared on characteristic classes.

Required dependencies MUST be present and successfully parsed; missing required dependencies result in parse failure with MissingDependencyError. Optional dependencies enrich parsing when available but are not mandatory.

Parameters:
  • char_data – Dictionary mapping UUIDs to raw data bytes

  • ctx – Optional CharacteristicContext used as the starting context

Returns:

Dictionary mapping UUIDs to parsed values

Raises:

Example

Parse multiple environmental characteristics:

from bluetooth_sig import BluetoothSIGTranslator

translator = BluetoothSIGTranslator()
data = {
    "2A6E": b"\\x0A\\x00",  # Temperature
    "2A6F": b"\\x32\\x00",  # Humidity
}
try:
    results = translator.parse_characteristics(data)
    for uuid, value in results.items():
        print(f"{uuid}: {value}")
except CharacteristicParseError as e:
    print(f"Parse failed: {e}")
async parse_characteristics_async(char_data: dict[str, bytes], ctx: src.bluetooth_sig.types.CharacteristicContext | None = None) dict[str, Any]

Parse multiple characteristics in an async-compatible manner.

This is an async wrapper for batch characteristic parsing. The parsing is performed synchronously as it’s a fast, CPU-bound operation. This method allows batch parsing to be used naturally in async workflows.

Parameters:
  • char_data – Dictionary mapping UUIDs to raw data bytes

  • ctx – Optional context

Returns:

Dictionary mapping UUIDs to parsed values

Example:

async with BleakClient(address) as client:
    # Read multiple characteristics
    char_data = {}
    for uuid in ["2A19", "2A6E", "2A6F"]:
        char_data[uuid] = await client.read_gatt_char(uuid)

    # Parse all asynchronously
    results = await translator.parse_characteristics_async(char_data)
    for uuid, value in results.items():
        print(f"{uuid}: {value}")
process_services(services: dict[str, dict[str, CharacteristicDataDict]]) None

Process discovered services and their characteristics.

Parameters:

services – Dictionary of service UUIDs to their characteristics

register_custom_characteristic_class(uuid_or_name: str, cls: type[src.bluetooth_sig.gatt.characteristics.base.BaseCharacteristic[Any]], info: src.bluetooth_sig.types.CharacteristicInfo | None = None, override: bool = False) None

Register a custom characteristic class at runtime.

Parameters:
  • uuid_or_name – The characteristic UUID or name

  • cls – The characteristic class to register

  • info – Optional CharacteristicInfo with metadata (name, unit, value_type)

  • override – Whether to override existing registrations

Raises:
  • TypeError – If cls does not inherit from BaseCharacteristic

  • ValueError – If UUID conflicts with existing registration and override=False

Example:

from bluetooth_sig import BluetoothSIGTranslator, CharacteristicInfo, ValueType
from bluetooth_sig.types import BluetoothUUID

translator = BluetoothSIGTranslator()
info = CharacteristicInfo(
    uuid=BluetoothUUID("12345678-1234-1234-1234-123456789abc"),
    name="Custom Temperature",
    unit="°C",
    value_type=ValueType.FLOAT,
)
translator.register_custom_characteristic_class(str(info.uuid), MyCustomCharacteristic, info=info)
register_custom_service_class(uuid_or_name: str, cls: type[src.bluetooth_sig.gatt.services.base.BaseGattService], info: src.bluetooth_sig.types.ServiceInfo | None = None, override: bool = False) None

Register a custom service class at runtime.

Parameters:
  • uuid_or_name – The service UUID or name

  • cls – The service class to register

  • info – Optional ServiceInfo with metadata (name)

  • override – Whether to override existing registrations

Raises:
  • TypeError – If cls does not inherit from BaseGattService

  • ValueError – If UUID conflicts with existing registration and override=False

Example:

from bluetooth_sig import BluetoothSIGTranslator, ServiceInfo
from bluetooth_sig.types import BluetoothUUID

translator = BluetoothSIGTranslator()
info = ServiceInfo(uuid=BluetoothUUID("12345678-1234-1234-1234-123456789abc"), name="Custom Service")
translator.register_custom_service_class(str(info.uuid), MyCustomService, info=info)
supports(uuid: str) bool

Check if a characteristic UUID is supported.

Parameters:

uuid – The characteristic UUID to check

Returns:

True if the characteristic has a parser/encoder, False otherwise

Example

Check if characteristic is supported:

from bluetooth_sig import BluetoothSIGTranslator

translator = BluetoothSIGTranslator()
if translator.supports("2A19"):
    result = translator.parse_characteristic("2A19", data)
validate_characteristic_data(uuid: str, data: bytes) src.bluetooth_sig.types.ValidationResult

Validate characteristic data format against SIG specifications.

Parameters:
  • uuid – The characteristic UUID

  • data – Raw data bytes to validate

Returns:

ValidationResult with validation details

property discovered_services: list[src.bluetooth_sig.gatt.services.base.BaseGattService]

Get list of discovered service instances.

Returns:

List of discovered service instances

src.bluetooth_sig.core.translator.BluetoothSIG
src.bluetooth_sig.core.translator.CharacteristicDataDict
src.bluetooth_sig.core.translator.T
src.bluetooth_sig.core.translator.logger