Coverage for src / bluetooth_sig / gatt / characteristics / idd_command_control_point.py: 100%
84 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"""IDD Command Control Point characteristic (0x2B25).
3Control point for insulin delivery commands: bolus, TBR, profile management.
5References:
6 Bluetooth SIG Insulin Delivery Service 1.0.1, Table 4.36
7"""
9from __future__ import annotations
11from enum import IntEnum
13import msgspec
15from ..context import CharacteristicContext
16from .base import BaseCharacteristic
17from .utils import DataParser
20class IDDCommandOpCode(IntEnum):
21 """IDD Command Control Point Op Codes (Table 4.36, IDS v1.0.1)."""
23 RESPONSE_CODE = 0x0F55
24 SET_THERAPY_CONTROL_STATE = 0x0F5A
25 SET_FLIGHT_MODE = 0x0F66
26 SNOOZE_ANNUNCIATION = 0x0F69
27 SNOOZE_ANNUNCIATION_RESPONSE = 0x0F96
28 CONFIRM_ANNUNCIATION = 0x0F99
29 CONFIRM_ANNUNCIATION_RESPONSE = 0x0FA5
30 READ_BASAL_RATE_PROFILE_TEMPLATE = 0x0FAA
31 READ_BASAL_RATE_PROFILE_TEMPLATE_RESPONSE = 0x0FC3
32 WRITE_BASAL_RATE_PROFILE_TEMPLATE = 0x0FCC
33 WRITE_BASAL_RATE_PROFILE_TEMPLATE_RESPONSE = 0x0FF0
34 SET_TBR_ADJUSTMENT = 0x0FFF
35 CANCEL_TBR_ADJUSTMENT = 0x1111
36 GET_TBR_TEMPLATE = 0x111E
37 GET_TBR_TEMPLATE_RESPONSE = 0x1122
38 SET_TBR_TEMPLATE = 0x112D
39 SET_TBR_TEMPLATE_RESPONSE = 0x1144
40 SET_BOLUS = 0x114B
41 SET_BOLUS_RESPONSE = 0x1177
42 CANCEL_BOLUS = 0x11A4 # NOTE: value not explicitly in spec extract; retained
43 GET_AVAILABLE_BOLUSES = 0x11C3 # NOTE: value not explicitly in spec extract; retained
44 GET_AVAILABLE_BOLUSES_RESPONSE = 0x11B4
45 GET_BOLUS_TEMPLATE = 0x11BB
46 GET_BOLUS_TEMPLATE_RESPONSE = 0x11D2
47 SET_BOLUS_TEMPLATE = 0x11DD
48 SET_BOLUS_TEMPLATE_RESPONSE = 0x11E1
49 GET_TEMPLATE_STATUS_AND_DETAILS = 0x11EE
50 GET_TEMPLATE_STATUS_AND_DETAILS_RESPONSE = 0x1212
51 RESET_TEMPLATE_STATUS = 0x121D
52 RESET_TEMPLATE_STATUS_RESPONSE = 0x1221
53 ACTIVATE_PROFILE_TEMPLATES = 0x122E
54 ACTIVATE_PROFILE_TEMPLATES_RESPONSE = 0x1247
55 GET_ACTIVATED_PROFILE_TEMPLATES = 0x1248
56 GET_ACTIVATED_PROFILE_TEMPLATES_RESPONSE = 0x1274
57 START_PRIMING = 0x127B
58 STOP_PRIMING = 0x1284
59 SET_INITIAL_RESERVOIR_FILL_LEVEL = 0x128B
60 RESET_RESERVOIR_INSULIN_OPERATION_TIME = 0x12B7
61 READ_ISF_PROFILE_TEMPLATE = 0x12B8
62 READ_ISF_PROFILE_TEMPLATE_RESPONSE = 0x12D1
63 WRITE_ISF_PROFILE_TEMPLATE = 0x12DE
64 WRITE_ISF_PROFILE_TEMPLATE_RESPONSE = 0x12E2
65 READ_I2CHO_RATIO_PROFILE_TEMPLATE = 0x12ED
66 READ_I2CHO_RATIO_PROFILE_TEMPLATE_RESPONSE = 0x1414
67 WRITE_I2CHO_RATIO_PROFILE_TEMPLATE = 0x141B
68 WRITE_I2CHO_RATIO_PROFILE_TEMPLATE_RESPONSE = 0x1427
69 READ_TARGET_GLUCOSE_RANGE_PROFILE_TEMPLATE = 0x1428
70 READ_TARGET_GLUCOSE_RANGE_PROFILE_TEMPLATE_RESPONSE = 0x1441
71 WRITE_TARGET_GLUCOSE_RANGE_PROFILE_TEMPLATE = 0x144E
72 WRITE_TARGET_GLUCOSE_RANGE_PROFILE_TEMPLATE_RESPONSE = 0x1472
73 GET_MAX_BOLUS_AMOUNT = 0x147D
74 GET_MAX_BOLUS_AMOUNT_RESPONSE = 0x1482
75 SET_MAX_BOLUS_AMOUNT = 0x148D
78class IDDCommandResponseCode(IntEnum):
79 """IDD Command Control Point response codes (Table 4.38, Hamming distance 4 to 0x0F)."""
81 SUCCESS = 0x0F
82 OP_CODE_NOT_SUPPORTED = 0x70
83 INVALID_OPERAND = 0x71
84 PROCEDURE_NOT_COMPLETED = 0x72
85 PARAMETER_OUT_OF_RANGE = 0x73
86 PROCEDURE_NOT_APPLICABLE = 0x74
87 PLAUSIBILITY_CHECK_FAILED = 0x75
88 MAXIMUM_BOLUS_NUMBER_REACHED = 0x76
91class IDDCommandControlPointData(msgspec.Struct, frozen=True, kw_only=True):
92 """Parsed data from IDD Command Control Point.
94 Attributes:
95 opcode: The operation code (uint16).
96 operand: Raw operand bytes (variable per opcode). Empty if none.
98 """
100 opcode: IDDCommandOpCode
101 operand: bytes = b""
104class IDDCommandControlPointCharacteristic(BaseCharacteristic[IDDCommandControlPointData]):
105 """IDD Command Control Point characteristic (0x2B25).
107 org.bluetooth.characteristic.idd_command_control_point
109 Control point for insulin delivery commands.
110 ROLE: CONTROL
111 """
113 min_length = 2 # opcode is uint16
114 allow_variable_length = True
116 def _decode_value(
117 self, data: bytearray, ctx: CharacteristicContext | None = None, *, validate: bool = True
118 ) -> IDDCommandControlPointData:
119 """Parse IDD Command Control Point data.
121 Format: OpCode (uint16 LE) + Operand (variable).
122 """
123 opcode = IDDCommandOpCode(DataParser.parse_int16(data, 0, signed=False))
124 operand = bytes(data[2:])
126 return IDDCommandControlPointData(
127 opcode=opcode,
128 operand=operand,
129 )
131 def _encode_value(self, data: IDDCommandControlPointData) -> bytearray:
132 """Encode IDD Command Control Point data."""
133 result = bytearray()
134 result.extend(DataParser.encode_int16(data.opcode, signed=False))
135 result.extend(data.operand)
136 return result