Coverage for src / bluetooth_sig / gatt / characteristics / esl_image_information.py: 100%
37 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-03 16:41 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-03 16:41 +0000
1"""ESL Image Information characteristic implementation."""
3from __future__ import annotations
5from enum import IntEnum
7import msgspec
9from ...types.gatt_enums import CharacteristicRole
10from ..context import CharacteristicContext
11from .base import BaseCharacteristic
12from .utils import DataParser
15class ESLImageType(IntEnum):
16 """ESL image type identifiers per ESL Service spec."""
18 BLACK_WHITE = 0x00
19 THREE_GRAY_SCALE = 0x01
20 FOUR_GRAY_SCALE = 0x02
21 EIGHT_GRAY_SCALE = 0x03
22 SIXTEEN_GRAY_SCALE = 0x04
23 RED_BLACK_WHITE = 0x05
24 YELLOW_BLACK_WHITE = 0x06
25 FULL_COLOR = 0x07
28class ESLImageInformationData(msgspec.Struct, frozen=True, kw_only=True):
29 """Parsed data from ESL Image Information characteristic.
31 Attributes:
32 image_index: Index of the image slot (0-based).
33 max_width: Maximum image width in pixels.
34 max_height: Maximum image height in pixels.
35 image_type: Image type identifier (codec/format).
37 """
39 image_index: int
40 max_width: int
41 max_height: int
42 image_type: ESLImageType
45class ESLImageInformationCharacteristic(BaseCharacteristic[ESLImageInformationData]):
46 """ESL Image Information characteristic (0x2BFB).
48 org.bluetooth.characteristic.esl_image_information
50 Describes an ESL image slot: index, maximum width, maximum height,
51 and image type.
52 """
54 _manual_role = CharacteristicRole.INFO
55 expected_length: int = 6 # image_index(1) + max_width(2) + max_height(2) + image_type(1)
56 min_length: int = 6
58 def _decode_value(
59 self,
60 data: bytearray,
61 ctx: CharacteristicContext | None = None,
62 *,
63 validate: bool = True,
64 ) -> ESLImageInformationData:
65 """Parse ESL image information.
67 Args:
68 data: Raw bytes (6 bytes).
69 ctx: Optional CharacteristicContext.
70 validate: Whether to validate ranges (default True).
72 Returns:
73 ESLImageInformationData with image slot details.
75 """
76 image_index = DataParser.parse_int8(data, 0, signed=False)
77 max_width = DataParser.parse_int16(data, 1, signed=False)
78 max_height = DataParser.parse_int16(data, 3, signed=False)
79 image_type = DataParser.parse_int8(data, 5, signed=False)
80 return ESLImageInformationData(
81 image_index=image_index,
82 max_width=max_width,
83 max_height=max_height,
84 image_type=ESLImageType(image_type),
85 )
87 def _encode_value(self, data: ESLImageInformationData) -> bytearray:
88 """Encode ESL image information to bytes.
90 Args:
91 data: ESLImageInformationData to encode.
93 Returns:
94 Encoded bytes (6 bytes).
96 """
97 result = DataParser.encode_int8(data.image_index, signed=False)
98 result.extend(DataParser.encode_int16(data.max_width, signed=False))
99 result.extend(DataParser.encode_int16(data.max_height, signed=False))
100 result.extend(DataParser.encode_int8(int(data.image_type), signed=False))
101 return result