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
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-11 20:14 +0000
1"""Date of Threshold Assessment characteristic (0x2A86)."""
3from __future__ import annotations
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
12DateOfThresholdAssessmentData = DateData
15class DateOfThresholdAssessmentCharacteristic(BaseCharacteristic[DateOfThresholdAssessmentData]):
16 """Date of Threshold Assessment characteristic (0x2A86).
18 org.bluetooth.characteristic.date_of_threshold_assessment
20 Date of Threshold Assessment characteristic.
21 """
23 expected_length: int = 4 # Year(2) + Month(1) + Day(1)
25 def _decode_value(self, data: bytearray, ctx: CharacteristicContext | None = None) -> DateOfThresholdAssessmentData:
26 """Decode Date of Threshold Assessment from raw bytes.
28 Args:
29 data: Raw bytes from BLE characteristic (4 bytes)
30 ctx: Optional context for parsing
32 Returns:
33 DateOfThresholdAssessmentData with year, month, day
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)
41 # Year is uint16 (little-endian)
42 year = DataParser.parse_int16(data, 0, signed=False)
44 # Month is uint8
45 month = data[2]
47 # Day is uint8
48 day = data[3]
50 return DateOfThresholdAssessmentData(year=year, month=month, day=day)
52 def _encode_value(self, data: DateOfThresholdAssessmentData) -> bytearray:
53 """Encode Date of Threshold Assessment to bytes.
55 Args:
56 data: DateOfThresholdAssessmentData to encode
58 Returns:
59 Encoded bytes (4 bytes)
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)
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)
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)
76 result = bytearray()
78 # Encode year (uint16, little-endian)
79 result.extend(DataParser.encode_int16(data.year, signed=False))
81 # Encode month (uint8)
82 result.append(data.month)
84 # Encode day (uint8)
85 result.append(data.day)
87 return result