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
« 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.
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.
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"""
14from __future__ import annotations
16from collections.abc import Callable
17from dataclasses import dataclass
19from homeassistant.helpers import config_validation as cv
21from custom_components.supernotify.compat import vol
22from custom_components.supernotify.model import SelectionRule
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"
41# Domain of a SelectionRule-typed option's mapping, e.g. {SELECT_INCLUDE: [...], SELECT_EXCLUDE: [...]}
42SELECT_INCLUDE = "include"
43SELECT_EXCLUDE = "exclude"
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"
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
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]
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]
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)
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]