Coverage for custom_components/supernotify/options.py: 97%
38 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-09-25 14:29 +0000
« prev ^ index » next coverage.py v7.15.4, created at 2026-09-25 14:29 +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
19import voluptuous as vol
20from homeassistant.helpers import config_validation as cv
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_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"
42# Domain of a SelectionRule-typed option's mapping, e.g. {SELECT_INCLUDE: [...], SELECT_EXCLUDE: [...]}
43SELECT_INCLUDE = "include"
44SELECT_EXCLUDE = "exclude"
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"
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
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]
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]
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]