Coverage for src / bluetooth_sig / gatt / characteristics / acceleration_3d.py: 100%
23 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-18 11:17 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-18 11:17 +0000
1"""Acceleration - 3D characteristic implementation."""
3from __future__ import annotations
5from ..context import CharacteristicContext
6from .base import BaseCharacteristic
7from .templates import VectorData
8from .utils import DataParser
11class Acceleration3DCharacteristic(BaseCharacteristic[VectorData]):
12 """Acceleration - 3D characteristic (0x2C1D).
14 org.bluetooth.characteristic.acceleration_3d
16 The Acceleration - 3D characteristic represents a measure of acceleration with a limited range.
17 """
19 _characteristic_name: str | None = "Acceleration 3D"
20 resolution: float = 0.01
22 # BaseCharacteristic handles validation
23 expected_length = 3
25 def _decode_value(
26 self, data: bytearray, ctx: CharacteristicContext | None = None, *, validate: bool = True
27 ) -> VectorData:
28 """Parse 3D acceleration (3 x sint8).
30 Args:
31 data: Raw bytearray from BLE characteristic (3 bytes, validated by base class).
32 ctx: Optional CharacteristicContext.
33 validate: Whether to validate ranges (default True)
35 Returns:
36 VectorData with x, y, z axis values in gₙ (standard acceleration due to gravity).
37 """
38 x_raw = DataParser.parse_int8(data, 0, signed=True)
39 y_raw = DataParser.parse_int8(data, 1, signed=True)
40 z_raw = DataParser.parse_int8(data, 2, signed=True)
42 return VectorData(
43 x_axis=x_raw * self.resolution,
44 y_axis=y_raw * self.resolution,
45 z_axis=z_raw * self.resolution,
46 )
48 def _encode_value(self, data: VectorData) -> bytearray:
49 """Encode 3D acceleration.
51 Args:
52 data: VectorData with x, y, z axis values in gₙ.
54 Returns:
55 Encoded bytes (3 bytes)
56 """
57 x_raw = int(data.x_axis / self.resolution)
58 y_raw = int(data.y_axis / self.resolution)
59 z_raw = int(data.z_axis / self.resolution)
61 result = bytearray()
62 result.extend(DataParser.encode_int8(x_raw, signed=True))
63 result.extend(DataParser.encode_int8(y_raw, signed=True))
64 result.extend(DataParser.encode_int8(z_raw, signed=True))
65 return result