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

12 statements  

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

1"""Rotational Speed 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 RotationalSpeedCharacteristic(BaseCharacteristic[float]): 

11 """Rotational Speed characteristic (0x2C09). 

12 

13 org.bluetooth.characteristic.rotational_speed 

14 

15 The Rotational Speed characteristic is used to represent the rotational speed of an object 

16 rotating around a device-specific axis. 

17 """ 

18 

19 _manual_unit: str | None = "RPM" # YAML ID mismatch: has rotational_speed.*, should be angular_velocity.* 

20 

21 def _decode_value( 

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

23 ) -> float: 

24 """Decode rotational speed characteristic. 

25 

26 Decodes a 32-bit signed integer representing speed in RPM 

27 per Bluetooth SIG Rotational Speed characteristic specification. 

28 

29 Args: 

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

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

32 validate: Whether to validate ranges (default True) 

33 

34 Returns: 

35 Rotational speed in revolutions per minute (RPM), or None if value is not known 

36 

37 Raises: 

38 InsufficientDataError: If data is not exactly 4 bytes 

39 """ 

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

41 return float(raw_value) 

42 

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

44 """Encode rotational speed value.""" 

45 raw_value = int(data) 

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