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

1"""Acceleration - 3D characteristic implementation.""" 

2 

3from __future__ import annotations 

4 

5from ..context import CharacteristicContext 

6from .base import BaseCharacteristic 

7from .templates import VectorData 

8from .utils import DataParser 

9 

10 

11class Acceleration3DCharacteristic(BaseCharacteristic[VectorData]): 

12 """Acceleration - 3D characteristic (0x2C1D). 

13 

14 org.bluetooth.characteristic.acceleration_3d 

15 

16 The Acceleration - 3D characteristic represents a measure of acceleration with a limited range. 

17 """ 

18 

19 _characteristic_name: str | None = "Acceleration 3D" 

20 resolution: float = 0.01 

21 _manual_value_type = "VectorData" 

22 

23 # BaseCharacteristic handles validation 

24 expected_length = 3 

25 

26 def _decode_value(self, data: bytearray, ctx: CharacteristicContext | None = None) -> VectorData: 

27 """Parse 3D acceleration (3 x sint8). 

28 

29 Args: 

30 data: Raw bytearray from BLE characteristic (3 bytes, validated by base class). 

31 ctx: Optional CharacteristicContext. 

32 

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) 

39 

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 ) 

45 

46 def _encode_value(self, data: VectorData) -> bytearray: 

47 """Encode 3D acceleration. 

48 

49 Args: 

50 data: VectorData with x, y, z axis values in gₙ. 

51 

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) 

58 

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