Coverage for src / bluetooth_sig / gatt / characteristics / appearance.py: 100%
16 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-18 11:17 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-18 11:17 +0000
1"""Appearance characteristic implementation."""
3from __future__ import annotations
5from ...registry.core.appearance_values import appearance_values_registry
6from ...types.appearance import AppearanceData
7from ...types.gatt_enums import CharacteristicRole
8from ..context import CharacteristicContext
9from .base import BaseCharacteristic
10from .utils import DataParser
13class AppearanceCharacteristic(BaseCharacteristic[AppearanceData]):
14 """Appearance characteristic (0x2A01).
16 org.bluetooth.characteristic.gap.appearance
18 Appearance characteristic with human-readable device type information.
19 """
21 _manual_role = CharacteristicRole.INFO
22 expected_length = 2
24 def _decode_value(
25 self, data: bytearray, ctx: CharacteristicContext | None = None, *, validate: bool = True
26 ) -> AppearanceData:
27 """Parse appearance value with human-readable info.
29 Args:
30 data: Raw bytearray from BLE characteristic (2 bytes).
31 ctx: Optional CharacteristicContext providing surrounding context (may be None).
32 validate: Whether to validate ranges (default True)
34 Returns:
35 AppearanceData with raw value and optional human-readable info.
36 """
37 raw_value = DataParser.parse_int16(data, 0, signed=False)
38 appearance_info = appearance_values_registry.get_appearance_info(raw_value)
40 return AppearanceData(
41 raw_value=raw_value,
42 info=appearance_info,
43 )
45 def _encode_value(self, data: AppearanceData) -> bytearray:
46 """Encode appearance value back to bytes.
48 Args:
49 data: Appearance value as AppearanceData
51 Returns:
52 Encoded bytes representing the appearance
53 """
54 return DataParser.encode_int16(data.raw_value, signed=False)