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

12 statements  

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

1"""Force characteristic implementation.""" 

2 

3from __future__ import annotations 

4 

5from ..context import CharacteristicContext 

6from .base import BaseCharacteristic 

7from .utils.data_parser import DataParser 

8 

9 

10class ForceCharacteristic(BaseCharacteristic[float]): 

11 """Force characteristic (0x2C07). 

12 

13 org.bluetooth.characteristic.force 

14 

15 The Force characteristic is used to represent the force being applied to an object along a given axis. 

16 """ 

17 

18 expected_length: int = 4 # sint32 

19 

20 def _decode_value( 

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

22 ) -> float: 

23 """Decode force characteristic. 

24 

25 Decodes a 32-bit signed integer representing force in 0.001 N increments 

26 per Bluetooth SIG Force characteristic specification. 

27 

28 Args: 

29 data: Raw bytes from BLE characteristic (exactly 4 bytes, little-endian) 

30 ctx: Optional context for parsing (device info, flags, etc.) 

31 validate: Whether to validate ranges (default True) 

32 

33 Returns: 

34 Force in Newtons 

35 

36 Raises: 

37 InsufficientDataError: If data is not exactly 4 bytes 

38 """ 

39 raw_value = DataParser.parse_int32(data, 0, signed=True) 

40 return raw_value * 0.001 

41 

42 def _encode_value(self, data: float) -> bytearray: 

43 """Encode force value.""" 

44 raw_value = int(data / 0.001) 

45 return DataParser.encode_int32(raw_value, signed=True)