Coverage for custom_components/supernotify/options.py: 97%

38 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-11-08 17:42 +0000

1"""Common `options:` tuning keys and their metadata — documentation/introspection only. 

2 

3Does not replace or drive runtime validation (schema.py's CONF_OPTIONS stays a 

4permissive `dict`). Keys and their value-domain constants live here, alongside the 

5metadata that describes them - never redeclared elsewhere. 

6 

7Common options (read centrally in envelope.py/delivery.py, applicable to every 

8transport) are declared below. Transport-specific options and their own key/value 

9constants are declared on the owning Transport subclass's `declared_options` (see 

10transport.py) and in that transport's own module - not here, to avoid this module 

11importing static_config/engine and creating a cycle. 

12""" 

13 

14from __future__ import annotations 

15 

16from collections.abc import Callable 

17from dataclasses import dataclass 

18 

19from homeassistant.helpers import config_validation as cv 

20 

21from custom_components.supernotify.compat import vol 

22from custom_components.supernotify.model import SelectionRule 

23 

24OPTION_SIMPLIFY_TEXT = "simplify_text" 

25OPTION_STRIP_URLS = "strip_urls" 

26OPTION_MESSAGE_USAGE = "message_usage" 

27OPTION_TARGET_CATEGORIES = "target_categories" 

28OPTION_TARGET_SELECT = "target_select" 

29OPTION_DATA_KEYS_SELECT = "data_keys_select" 

30OPTION_DEVICE_DOMAIN = "device_domain" 

31OPTION_DEVICE_MODEL_SELECT = "device_model_select" 

32OPTION_DEVICE_MANUFACTURER_SELECT = "device_manufacturer_select" 

33OPTION_DEVICE_OS_SELECT = "device_os_select" 

34OPTION_DEVICE_LABEL_SELECT = "device_label_select" 

35OPTION_DEVICE_AREA_SELECT = "device_area_select" 

36OPTION_DEVICE_DISCOVERY = "device_discovery" 

37OPTION_JPEG = "jpeg_opts" 

38OPTION_PNG = "png_opts" 

39MEDIA_OPTION_REPROCESS = "reprocess" 

40 

41# Domain of a SelectionRule-typed option's mapping, e.g. {SELECT_INCLUDE: [...], SELECT_EXCLUDE: [...]} 

42SELECT_INCLUDE = "include" 

43SELECT_EXCLUDE = "exclude" 

44 

45# Deprecated v1.9.0 aliases, upgraded in Delivery.upgrade_deprecations() - not part of 

46# COMMON_OPTIONS since they're not offered to new configuration. 

47OPTION_TARGET_INCLUDE_RE = "target_include_re" 

48OPTION_DATA_KEYS_INCLUDE_RE = "data_keys_include_re" 

49OPTION_DATA_KEYS_EXCLUDE_RE = "data_keys_exclude_re" 

50 

51 

52@dataclass(frozen=True) 

53class DeliveryOption: 

54 key: str 

55 description: str 

56 value_type: Callable[..., object] = cv.string 

57 examples: list[str] | None = None 

58 

59 

60COMMON_OPTIONS: list[DeliveryOption] = [ 

61 DeliveryOption( 

62 OPTION_SIMPLIFY_TEXT, 

63 "Remove some common symbols that can trip up voice assistants. SSML markup is left alone on spoken transports", 

64 value_type=cv.boolean, 

65 ), 

66 DeliveryOption(OPTION_STRIP_URLS, "Remove URLs from message and title", value_type=cv.boolean), 

67 DeliveryOption( 

68 OPTION_MESSAGE_USAGE, 

69 "Combine message and title, default title", 

70 examples=["combine_title", "use_title", "message_only"], 

71 ), 

72 DeliveryOption( 

73 OPTION_TARGET_SELECT, 

74 "Only use targets fully matching these regular expressions, group members expanded first", 

75 value_type=SelectionRule, 

76 ), 

77 DeliveryOption( 

78 OPTION_TARGET_CATEGORIES, 

79 "Which targets to pass, e.g. entity_id, email, device_id", 

80 value_type=list, 

81 examples=['["entity_id", "device_id"]'], 

82 ), 

83 DeliveryOption(OPTION_DEVICE_DISCOVERY, "Switch automatic device discovery on or off", value_type=cv.boolean), 

84 DeliveryOption(OPTION_DEVICE_DOMAIN, "One or more Home Assistant domains to discover devices, e.g. alexa_devices"), 

85 DeliveryOption(OPTION_DEVICE_MODEL_SELECT, "Choose device models in device discovery", value_type=SelectionRule), 

86 DeliveryOption( 

87 OPTION_DEVICE_MANUFACTURER_SELECT, 

88 "Choose device manufacturers in device discovery", 

89 value_type=SelectionRule, 

90 ), 

91 DeliveryOption( 

92 OPTION_DEVICE_OS_SELECT, 

93 "Choose device operating systems in device discovery", 

94 value_type=SelectionRule, 

95 ), 

96 DeliveryOption(OPTION_DEVICE_LABEL_SELECT, "Choose devices by label in device discovery", value_type=SelectionRule), 

97 DeliveryOption( 

98 OPTION_DEVICE_AREA_SELECT, 

99 "Choose devices by Home Assistant area in device discovery", 

100 value_type=SelectionRule, 

101 ), 

102] 

103 

104# Only meaningful for transports that call Envelope.grab_image() - not read at all otherwise, 

105# so not universal like COMMON_OPTIONS. Transports splice this into their own declared_options. 

106MEDIA_OPTIONS: list[DeliveryOption] = [ 

107 DeliveryOption( 

108 OPTION_JPEG, 

109 "Tune camera snapshot grabs saved/attached as JPEG", 

110 value_type=dict, 

111 examples=["progressive: true", "optimize: true", "quality: 50"], 

112 ), 

113 DeliveryOption( 

114 OPTION_PNG, "Tune camera snapshot grabs saved/attached as PNG", value_type=dict, examples=["optimize: true"] 

115 ), 

116 DeliveryOption( 

117 MEDIA_OPTION_REPROCESS, 

118 "Whether to regenerate a camera snapshot already grabbed for this notification", 

119 value_type=vol.In({ 

120 "always": "Always regenerate", 

121 "never": "Reuse the existing grab", 

122 "preserve": "Keep the original file", 

123 }), 

124 ), 

125] 

126 

127# for a transport passing on what's left of the notification's `data` to the integration 

128DATA_KEYS_SELECT_OPTION = DeliveryOption( 

129 OPTION_DATA_KEYS_SELECT, 

130 "Prune the data block by including/excluding values or by regex pattern", 

131 value_type=SelectionRule, 

132) 

133 

134 

135def all_options_for(transport_options: list[DeliveryOption]) -> list[DeliveryOption]: 

136 """Common options plus a transport's own — the full applicable set for one transport.""" 

137 return [*COMMON_OPTIONS, *transport_options]