Coverage for custom_components/supernotify/transports/notify_entity.py: 100%
41 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
1from __future__ import annotations
3import logging
4from typing import TYPE_CHECKING, Any
6from homeassistant.const import ATTR_ENTITY_ID
7from homeassistant.helpers.typing import ConfigType
9from custom_components.supernotify.const import (
10 RE_NOTIFY_ENTITY_ID,
11 TRANSPORT_NOTIFY_ENTITY,
12)
13from custom_components.supernotify.model import (
14 DebugTrace,
15 MessageOnlyPolicy,
16 TransportConfig,
17 TransportFeature,
18)
19from custom_components.supernotify.options import (
20 OPTION_MESSAGE_USAGE,
21 OPTION_SIMPLIFY_TEXT,
22 OPTION_STRIP_URLS,
23 OPTION_TARGET_SELECT,
24)
25from custom_components.supernotify.target import TargetEntityCategory
26from custom_components.supernotify.transport import (
27 Transport,
28)
30if TYPE_CHECKING:
31 from custom_components.supernotify.envelope import Envelope
32 from custom_components.supernotify.hass_api import HomeAssistantAPI
34_LOGGER = logging.getLogger(__name__)
37FIXED_ACTION = "notify.send_message"
40class NotifyEntityTransport(Transport):
41 """Call any notify entity"""
43 name = TRANSPORT_NOTIFY_ENTITY
44 integration_domain = "notify"
46 def __init__(self, *args: Any, **kwargs: Any) -> None:
47 super().__init__(*args, **kwargs)
49 @property
50 def supported_features(self) -> TransportFeature:
51 return TransportFeature.MESSAGE | TransportFeature.TITLE
53 @property
54 def default_config(self) -> TransportConfig:
55 config = super().default_config
56 config.delivery_defaults.action = FIXED_ACTION
57 config.delivery_defaults.options = {
58 OPTION_SIMPLIFY_TEXT: False,
59 OPTION_STRIP_URLS: False,
60 OPTION_MESSAGE_USAGE: MessageOnlyPolicy.STANDARD,
61 OPTION_TARGET_SELECT: [RE_NOTIFY_ENTITY_ID],
62 }
63 return config
65 @property
66 def fallback_target_categories(self) -> list[str | TargetEntityCategory]:
67 # no platform restriction - the generic catch-all for any notify.* entity not
68 # claimed by a more specific transport (html5, alexa_devices) - being `fallback`
69 # rather than `unique` is what gives those first refusal, both for selection
70 # (Notification.select_deliveries()) and ranking (default_selection_rank())
71 return [TargetEntityCategory(domain="notify")]
73 def is_viable(self, hass_api: HomeAssistantAPI) -> bool:
74 return bool(hass_api.entity_ids_for_domain("notify"))
76 def build_standard_deliveries(self, hass_api: HomeAssistantAPI) -> dict[str, ConfigType]:
77 return {self.name: {}}
79 async def deliver(self, envelope: Envelope, debug_trace: DebugTrace | None = None) -> bool:
80 targets = envelope.target.entity_ids or []
81 if not targets:
82 _LOGGER.warning("SUPERNOTIFY notify_entity: no targets")
83 return False
84 # area_id/floor_id/label_id targets have already been resolved to entities, see Target.resolve_selectors
85 target_data: dict[str, Any] = {ATTR_ENTITY_ID: targets}
86 action_data = envelope.core_action_data()
88 return await self.call_action(envelope, FIXED_ACTION, action_data=action_data, target_data=target_data)