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

26 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-04-03 16:41 +0000

1"""Volume State characteristic (0x2B7D).""" 

2 

3from __future__ import annotations 

4 

5from enum import IntEnum 

6 

7import msgspec 

8 

9from ..context import CharacteristicContext 

10from .base import BaseCharacteristic 

11from .utils import DataParser 

12 

13 

14class VolumeMuteState(IntEnum): 

15 """Volume mute state.""" 

16 

17 NOT_MUTED = 0 

18 MUTED = 1 

19 

20 

21class VolumeStateData(msgspec.Struct, frozen=True, kw_only=True): # pylint: disable=too-few-public-methods 

22 """Parsed data from Volume State characteristic. 

23 

24 Contains the current volume setting, mute state, and change counter. 

25 """ 

26 

27 volume_setting: int 

28 mute: VolumeMuteState 

29 change_counter: int 

30 

31 

32class VolumeStateCharacteristic(BaseCharacteristic[VolumeStateData]): 

33 """Volume State characteristic (0x2B7D). 

34 

35 org.bluetooth.characteristic.volume_state 

36 

37 Reports the current volume setting, mute state, and change counter 

38 for the Volume Control Service. 

39 """ 

40 

41 expected_length = 3 

42 

43 def _decode_value( 

44 self, data: bytearray, ctx: CharacteristicContext | None = None, *, validate: bool = True 

45 ) -> VolumeStateData: 

46 """Parse Volume State data. 

47 

48 Format: volume_setting (uint8) + mute (uint8) + change_counter (uint8). 

49 """ 

50 volume_setting = DataParser.parse_int8(data, 0, signed=False) 

51 mute = VolumeMuteState(DataParser.parse_int8(data, 1, signed=False)) 

52 change_counter = DataParser.parse_int8(data, 2, signed=False) 

53 return VolumeStateData( 

54 volume_setting=volume_setting, 

55 mute=mute, 

56 change_counter=change_counter, 

57 ) 

58 

59 def _encode_value(self, data: VolumeStateData) -> bytearray: 

60 """Encode Volume State data to bytes.""" 

61 result = bytearray() 

62 result += DataParser.encode_int8(data.volume_setting) 

63 result += DataParser.encode_int8(int(data.mute)) 

64 result += DataParser.encode_int8(data.change_counter) 

65 return result