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

16 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-11 20:14 +0000

1"""Supported Unread Alert Category characteristic (0x2A48) implementation. 

2 

3Represents which alert categories the server supports for unread alerts. 

4Used by Alert Notification Service (0x1811). 

5 

6Based on Bluetooth SIG GATT Specification: 

7- Supported Unread Alert Category: 2 bytes (16-bit Category ID Bit Mask) 

8""" 

9 

10from __future__ import annotations 

11 

12from ...types import AlertCategoryBitMask 

13from ..context import CharacteristicContext 

14from .base import BaseCharacteristic 

15from .utils import DataParser 

16 

17 

18class SupportedUnreadAlertCategoryCharacteristic(BaseCharacteristic[AlertCategoryBitMask]): 

19 """Supported Unread Alert Category characteristic (0x2A48). 

20 

21 Represents which alert categories the server supports for unread alerts 

22 using a 16-bit bitmask. 

23 

24 Structure (2 bytes): 

25 - Category ID Bit Mask: uint16 (bit 0=Simple Alert, bit 1=Email, etc.) 

26 Bits 10-15 reserved for future use 

27 

28 Used by Alert Notification Service (0x1811). 

29 """ 

30 

31 # YAML specifies size: 1 or 2 (variable length struct) 

32 min_length: int | None = 1 

33 max_length: int | None = 2 

34 

35 def _decode_value(self, data: bytearray, ctx: CharacteristicContext | None = None) -> AlertCategoryBitMask: 

36 """Decode Supported Unread Alert Category data from bytes. 

37 

38 Args: 

39 data: Raw characteristic data (2 bytes) 

40 ctx: Optional characteristic context 

41 

42 Returns: 

43 AlertCategoryBitMask flags 

44 

45 Raises: 

46 ValueError: If data is insufficient 

47 

48 """ 

49 if len(data) < 2: 

50 raise ValueError( 

51 f"Insufficient data for Supported Unread Alert Category: expected 2 bytes, got {len(data)}" 

52 ) 

53 

54 mask_value = DataParser.parse_int16(data, 0, signed=False) 

55 return AlertCategoryBitMask(mask_value) 

56 

57 def _encode_value(self, data: AlertCategoryBitMask | int) -> bytearray: 

58 """Encode Supported Unread Alert Category data to bytes. 

59 

60 Args: 

61 data: AlertCategoryBitMask or int value 

62 

63 Returns: 

64 Encoded supported unread alert category (2 bytes) 

65 

66 """ 

67 int_value = int(data) if isinstance(data, AlertCategoryBitMask) else data 

68 return DataParser.encode_int16(int_value, signed=False)