Coverage for src / bluetooth_sig / gatt / descriptors / environmental_sensing_measurement.py: 62%
32 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"""Environmental Sensing Measurement Descriptor implementation."""
3from __future__ import annotations
5import msgspec
7from ..characteristics.utils import DataParser
8from .base import BaseDescriptor
11class EnvironmentalSensingMeasurementData(msgspec.Struct, frozen=True, kw_only=True):
12 """Environmental Sensing Measurement descriptor data."""
14 sampling_function: int
15 measurement_period: int
16 update_interval: int
17 application: int
18 measurement_uncertainty: int
21class EnvironmentalSensingMeasurementDescriptor(BaseDescriptor):
22 """Environmental Sensing Measurement Descriptor (0x290C).
24 Contains measurement parameters for environmental sensors.
25 Includes sampling function, measurement period, and other parameters.
26 """
28 def _has_structured_data(self) -> bool:
29 return True
31 def _get_data_format(self) -> str:
32 return "struct"
34 def _parse_descriptor_value(self, data: bytes) -> EnvironmentalSensingMeasurementData:
35 """Parse Environmental Sensing Measurement value.
37 Format: 12 bytes
38 - Sampling Function (3 bytes, uint24) - using uint32 for simplicity
39 - Measurement Period (3 bytes, uint24) - using uint32 for simplicity
40 - Update Interval (3 bytes, uint24) - using uint32 for simplicity
41 - Application (1 byte)
42 - Measurement Uncertainty (2 bytes, uint16)
44 Args:
45 data: Raw bytes (should be 12 bytes)
47 Returns:
48 EnvironmentalSensingMeasurementData with measurement parameters
50 Raises:
51 ValueError: If data is not exactly 12 bytes
52 """
53 # For simplicity, treat uint24 values as uint32 (they'll fit)
54 return EnvironmentalSensingMeasurementData(
55 sampling_function=DataParser.parse_int32(data, offset=0, endian="little") & 0xFFFFFF,
56 measurement_period=DataParser.parse_int32(data, offset=3, endian="little") & 0xFFFFFF,
57 update_interval=DataParser.parse_int32(data, offset=6, endian="little") & 0xFFFFFF,
58 application=DataParser.parse_int8(data, offset=9),
59 measurement_uncertainty=DataParser.parse_int16(data, offset=10, endian="little"),
60 )
62 def get_sampling_function(self, data: bytes) -> int:
63 """Get the sampling function."""
64 parsed = self._parse_descriptor_value(data)
65 return parsed.sampling_function
67 def get_measurement_period(self, data: bytes) -> int:
68 """Get the measurement period."""
69 parsed = self._parse_descriptor_value(data)
70 return parsed.measurement_period
72 def get_update_interval(self, data: bytes) -> int:
73 """Get the update interval."""
74 parsed = self._parse_descriptor_value(data)
75 return parsed.update_interval
77 def get_application(self, data: bytes) -> int:
78 """Get the application identifier."""
79 parsed = self._parse_descriptor_value(data)
80 return parsed.application
82 def get_measurement_uncertainty(self, data: bytes) -> int:
83 """Get the measurement uncertainty."""
84 parsed = self._parse_descriptor_value(data)
85 return parsed.measurement_uncertainty