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

27 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-04-03 16:41 +0000

1"""ESL LED Information characteristic implementation.""" 

2 

3from __future__ import annotations 

4 

5from enum import IntFlag 

6 

7import msgspec 

8 

9from ...types.gatt_enums import CharacteristicRole 

10from ..context import CharacteristicContext 

11from .base import BaseCharacteristic 

12from .utils import DataParser 

13 

14 

15class ESLColorGamut(IntFlag): 

16 """ESL LED colour gamut flags per ESL specification.""" 

17 

18 RED = 0x01 

19 GREEN = 0x02 

20 BLUE = 0x04 

21 

22 

23class ESLLEDInformationData(msgspec.Struct, frozen=True, kw_only=True): 

24 """Parsed data from ESL LED Information characteristic. 

25 

26 Attributes: 

27 led_index: Index of the LED (0-based). 

28 color_gamut: Colour gamut bitfield indicating supported colours. 

29 

30 """ 

31 

32 led_index: int 

33 color_gamut: ESLColorGamut 

34 

35 

36class ESLLEDInformationCharacteristic(BaseCharacteristic[ESLLEDInformationData]): 

37 """ESL LED Information characteristic (0x2BFD). 

38 

39 org.bluetooth.characteristic.esl_led_information 

40 

41 Describes an ESL LED: index and colour gamut bitfield (Red, Green, Blue). 

42 """ 

43 

44 _characteristic_name = "ESL LED Information" 

45 _manual_role = CharacteristicRole.INFO 

46 expected_length: int = 2 # led_index(1) + color_gamut(1) 

47 min_length: int = 2 

48 

49 def _decode_value( 

50 self, 

51 data: bytearray, 

52 ctx: CharacteristicContext | None = None, 

53 *, 

54 validate: bool = True, 

55 ) -> ESLLEDInformationData: 

56 """Parse ESL LED information. 

57 

58 Args: 

59 data: Raw bytes (2 bytes). 

60 ctx: Optional CharacteristicContext. 

61 validate: Whether to validate ranges (default True). 

62 

63 Returns: 

64 ESLLEDInformationData with LED details. 

65 

66 """ 

67 led_index = DataParser.parse_int8(data, 0, signed=False) 

68 color_gamut = ESLColorGamut(DataParser.parse_int8(data, 1, signed=False)) 

69 return ESLLEDInformationData(led_index=led_index, color_gamut=color_gamut) 

70 

71 def _encode_value(self, data: ESLLEDInformationData) -> bytearray: 

72 """Encode ESL LED information to bytes. 

73 

74 Args: 

75 data: ESLLEDInformationData to encode. 

76 

77 Returns: 

78 Encoded bytes (2 bytes). 

79 

80 """ 

81 result = DataParser.encode_int8(data.led_index, signed=False) 

82 result.extend(DataParser.encode_int8(int(data.color_gamut), signed=False)) 

83 return result