Coverage for src / bluetooth_sig / gatt / characteristics / ghs_control_point.py: 100%
25 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"""GHS Control Point characteristic (0x2BF4).
3Control point for the Generic Health Sensor service.
5References:
6 Bluetooth SIG Generic Health Sensor Service specification
7"""
9from __future__ import annotations
11from enum import IntEnum
13import msgspec
15from ..context import CharacteristicContext
16from .base import BaseCharacteristic
17from .utils import DataParser
20class GHSControlPointOpCode(IntEnum):
21 """GHS Control Point Op Codes."""
23 START_SEND_LIVE_OBSERVATIONS = 0x01
24 STOP_SEND_LIVE_OBSERVATIONS = 0x02
25 RESPONSE_CODE = 0x80
28class GHSControlPointData(msgspec.Struct, frozen=True, kw_only=True):
29 """Parsed data from GHS Control Point.
31 Attributes:
32 opcode: The operation code.
33 parameter: Raw parameter bytes (variable per opcode). Empty if none.
35 """
37 opcode: GHSControlPointOpCode
38 parameter: bytes = b""
41class GHSControlPointCharacteristic(BaseCharacteristic[GHSControlPointData]):
42 """GHS Control Point characteristic (0x2BF4).
44 org.bluetooth.characteristic.ghs_control_point
46 Control point for managing observations in the Generic Health
47 Sensor service.
48 """
50 min_length = 1
51 allow_variable_length = True
53 def _decode_value(
54 self, data: bytearray, ctx: CharacteristicContext | None = None, *, validate: bool = True
55 ) -> GHSControlPointData:
56 """Parse GHS Control Point data.
58 Format: OpCode (uint8) + Parameter (variable).
59 """
60 opcode = GHSControlPointOpCode(DataParser.parse_int8(data, 0, signed=False))
61 parameter = bytes(data[1:])
63 return GHSControlPointData(
64 opcode=opcode,
65 parameter=parameter,
66 )
68 def _encode_value(self, data: GHSControlPointData) -> bytearray:
69 """Encode GHS Control Point data."""
70 result = bytearray()
71 result.extend(DataParser.encode_int8(int(data.opcode), signed=False))
72 result.extend(data.parameter)
73 return result