Coverage for src / bluetooth_sig / gatt / characteristics / acceleration_3d.py: 100%
24 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-11 20:14 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-11 20:14 +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
21 _manual_value_type = "VectorData"
23 # BaseCharacteristic handles validation
24 expected_length = 3
26 def _decode_value(self, data: bytearray, ctx: CharacteristicContext | None = None) -> VectorData:
27 """Parse 3D acceleration (3 x sint8).
29 Args:
30 data: Raw bytearray from BLE characteristic (3 bytes, validated by base class).
31 ctx: Optional CharacteristicContext.
33 Returns:
34 VectorData with x, y, z axis values in gₙ (standard acceleration due to gravity).
35 """
36 x_raw = DataParser.parse_int8(data, 0, signed=True)
37 y_raw = DataParser.parse_int8(data, 1, signed=True)
38 z_raw = DataParser.parse_int8(data, 2, signed=True)
40 return VectorData(
41 x_axis=x_raw * self.resolution,
42 y_axis=y_raw * self.resolution,
43 z_axis=z_raw * self.resolution,
44 )
46 def _encode_value(self, data: VectorData) -> bytearray:
47 """Encode 3D acceleration.
49 Args:
50 data: VectorData with x, y, z axis values in gₙ.
52 Returns:
53 Encoded bytes (3 bytes)
54 """
55 x_raw = int(data.x_axis / self.resolution)
56 y_raw = int(data.y_axis / self.resolution)
57 z_raw = int(data.z_axis / self.resolution)
59 result = bytearray()
60 result.extend(DataParser.encode_int8(x_raw, signed=True))
61 result.extend(DataParser.encode_int8(y_raw, signed=True))
62 result.extend(DataParser.encode_int8(z_raw, signed=True))
63 return result