Coverage for src / bluetooth_sig / gatt / descriptors / environmental_sensing_configuration.py: 78%
36 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 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 behaviour.
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 # Parse as little-endian uint16
61 value = DataParser.parse_int16(data, endian="little")
63 return EnvironmentalSensingConfigurationData(
64 trigger_logic_value=bool(value & ESCFlags.TRIGGER_LOGIC_VALUE),
65 transmission_interval_present=bool(value & ESCFlags.TRANSMISSION_INTERVAL_PRESENT),
66 measurement_period_present=bool(value & ESCFlags.MEASUREMENT_PERIOD_PRESENT),
67 update_interval_present=bool(value & ESCFlags.UPDATE_INTERVAL_PRESENT),
68 application_present=bool(value & ESCFlags.APPLICATION_PRESENT),
69 measurement_uncertainty_present=bool(value & ESCFlags.MEASUREMENT_UNCERTAINTY_PRESENT),
70 )
72 def has_trigger_logic_value(self, data: bytes) -> bool:
73 """Check if trigger logic value is present."""
74 parsed = self._parse_descriptor_value(data)
75 return parsed.trigger_logic_value
77 def has_transmission_interval(self, data: bytes) -> bool:
78 """Check if transmission interval is present."""
79 parsed = self._parse_descriptor_value(data)
80 return parsed.transmission_interval_present
82 def has_measurement_period(self, data: bytes) -> bool:
83 """Check if measurement period is present."""
84 parsed = self._parse_descriptor_value(data)
85 return parsed.measurement_period_present