Coverage for src / bluetooth_sig / gatt / characteristics / battery_critical_status.py: 100%
24 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"""Battery Critical Status characteristic implementation."""
3from __future__ import annotations
5from enum import IntFlag
7import msgspec
9from ..context import CharacteristicContext
10from .base import BaseCharacteristic
11from .utils.data_parser import DataParser
14class BatteryCriticalStatus(msgspec.Struct):
15 """Battery Critical Status data structure."""
17 critical_power_state: bool
18 immediate_service_required: bool
21class BatteryCriticalStatusValues(IntFlag): # pylint: disable=too-few-public-methods
22 """Bit mask constants for Battery Critical Status characteristic."""
24 CRITICAL_POWER_STATE_MASK = 0x01
25 IMMEDIATE_SERVICE_REQUIRED_MASK = 0x02
28class BatteryCriticalStatusCharacteristic(BaseCharacteristic[BatteryCriticalStatus]):
29 """Battery Critical Status characteristic."""
31 _manual_unit: str | None = None # Bitfield, no units
33 def _decode_value(
34 self, data: bytearray, ctx: CharacteristicContext | None = None, *, validate: bool = True
35 ) -> BatteryCriticalStatus:
36 """Decode the battery critical status value."""
37 value = DataParser.parse_int8(data, 0, signed=False)
39 return BatteryCriticalStatus(
40 critical_power_state=bool(value & BatteryCriticalStatusValues.CRITICAL_POWER_STATE_MASK),
41 immediate_service_required=bool(value & BatteryCriticalStatusValues.IMMEDIATE_SERVICE_REQUIRED_MASK),
42 )
44 def _encode_value(self, data: BatteryCriticalStatus) -> bytearray:
45 """Encode the battery critical status value."""
46 encoded = 0
47 if data.critical_power_state:
48 encoded |= BatteryCriticalStatusValues.CRITICAL_POWER_STATE_MASK
49 if data.immediate_service_required:
50 encoded |= BatteryCriticalStatusValues.IMMEDIATE_SERVICE_REQUIRED_MASK
52 return DataParser.encode_int8(encoded, signed=False)