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

21 statements  

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

1"""IDD Command Data characteristic (0x2B26). 

2 

3Contains command data associated with IDD Command Control Point responses. 

4 

5References: 

6 Bluetooth SIG Insulin Delivery Service 1.0 

7""" 

8 

9from __future__ import annotations 

10 

11import msgspec 

12 

13from ..context import CharacteristicContext 

14from .base import BaseCharacteristic 

15from .idd_command_control_point import IDDCommandOpCode 

16from .utils import DataParser 

17 

18 

19class IDDCommandDataPayload(msgspec.Struct, frozen=True, kw_only=True): 

20 """Parsed data from IDD Command Data characteristic. 

21 

22 Attributes: 

23 opcode: The echoed operation code (uint16 LE). 

24 command_data: Raw command-specific data bytes. 

25 

26 """ 

27 

28 opcode: IDDCommandOpCode 

29 command_data: bytes = b"" 

30 

31 

32class IDDCommandDataCharacteristic(BaseCharacteristic[IDDCommandDataPayload]): 

33 """IDD Command Data characteristic (0x2B26). 

34 

35 org.bluetooth.characteristic.idd_command_data 

36 

37 Contains command data associated with IDD Command Control Point operations. 

38 """ 

39 

40 min_length = 2 # opcode (uint16) 

41 allow_variable_length = True 

42 

43 def _decode_value( 

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

45 ) -> IDDCommandDataPayload: 

46 """Parse IDD Command Data. 

47 

48 Format: OpCode (uint16 LE) + CommandData (variable). 

49 """ 

50 opcode = IDDCommandOpCode(DataParser.parse_int16(data, 0, signed=False)) 

51 command_data = bytes(data[2:]) 

52 

53 return IDDCommandDataPayload( 

54 opcode=opcode, 

55 command_data=command_data, 

56 ) 

57 

58 def _encode_value(self, data: IDDCommandDataPayload) -> bytearray: 

59 """Encode IDD Command Data.""" 

60 result = bytearray() 

61 result.extend(DataParser.encode_int16(data.opcode, signed=False)) 

62 result.extend(data.command_data) 

63 return result