Coverage for src / bluetooth_sig / types / io.py: 58%
19 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-11 20:14 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-11 20:14 +0000
1"""Typed containers for staging raw BLE I/O into the translator.
3These structs model common outputs from BLE connection managers (e.g., Bleak,
4SimpleBLE) and provide a convenient way to feed raw bytes into the
5`BluetoothSIGTranslator` batch parser, including descriptor bytes when
6available.
7"""
9from __future__ import annotations
11import msgspec
13from .uuid import BluetoothUUID
16class RawCharacteristicRead(msgspec.Struct, kw_only=True):
17 """Container for a single characteristic read.
19 This type is convenient for users to stage raw values coming from their BLE
20 connection manager (e.g. Bleak, SimpleBLE) before handing them to the
21 translator. It models the common shape produced by those libraries:
23 - `uuid`: characteristic UUID (short or full form)
24 - `raw_data`: bytes value as returned by `read_gatt_char`/notification
25 - `descriptors`: optional mapping of descriptor UUID -> raw bytes (if read)
26 - `properties`: optional list of characteristic properties (e.g. "read",
27 "notify"). These are currently informational for the parser.
28 """
30 uuid: BluetoothUUID | str
31 raw_data: bytes
32 descriptors: dict[str, bytes] = msgspec.field(default_factory=dict)
33 properties: list[str] = msgspec.field(default_factory=list)
36class RawCharacteristicBatch(msgspec.Struct, kw_only=True):
37 """A batch of raw characteristic reads to be parsed together.
39 Use this when you have multiple related characteristics (e.g., Glucose
40 Measurement + Glucose Measurement Context). The translator can parse them in
41 dependency-aware order.
42 """
44 items: list[RawCharacteristicRead]
47def to_parse_inputs(
48 batch: RawCharacteristicBatch,
49) -> tuple[dict[str, bytes], dict[str, dict[str, bytes]]]:
50 """Convert a :class:`RawCharacteristicBatch` to translator inputs.
52 Returns a tuple of `(char_data, descriptor_data)` suitable for
53 `BluetoothSIGTranslator.parse_characteristics(char_data, descriptor_data=...)`.
55 - `char_data` is a mapping of UUID -> raw bytes
56 - `descriptor_data` is a nested mapping of char UUID -> (descriptor UUID -> raw bytes)
57 """
58 char_data: dict[str, bytes] = {}
59 descriptor_data: dict[str, dict[str, bytes]] = {}
61 for item in batch.items:
62 uuid_str = str(item.uuid)
63 char_data[uuid_str] = item.raw_data
64 if item.descriptors:
65 descriptor_data[uuid_str] = dict(item.descriptors)
67 return char_data, descriptor_data