Coverage for src/bluetooth_sig/gatt/descriptors/valid_range.py: 100%
19 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-30 00:10 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-30 00:10 +0000
1"""Valid Range Descriptor implementation."""
3from __future__ import annotations
5import msgspec
7from ..characteristics.utils import DataParser
8from .base import BaseDescriptor, RangeDescriptorMixin
11class ValidRangeData(msgspec.Struct, frozen=True, kw_only=True):
12 """Valid Range descriptor data."""
14 min_value: int | float
15 max_value: int | float
18class ValidRangeDescriptor(BaseDescriptor, RangeDescriptorMixin):
19 """Valid Range Descriptor (0x2906).
21 Defines the valid range for characteristic values.
22 Contains minimum and maximum values for validation.
23 """
25 _descriptor_name = "Valid Range"
27 def _has_structured_data(self) -> bool:
28 return True
30 def _get_data_format(self) -> str:
31 return "struct"
33 def _parse_descriptor_value(self, data: bytes) -> ValidRangeData:
34 """Parse Valid Range descriptor value.
36 The format depends on the characteristic's value type.
37 For simplicity, this implementation assumes uint16 min/max values.
38 In practice, this should be adapted based on the characteristic's format.
40 Args:
41 data: Raw bytes containing min and max values
43 Returns:
44 ValidRangeData with min and max values
46 Raises:
47 ValueError: If data length is incorrect
48 """
49 # Valid Range format: min_value (same format as characteristic) + max_value
50 # For now, assume 4 bytes total (2 bytes min + 2 bytes max for uint16)
51 if len(data) != 4:
52 raise ValueError(f"Valid Range data expected 4 bytes, got {len(data)}")
54 min_value = DataParser.parse_int16(data, offset=0, endian="little")
55 max_value = DataParser.parse_int16(data, offset=2, endian="little")
57 return ValidRangeData(
58 min_value=min_value,
59 max_value=max_value,
60 )