Coverage for src / bluetooth_sig / types / registry / appearance_info.py: 100%
14 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"""Appearance information data structures.
3This module contains only the data structures for appearance values,
4with no dependencies on the registry system. This allows the registry
5to import these types without creating circular dependencies.
6"""
8from __future__ import annotations
10import msgspec
13class AppearanceSubcategoryInfo(msgspec.Struct, frozen=True, kw_only=True):
14 """Decoded appearance subcategory information.
16 Attributes:
17 name: Human-readable subcategory name (e.g., "Heart Rate Belt")
18 value: Subcategory value (0-63)
19 """
21 name: str
22 value: int
25class AppearanceInfo(msgspec.Struct, frozen=True, kw_only=True):
26 """Decoded appearance information from registry.
28 The 16-bit appearance value encodes device type information:
29 - Bits 15-6 (10 bits): Category value (0-1023)
30 - Bits 5-0 (6 bits): Subcategory value (0-63)
31 - Full code = (category << 6) | subcategory
33 Attributes:
34 category: Human-readable device category name (e.g., "Heart Rate Sensor")
35 category_value: Category value (upper 10 bits of appearance code)
36 subcategory: Optional subcategory information (e.g., "Heart Rate Belt")
37 """
39 category: str
40 category_value: int
41 subcategory: AppearanceSubcategoryInfo | None = None
43 @property
44 def full_name(self) -> str:
45 """Get full appearance name.
47 Returns:
48 Full name with category and optional subcategory
49 (e.g., "Heart Rate Sensor: Heart Rate Belt" or "Phone")
50 """
51 if self.subcategory:
52 return f"{self.category}: {self.subcategory.name}"
53 return self.category