Coverage for src / bluetooth_sig / gatt / characteristics / descriptor_value_changed.py: 100%
29 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"""Descriptor Value Changed characteristic (0x2A7D)."""
3from __future__ import annotations
5from enum import IntFlag
7import msgspec
9from ...types.uuid import BluetoothUUID
10from ..context import CharacteristicContext
11from .base import BaseCharacteristic
12from .utils import DataParser
15class DescriptorValueChangedFlags(IntFlag):
16 """Descriptor Value Changed flags."""
18 SOURCE_OF_CHANGE_DEVICE = 0x0001
19 SOURCE_OF_CHANGE_EXTERNAL = 0x0002
22class DescriptorValueChangedData(msgspec.Struct, frozen=True, kw_only=True):
23 """Parsed data from Descriptor Value Changed characteristic."""
25 flags: DescriptorValueChangedFlags
26 characteristic_uuid: BluetoothUUID
27 value: bytes
30_ADDITIONAL_DATA_START_OFFSET = 4
33class DescriptorValueChangedCharacteristic(BaseCharacteristic[DescriptorValueChangedData]):
34 """Descriptor Value Changed characteristic (0x2A7D).
36 org.bluetooth.characteristic.descriptor_value_changed
38 Indicates that a descriptor value has changed. Contains flags,
39 the UUID of the changed characteristic, and the new value.
40 """
42 min_length = 4
43 allow_variable_length = True
45 def _decode_value(
46 self, data: bytearray, ctx: CharacteristicContext | None = None, *, validate: bool = True
47 ) -> DescriptorValueChangedData:
48 flags = DescriptorValueChangedFlags(DataParser.parse_int16(data, 0, signed=False))
49 characteristic_uuid = BluetoothUUID(DataParser.parse_int16(data, 2, signed=False))
50 value = bytes(data[_ADDITIONAL_DATA_START_OFFSET:]) if len(data) > _ADDITIONAL_DATA_START_OFFSET else b""
52 return DescriptorValueChangedData(
53 flags=flags,
54 characteristic_uuid=characteristic_uuid,
55 value=value,
56 )
58 def _encode_value(self, data: DescriptorValueChangedData) -> bytearray:
59 result = bytearray()
60 result.extend(DataParser.encode_int16(int(data.flags), signed=False))
61 result.extend(DataParser.encode_int16(int(data.characteristic_uuid.short_form, 16), signed=False))
62 result.extend(data.value)
63 return result