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

38 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-09-25 21:14 +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 

19import voluptuous as vol 

20from homeassistant.helpers import config_validation as cv 

21 

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_UNIQUE_TARGETS = "unique_targets" 

29OPTION_TARGET_SELECT = "target_select" 

30OPTION_DATA_KEYS_SELECT = "data_keys_select" 

31OPTION_DEVICE_DOMAIN = "device_domain" 

32OPTION_DEVICE_MODEL_SELECT = "device_model_select" 

33OPTION_DEVICE_MANUFACTURER_SELECT = "device_manufacturer_select" 

34OPTION_DEVICE_OS_SELECT = "device_os_select" 

35OPTION_DEVICE_LABEL_SELECT = "device_label_select" 

36OPTION_DEVICE_AREA_SELECT = "device_area_select" 

37OPTION_DEVICE_DISCOVERY = "device_discovery" 

38OPTION_JPEG = "jpeg_opts" 

39OPTION_PNG = "png_opts" 

40MEDIA_OPTION_REPROCESS = "reprocess" 

41 

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

43SELECT_INCLUDE = "include" 

44SELECT_EXCLUDE = "exclude" 

45 

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

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

48OPTION_TARGET_INCLUDE_RE = "target_include_re" 

49OPTION_DATA_KEYS_INCLUDE_RE = "data_keys_include_re" 

50OPTION_DATA_KEYS_EXCLUDE_RE = "data_keys_exclude_re" 

51 

52 

53@dataclass(frozen=True) 

54class DeliveryOption: 

55 key: str 

56 description: str 

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

58 examples: list[str] | None = None 

59 

60 

61COMMON_OPTIONS: list[DeliveryOption] = [ 

62 DeliveryOption( 

63 OPTION_SIMPLIFY_TEXT, 

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

65 value_type=cv.boolean, 

66 ), 

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

68 DeliveryOption(OPTION_MESSAGE_USAGE, "Combine message and title, default title", examples=["combine_title", "use_title"]), 

69 DeliveryOption( 

70 OPTION_TARGET_SELECT, 

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

72 value_type=SelectionRule, 

73 ), 

74 DeliveryOption( 

75 OPTION_UNIQUE_TARGETS, 

76 "Don't pass targets already used in this notification", 

77 value_type=cv.boolean, 

78 ), 

79 DeliveryOption( 

80 OPTION_TARGET_CATEGORIES, 

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

82 value_type=list, 

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

84 ), 

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

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

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

88 DeliveryOption( 

89 OPTION_DEVICE_MANUFACTURER_SELECT, 

90 "Choose device manufacturers in device discovery", 

91 value_type=SelectionRule, 

92 ), 

93 DeliveryOption( 

94 OPTION_DEVICE_OS_SELECT, 

95 "Choose device operating systems in device discovery", 

96 value_type=SelectionRule, 

97 ), 

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

99 DeliveryOption( 

100 OPTION_DEVICE_AREA_SELECT, 

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

102 value_type=SelectionRule, 

103 ), 

104] 

105 

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

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

108MEDIA_OPTIONS: list[DeliveryOption] = [ 

109 DeliveryOption( 

110 OPTION_JPEG, 

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

112 value_type=dict, 

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

114 ), 

115 DeliveryOption( 

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

117 ), 

118 DeliveryOption( 

119 MEDIA_OPTION_REPROCESS, 

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

121 value_type=vol.In({ 

122 "always": "Always regenerate", 

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

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

125 }), 

126 ), 

127] 

128 

129 

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

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

132 return [*COMMON_OPTIONS, *transport_options]