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

16 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-10-30 00:10 +0000

1"""Magnetic Declination characteristic implementation.""" 

2 

3from __future__ import annotations 

4 

5from ...types.gatt_enums import ValueType 

6from ...types.units import AngleUnit 

7from .base import BaseCharacteristic 

8from .templates import ScaledUint16Template 

9 

10 

11class MagneticDeclinationCharacteristic(BaseCharacteristic): 

12 """Magnetic Declination characteristic (0x2A2C). 

13 

14 org.bluetooth.characteristic.magnetic_declination 

15 

16 Magnetic declination characteristic. 

17 

18 Represents the magnetic declination - the angle on the horizontal plane 

19 between the direction of True North (geographic) and the direction of 

20 Magnetic North, measured clockwise from True North to Magnetic North. 

21 """ 

22 

23 _template = ScaledUint16Template.from_letter_method(M=1, d=-2, b=0) 

24 

25 _characteristic_name: str = "Magnetic Declination" 

26 # Override YAML int type since decode_value returns float 

27 _manual_value_type: ValueType | str | None = ValueType.FLOAT 

28 _manual_unit: str = AngleUnit.DEGREES.value # Override template's "units" default 

29 

30 # Template configuration 

31 resolution: float = 0.01 # 0.01 degree resolution 

32 max_value: float = 655.35 # 65535 * 0.01 degrees max 

33 

34 def encode_value(self, data: float) -> bytearray: 

35 """Encode magnetic declination value back to bytes. 

36 

37 Args: 

38 data: Magnetic declination in degrees 

39 

40 Returns: 

41 Encoded bytes representing the magnetic declination (uint16, 0.01 degrees resolution) 

42 

43 """ 

44 declination = float(data) 

45 

46 # Normalize to 0-360 range if needed (magnetic declination can be 0-360) 

47 declination = declination % 360.0 

48 

49 # Use template encoding after normalization 

50 return super().encode_value(declination)