Coverage for src / bluetooth_sig / gatt / characteristics / date_of_threshold_assessment.py: 90%
30 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-18 11:17 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-18 11:17 +0000
1"""Date of Threshold Assessment characteristic (0x2A86)."""
3from __future__ import annotations
5from ...types import DateData
6from ..constants import MAX_YEAR_VALUE
7from ..context import CharacteristicContext
8from ..exceptions import ValueRangeError
9from .base import BaseCharacteristic
10from .utils import DataParser
11from .utils.ieee11073_parser import IEEE11073Parser
13DateOfThresholdAssessmentData = DateData
16class DateOfThresholdAssessmentCharacteristic(BaseCharacteristic[DateOfThresholdAssessmentData]):
17 """Date of Threshold Assessment characteristic (0x2A86).
19 org.bluetooth.characteristic.date_of_threshold_assessment
21 Date of Threshold Assessment characteristic.
22 """
24 expected_length: int = 4 # Year(2) + Month(1) + Day(1)
25 min_length: int = 4
26 max_length: int = 4
28 def _decode_value(
29 self, data: bytearray, ctx: CharacteristicContext | None = None, *, validate: bool = True
30 ) -> DateOfThresholdAssessmentData:
31 """Decode Date of Threshold Assessment from raw bytes.
33 Args:
34 data: Raw bytes from BLE characteristic (4 bytes)
35 ctx: Optional context for parsing
36 validate: Whether to validate ranges (default True)
38 Returns:
39 DateOfThresholdAssessmentData with year, month, day
41 Raises:
42 InsufficientDataError: If data length is not exactly 4 bytes
43 """
44 year = DataParser.parse_int16(data, 0, signed=False)
46 # Month is uint8
47 month = data[2]
49 # Day is uint8
50 day = data[3]
52 return DateOfThresholdAssessmentData(year=year, month=month, day=day)
54 def _encode_value(self, data: DateOfThresholdAssessmentData) -> bytearray:
55 """Encode Date of Threshold Assessment to bytes.
57 Args:
58 data: DateOfThresholdAssessmentData to encode
60 Returns:
61 Encoded bytes (4 bytes)
63 Raises:
64 ValueRangeError: If year, month, or day are out of valid range
65 """
66 # Validate year
67 if not ((data.year == 0) or (IEEE11073Parser.IEEE11073_MIN_YEAR <= data.year <= MAX_YEAR_VALUE)):
68 raise ValueRangeError("year", data.year, IEEE11073Parser.IEEE11073_MIN_YEAR, MAX_YEAR_VALUE)
70 # Validate month
71 if not ((data.month == 0) or (IEEE11073Parser.MONTH_MIN <= data.month <= IEEE11073Parser.MONTH_MAX)):
72 raise ValueRangeError("month", data.month, IEEE11073Parser.MONTH_MIN, IEEE11073Parser.MONTH_MAX)
74 # Validate day
75 if not ((data.day == 0) or (IEEE11073Parser.DAY_MIN <= data.day <= IEEE11073Parser.DAY_MAX)):
76 raise ValueRangeError("day", data.day, IEEE11073Parser.DAY_MIN, IEEE11073Parser.DAY_MAX)
78 result = bytearray()
80 # Encode year (uint16, little-endian)
81 result.extend(DataParser.encode_int16(data.year, signed=False))
83 # Encode month (uint8)
84 result.append(data.month)
86 # Encode day (uint8)
87 result.append(data.day)
89 return result