Coverage for src/bluetooth_sig/gatt/descriptors/environmental_sensing_configuration.py: 84%
38 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"""Environmental Sensing Configuration Descriptor implementation."""
3from __future__ import annotations
5from enum import IntFlag
7import msgspec
9from ..characteristics.utils import DataParser
10from .base import BaseDescriptor
13class ESCFlags(IntFlag):
14 """ESC (Environmental Sensing Configuration) flags."""
16 TRIGGER_LOGIC_VALUE = 0x0001
17 TRANSMISSION_INTERVAL_PRESENT = 0x0002
18 MEASUREMENT_PERIOD_PRESENT = 0x0004
19 UPDATE_INTERVAL_PRESENT = 0x0008
20 APPLICATION_PRESENT = 0x0010
21 MEASUREMENT_UNCERTAINTY_PRESENT = 0x0020
24class EnvironmentalSensingConfigurationData(msgspec.Struct, frozen=True, kw_only=True):
25 """Environmental Sensing Configuration descriptor data."""
27 trigger_logic_value: bool
28 transmission_interval_present: bool
29 measurement_period_present: bool
30 update_interval_present: bool
31 application_present: bool
32 measurement_uncertainty_present: bool
35class EnvironmentalSensingConfigurationDescriptor(BaseDescriptor):
36 """Environmental Sensing Configuration Descriptor (0x290B).
38 Configures environmental sensing measurement parameters.
39 Contains various configuration flags for sensor behavior.
40 """
42 def _has_structured_data(self) -> bool:
43 return True
45 def _get_data_format(self) -> str:
46 return "uint16"
48 def _parse_descriptor_value(self, data: bytes) -> EnvironmentalSensingConfigurationData:
49 """Parse Environmental Sensing Configuration value.
51 Args:
52 data: Raw bytes (should be 2 bytes for uint16)
54 Returns:
55 EnvironmentalSensingConfigurationData with configuration flags
57 Raises:
58 ValueError: If data is not exactly 2 bytes
59 """
60 if len(data) != 2:
61 raise ValueError(f"Environmental Sensing Configuration data must be exactly 2 bytes, got {len(data)}")
63 # Parse as little-endian uint16
64 value = DataParser.parse_int16(data, endian="little")
66 return EnvironmentalSensingConfigurationData(
67 trigger_logic_value=bool(value & ESCFlags.TRIGGER_LOGIC_VALUE),
68 transmission_interval_present=bool(value & ESCFlags.TRANSMISSION_INTERVAL_PRESENT),
69 measurement_period_present=bool(value & ESCFlags.MEASUREMENT_PERIOD_PRESENT),
70 update_interval_present=bool(value & ESCFlags.UPDATE_INTERVAL_PRESENT),
71 application_present=bool(value & ESCFlags.APPLICATION_PRESENT),
72 measurement_uncertainty_present=bool(value & ESCFlags.MEASUREMENT_UNCERTAINTY_PRESENT),
73 )
75 def has_trigger_logic_value(self, data: bytes) -> bool:
76 """Check if trigger logic value is present."""
77 parsed = self._parse_descriptor_value(data)
78 return parsed.trigger_logic_value
80 def has_transmission_interval(self, data: bytes) -> bool:
81 """Check if transmission interval is present."""
82 parsed = self._parse_descriptor_value(data)
83 return parsed.transmission_interval_present
85 def has_measurement_period(self, data: bytes) -> bool:
86 """Check if measurement period is present."""
87 parsed = self._parse_descriptor_value(data)
88 return parsed.measurement_period_present