Coverage for src/bluetooth_sig/gatt/characteristics/barometric_pressure_trend.py: 92%

37 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-10-30 00:10 +0000

1"""Barometric Pressure Trend characteristic implementation.""" 

2 

3from __future__ import annotations 

4 

5from enum import IntEnum 

6 

7from ..context import CharacteristicContext 

8from .base import BaseCharacteristic 

9from .templates import Uint8Template 

10 

11 

12class BarometricPressureTrend(IntEnum): 

13 """Barometric pressure trend enumeration.""" 

14 

15 UNKNOWN = 0 

16 CONTINUOUSLY_FALLING = 1 

17 CONTINUOUSLY_RISING = 2 

18 FALLING_THEN_STEADY = 3 

19 RISING_THEN_STEADY = 4 

20 FALLING_BEFORE_LESSER_RISE = 5 

21 FALLING_BEFORE_GREATER_RISE = 6 

22 RISING_BEFORE_GREATER_FALL = 7 

23 RISING_BEFORE_LESSER_FALL = 8 

24 STEADY = 9 

25 

26 def __str__(self) -> str: 

27 """Return human-readable description.""" 

28 descriptions = { 

29 0: "Unknown", 

30 1: "Continuously falling", 

31 2: "Continuously rising", 

32 3: "Falling, then steady", 

33 4: "Rising, then steady", 

34 5: "Falling before a lesser rise", 

35 6: "Falling before a greater rise", 

36 7: "Rising before a greater fall", 

37 8: "Rising before a lesser fall", 

38 9: "Steady", 

39 } 

40 return descriptions[self.value] 

41 

42 @classmethod 

43 def from_value(cls, value: int) -> BarometricPressureTrend: 

44 """Create enum from integer value with fallback to UNKNOWN.""" 

45 try: 

46 return cls(value) 

47 except ValueError: 

48 return cls.UNKNOWN 

49 

50 

51class BarometricPressureTrendCharacteristic(BaseCharacteristic): 

52 """Barometric Pressure Trend characteristic (0x2AA3). 

53 

54 org.bluetooth.characteristic.barometric_pressure_trend 

55 

56 Barometric pressure trend characteristic. 

57 

58 Represents the trend observed for barometric pressure using 

59 enumerated values. 

60 """ 

61 

62 _template = Uint8Template() # Used for base uint8 parsing, then converted to enum 

63 

64 # Manual override: YAML indicates uint8->int but we return enum 

65 _manual_value_type = "BarometricPressureTrend" 

66 

67 enum_class = BarometricPressureTrend 

68 

69 def decode_value(self, data: bytearray, ctx: CharacteristicContext | None = None) -> BarometricPressureTrend: 

70 """Parse barometric pressure trend and return enum. 

71 

72 Maps reserved value (0xFF) and invalid values to UNKNOWN. 

73 """ 

74 # Use template to parse uint8 

75 raw_value = self._template.decode_value(data, offset=0, ctx=ctx) 

76 # Convert to enum with fallback 

77 return BarometricPressureTrend.from_value(raw_value) 

78 

79 def encode_value(self, data: BarometricPressureTrend | int) -> bytearray: 

80 """Encode barometric pressure trend enum to bytes.""" 

81 if isinstance(data, BarometricPressureTrend): 

82 value = data.value 

83 else: 

84 value = int(data) 

85 return self._template.encode_value(value)