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

1"""Special value types for GATT characteristic parsing. 

2 

3Special values are reserved raw integer values that indicate 

4exceptional conditions like "unknown", "invalid", "overflow", etc. 

5rather than actual measured data. 

6 

7Pipeline integration: 

8 bytes → extract_raw() → check_special() → translate() → result 

9 ↓ short-circuit 

10 SpecialValueResult 

11 

12When a special value is detected, the pipeline short-circuits and 

13returns a SpecialValueResult instead of translating the raw value. 

14""" 

15 

16from __future__ import annotations 

17 

18import msgspec 

19 

20from .units import SpecialValueType 

21 

22 

23class SpecialValueRule(msgspec.Struct, frozen=True, kw_only=True): 

24 """A rule matching a raw value to its special meaning. 

25 

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 

31 

32 """ 

33 

34 raw_value: int 

35 meaning: str 

36 value_type: SpecialValueType = SpecialValueType.UNKNOWN 

37 threshold: float | None = None 

38 

39 def to_result(self) -> SpecialValueResult: 

40 """Convert rule to a result when matched. 

41 

42 Returns: 

43 SpecialValueResult with this rule's values 

44 

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 ) 

52 

53 

54class SpecialValueResult(msgspec.Struct, frozen=True, kw_only=True): 

55 """Result when a special value is detected during parsing. 

56 

57 Contains the raw value that was detected, its meaning, type, 

58 and optionally a threshold value for overflow/underflow cases. 

59 

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 

65 

66 """ 

67 

68 raw_value: int 

69 meaning: str 

70 value_type: SpecialValueType 

71 threshold: float | None = None 

72 

73 @property 

74 def effective_value(self) -> float | None: 

75 """Return threshold for overflow/underflow, None otherwise. 

76 

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. 

80 

81 Returns: 

82 Threshold value for overflow/underflow, None for other types 

83 

84 """ 

85 if self.value_type in (SpecialValueType.OVERFLOW, SpecialValueType.UNDERFLOW): 

86 return self.threshold 

87 return None 

88 

89 

90__all__ = [ 

91 "SpecialValueRule", 

92 "SpecialValueResult", 

93]