Coverage for src / bluetooth_sig / gatt / characteristics / volume_offset_state.py: 100%
19 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-03 16:41 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-03 16:41 +0000
1"""Volume Offset State characteristic (0x2B80)."""
3from __future__ import annotations
5import msgspec
7from ..context import CharacteristicContext
8from .base import BaseCharacteristic
9from .utils import DataParser
12class VolumeOffsetStateData(msgspec.Struct, frozen=True, kw_only=True): # pylint: disable=too-few-public-methods
13 """Parsed data from Volume Offset State characteristic.
15 Contains the volume offset and change counter.
16 """
18 volume_offset: int
19 change_counter: int
22class VolumeOffsetStateCharacteristic(BaseCharacteristic[VolumeOffsetStateData]):
23 """Volume Offset State characteristic (0x2B80).
25 org.bluetooth.characteristic.volume_offset_state
27 Reports the current volume offset and change counter
28 for the Volume Offset Control Service.
29 """
31 expected_length = 3
33 def _decode_value(
34 self, data: bytearray, ctx: CharacteristicContext | None = None, *, validate: bool = True
35 ) -> VolumeOffsetStateData:
36 """Parse Volume Offset State data.
38 Format: volume_offset (sint16 LE) + change_counter (uint8).
39 """
40 volume_offset = DataParser.parse_int16(data, 0, signed=True)
41 change_counter = DataParser.parse_int8(data, 2, signed=False)
42 return VolumeOffsetStateData(
43 volume_offset=volume_offset,
44 change_counter=change_counter,
45 )
47 def _encode_value(self, data: VolumeOffsetStateData) -> bytearray:
48 """Encode Volume Offset State data to bytes."""
49 result = bytearray()
50 result += DataParser.encode_int16(data.volume_offset, signed=True)
51 result += DataParser.encode_int8(data.change_counter)
52 return result