Coverage for src / bluetooth_sig / gatt / characteristics / date_of_threshold_assessment.py: 86%

29 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-11 20:14 +0000

1"""Date of Threshold Assessment characteristic (0x2A86).""" 

2 

3from __future__ import annotations 

4 

5from ...types import DateData 

6from ..context import CharacteristicContext 

7from ..exceptions import InsufficientDataError, ValueRangeError 

8from .base import BaseCharacteristic 

9from .utils import DataParser 

10from .utils.ieee11073_parser import IEEE11073Parser 

11 

12DateOfThresholdAssessmentData = DateData 

13 

14 

15class DateOfThresholdAssessmentCharacteristic(BaseCharacteristic[DateOfThresholdAssessmentData]): 

16 """Date of Threshold Assessment characteristic (0x2A86). 

17 

18 org.bluetooth.characteristic.date_of_threshold_assessment 

19 

20 Date of Threshold Assessment characteristic. 

21 """ 

22 

23 expected_length: int = 4 # Year(2) + Month(1) + Day(1) 

24 

25 def _decode_value(self, data: bytearray, ctx: CharacteristicContext | None = None) -> DateOfThresholdAssessmentData: 

26 """Decode Date of Threshold Assessment from raw bytes. 

27 

28 Args: 

29 data: Raw bytes from BLE characteristic (4 bytes) 

30 ctx: Optional context for parsing 

31 

32 Returns: 

33 DateOfThresholdAssessmentData with year, month, day 

34 

35 Raises: 

36 InsufficientDataError: If data length is not exactly 4 bytes 

37 """ 

38 if len(data) != 4: 

39 raise InsufficientDataError("Date of Threshold Assessment", data, 4) 

40 

41 # Year is uint16 (little-endian) 

42 year = DataParser.parse_int16(data, 0, signed=False) 

43 

44 # Month is uint8 

45 month = data[2] 

46 

47 # Day is uint8 

48 day = data[3] 

49 

50 return DateOfThresholdAssessmentData(year=year, month=month, day=day) 

51 

52 def _encode_value(self, data: DateOfThresholdAssessmentData) -> bytearray: 

53 """Encode Date of Threshold Assessment to bytes. 

54 

55 Args: 

56 data: DateOfThresholdAssessmentData to encode 

57 

58 Returns: 

59 Encoded bytes (4 bytes) 

60 

61 Raises: 

62 ValueRangeError: If year, month, or day are out of valid range 

63 """ 

64 # Validate year 

65 if not ((data.year == 0) or (IEEE11073Parser.IEEE11073_MIN_YEAR <= data.year <= 9999)): 

66 raise ValueRangeError("year", data.year, IEEE11073Parser.IEEE11073_MIN_YEAR, 9999) 

67 

68 # Validate month 

69 if not ((data.month == 0) or (IEEE11073Parser.MONTH_MIN <= data.month <= IEEE11073Parser.MONTH_MAX)): 

70 raise ValueRangeError("month", data.month, IEEE11073Parser.MONTH_MIN, IEEE11073Parser.MONTH_MAX) 

71 

72 # Validate day 

73 if not ((data.day == 0) or (IEEE11073Parser.DAY_MIN <= data.day <= IEEE11073Parser.DAY_MAX)): 

74 raise ValueRangeError("day", data.day, IEEE11073Parser.DAY_MIN, IEEE11073Parser.DAY_MAX) 

75 

76 result = bytearray() 

77 

78 # Encode year (uint16, little-endian) 

79 result.extend(DataParser.encode_int16(data.year, signed=False)) 

80 

81 # Encode month (uint8) 

82 result.append(data.month) 

83 

84 # Encode day (uint8) 

85 result.append(data.day) 

86 

87 return result