Coverage for src / bluetooth_sig / types / special_values.py: 86%
21 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"""Special value types for GATT characteristic parsing.
3Special values are reserved raw integer values that indicate
4exceptional conditions like "unknown", "invalid", "overflow", etc.
5rather than actual measured data.
7Pipeline integration:
8 bytes → extract_raw() → check_special() → translate() → result
9 ↓ short-circuit
10 SpecialValueResult
12When a special value is detected, the pipeline short-circuits and
13returns a SpecialValueResult instead of translating the raw value.
14"""
16from __future__ import annotations
18import msgspec
20from .units import SpecialValueType
23class SpecialValueRule(msgspec.Struct, frozen=True, kw_only=True):
24 """A rule matching a raw value to its special meaning.
26 Field descriptions:
27 raw_value: The raw integer that triggers this rule
28 meaning: Human-readable description (e.g., "Value is unknown")
29 value_type: Category of special value
30 threshold: For OVERFLOW/UNDERFLOW, the boundary value to return
32 """
34 raw_value: int
35 meaning: str
36 value_type: SpecialValueType = SpecialValueType.UNKNOWN
37 threshold: float | None = None
39 def to_result(self) -> SpecialValueResult:
40 """Convert rule to a result when matched.
42 Returns:
43 SpecialValueResult with this rule's values
45 """
46 return SpecialValueResult(
47 raw_value=self.raw_value,
48 meaning=self.meaning,
49 value_type=self.value_type,
50 threshold=self.threshold,
51 )
54class SpecialValueResult(msgspec.Struct, frozen=True, kw_only=True):
55 """Result when a special value is detected during parsing.
57 Contains the raw value that was detected, its meaning, type,
58 and optionally a threshold value for overflow/underflow cases.
60 Field descriptions:
61 raw_value: The raw integer that triggered the special value
62 meaning: Human-readable description
63 value_type: Category of special value
64 threshold: For OVERFLOW/UNDERFLOW, the boundary value
66 """
68 raw_value: int
69 meaning: str
70 value_type: SpecialValueType
71 threshold: float | None = None
73 @property
74 def effective_value(self) -> float | None:
75 """Return threshold for overflow/underflow, None otherwise.
77 For OVERFLOW/UNDERFLOW special values, returns the threshold
78 as a meaningful boundary value. For other types, returns None
79 since the value doesn't represent actual data.
81 Returns:
82 Threshold value for overflow/underflow, None for other types
84 """
85 if self.value_type in (SpecialValueType.OVERFLOW, SpecialValueType.UNDERFLOW):
86 return self.threshold
87 return None
90__all__ = [
91 "SpecialValueRule",
92 "SpecialValueResult",
93]