Coverage for src / bluetooth_sig / gatt / characteristics / magnetic_flux_density_2d.py: 100%

25 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-03-18 11:17 +0000

1"""Magnetic Flux Density 2D characteristic implementation.""" 

2 

3from __future__ import annotations 

4 

5from typing import ClassVar 

6 

7from ...types.units import PhysicalUnit 

8from ..context import CharacteristicContext 

9from .base import BaseCharacteristic 

10from .templates import Vector2DData 

11from .utils import DataParser 

12 

13 

14class MagneticFluxDensity2DCharacteristic(BaseCharacteristic[Vector2DData]): 

15 """Magnetic Flux Density - 2D characteristic (0x2AA0). 

16 

17 org.bluetooth.characteristic.magnetic_flux_density_2d 

18 

19 Magnetic flux density 2D characteristic. 

20 

21 Represents measurements of magnetic flux density for two orthogonal 

22 axes: X and Y. Note that 1 x 10^-7 Tesla equals 0.001 Gauss. 

23 

24 Format: 2 x sint16 (4 bytes total) with 1e-7 Tesla resolution. 

25 """ 

26 

27 _characteristic_name: str | None = "Magnetic Flux Density - 2D" 

28 _manual_unit: str | None = PhysicalUnit.TESLA.value # Tesla 

29 

30 _vector_components: ClassVar[list[str]] = ["x_axis", "y_axis"] 

31 resolution: float = 1e-7 

32 expected_length: int = 4 # 2 x sint16 

33 min_length: int = 4 

34 

35 def _decode_value( 

36 self, data: bytearray, ctx: CharacteristicContext | None = None, *, validate: bool = True 

37 ) -> Vector2DData: 

38 """Parse 2D magnetic flux density (2 x sint16 with resolution). 

39 

40 Args: 

41 data: Raw bytearray from BLE characteristic. 

42 ctx: Optional CharacteristicContext providing surrounding context (may be None). 

43 validate: Whether to validate ranges (default True) 

44 

45 Returns: 

46 Vector2DData with x and y axis values in Tesla. 

47 

48 """ 

49 x_raw = DataParser.parse_int16(data, 0, signed=True) 

50 y_raw = DataParser.parse_int16(data, 2, signed=True) 

51 

52 return Vector2DData(x_axis=x_raw * self.resolution, y_axis=y_raw * self.resolution) 

53 

54 def _encode_value(self, data: Vector2DData) -> bytearray: 

55 """Encode 2D magnetic flux density.""" 

56 x_raw = int(data.x_axis / self.resolution) 

57 y_raw = int(data.y_axis / self.resolution) 

58 

59 result = bytearray() 

60 result.extend(DataParser.encode_int16(x_raw, signed=True)) 

61 result.extend(DataParser.encode_int16(y_raw, signed=True)) 

62 return result