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

35 statements  

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

1"""ESL Display Information characteristic implementation.""" 

2 

3from __future__ import annotations 

4 

5from enum import IntEnum 

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 ESLDisplayType(IntEnum): 

16 """ESL display type values per ESL specification.""" 

17 

18 BLACK_WHITE = 0x01 

19 THREE_GRAY = 0x02 

20 FOUR_GRAY = 0x03 

21 EIGHT_GRAY = 0x04 

22 SIXTEEN_GRAY = 0x05 

23 COLOR_RGB = 0x06 

24 

25 

26class ESLDisplayInformationData(msgspec.Struct, frozen=True, kw_only=True): 

27 """Parsed data from ESL Display Information characteristic. 

28 

29 Attributes: 

30 display_index: Index of the display (0-based). 

31 width: Display width in pixels. 

32 height: Display height in pixels. 

33 display_type: Type of display technology. 

34 

35 """ 

36 

37 display_index: int 

38 width: int 

39 height: int 

40 display_type: ESLDisplayType 

41 

42 

43class ESLDisplayInformationCharacteristic(BaseCharacteristic[ESLDisplayInformationData]): 

44 """ESL Display Information characteristic (0x2BFA). 

45 

46 org.bluetooth.characteristic.esl_display_information 

47 

48 Describes an ESL display: index, width, height, and display type. 

49 """ 

50 

51 _manual_role = CharacteristicRole.INFO 

52 expected_length: int = 6 # display_index(1) + width(2) + height(2) + display_type(1) 

53 min_length: int = 6 

54 

55 def _decode_value( 

56 self, 

57 data: bytearray, 

58 ctx: CharacteristicContext | None = None, 

59 *, 

60 validate: bool = True, 

61 ) -> ESLDisplayInformationData: 

62 """Parse ESL display information. 

63 

64 Args: 

65 data: Raw bytes (6 bytes). 

66 ctx: Optional CharacteristicContext. 

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

68 

69 Returns: 

70 ESLDisplayInformationData with display details. 

71 

72 """ 

73 display_index = DataParser.parse_int8(data, 0, signed=False) 

74 width = DataParser.parse_int16(data, 1, signed=False) 

75 height = DataParser.parse_int16(data, 3, signed=False) 

76 display_type = ESLDisplayType(DataParser.parse_int8(data, 5, signed=False)) 

77 return ESLDisplayInformationData( 

78 display_index=display_index, 

79 width=width, 

80 height=height, 

81 display_type=display_type, 

82 ) 

83 

84 def _encode_value(self, data: ESLDisplayInformationData) -> bytearray: 

85 """Encode ESL display information to bytes. 

86 

87 Args: 

88 data: ESLDisplayInformationData to encode. 

89 

90 Returns: 

91 Encoded bytes (6 bytes). 

92 

93 """ 

94 result = DataParser.encode_int8(data.display_index, signed=False) 

95 result.extend(DataParser.encode_int16(data.width, signed=False)) 

96 result.extend(DataParser.encode_int16(data.height, signed=False)) 

97 result.extend(DataParser.encode_int8(int(data.display_type), signed=False)) 

98 return result