Coverage for src / bluetooth_sig / gatt / characteristics / battery_critical_status.py: 100%

24 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-11 20:14 +0000

1"""Battery Critical Status characteristic implementation.""" 

2 

3from __future__ import annotations 

4 

5from enum import IntFlag 

6 

7import msgspec 

8 

9from ..context import CharacteristicContext 

10from .base import BaseCharacteristic 

11from .utils.data_parser import DataParser 

12 

13 

14class BatteryCriticalStatus(msgspec.Struct): 

15 """Battery Critical Status data structure.""" 

16 

17 critical_power_state: bool 

18 immediate_service_required: bool 

19 

20 

21class BatteryCriticalStatusValues(IntFlag): # pylint: disable=too-few-public-methods 

22 """Bit mask constants for Battery Critical Status characteristic.""" 

23 

24 CRITICAL_POWER_STATE_MASK = 0x01 

25 IMMEDIATE_SERVICE_REQUIRED_MASK = 0x02 

26 

27 

28class BatteryCriticalStatusCharacteristic(BaseCharacteristic[BatteryCriticalStatus]): 

29 """Battery Critical Status characteristic.""" 

30 

31 _manual_unit: str | None = None # Bitfield, no units 

32 

33 def _decode_value(self, data: bytearray, ctx: CharacteristicContext | None = None) -> BatteryCriticalStatus: 

34 """Decode the battery critical status value.""" 

35 value = DataParser.parse_int8(data, 0, signed=False) 

36 

37 return BatteryCriticalStatus( 

38 critical_power_state=bool(value & BatteryCriticalStatusValues.CRITICAL_POWER_STATE_MASK), 

39 immediate_service_required=bool(value & BatteryCriticalStatusValues.IMMEDIATE_SERVICE_REQUIRED_MASK), 

40 ) 

41 

42 def _encode_value(self, data: BatteryCriticalStatus) -> bytearray: 

43 """Encode the battery critical status value.""" 

44 encoded = 0 

45 if data.critical_power_state: 

46 encoded |= BatteryCriticalStatusValues.CRITICAL_POWER_STATE_MASK 

47 if data.immediate_service_required: 

48 encoded |= BatteryCriticalStatusValues.IMMEDIATE_SERVICE_REQUIRED_MASK 

49 

50 return DataParser.encode_int8(encoded, signed=False)