Coverage for custom_components/supernotify/transports/alexa_media_player.py: 53%
36 statements
« prev ^ index » next coverage.py v7.10.6, created at 2026-01-07 15:35 +0000
« prev ^ index » next coverage.py v7.10.6, created at 2026-01-07 15:35 +0000
1import logging
2from typing import Any
4from homeassistant.components.notify.const import ATTR_DATA, ATTR_TARGET
5from homeassistant.const import ATTR_ENTITY_ID
7from custom_components.supernotify import (
8 OPTION_MESSAGE_USAGE,
9 OPTION_SIMPLIFY_TEXT,
10 OPTION_STRIP_URLS,
11 OPTION_TARGET_CATEGORIES,
12 OPTION_TARGET_SELECT,
13 OPTION_UNIQUE_TARGETS,
14 TRANSPORT_ALEXA_MEDIA_PLAYER,
15)
16from custom_components.supernotify.envelope import Envelope
17from custom_components.supernotify.model import DebugTrace, MessageOnlyPolicy, TargetRequired, TransportConfig, TransportFeature
18from custom_components.supernotify.transport import (
19 Transport,
20)
22RE_VALID_ALEXA = r"media_player\.[A-Za-z0-9_]+"
24_LOGGER = logging.getLogger(__name__)
27class AlexaMediaPlayerTransport(Transport):
28 """Notify via Amazon Alexa announcements
30 options:
31 message_usage: standard | use_title | combine_title
33 """
35 name = TRANSPORT_ALEXA_MEDIA_PLAYER
37 def __init__(self, *args: Any, **kwargs: Any) -> None:
38 super().__init__(*args, **kwargs)
40 @property
41 def supported_features(self) -> TransportFeature:
42 return TransportFeature.MESSAGE
44 @property
45 def default_config(self) -> TransportConfig:
46 config = TransportConfig()
47 config.delivery_defaults.action = "notify.alexa_media"
48 config.delivery_defaults.target_required = TargetRequired.ALWAYS
49 config.delivery_defaults.options = {
50 OPTION_SIMPLIFY_TEXT: True,
51 OPTION_STRIP_URLS: True,
52 OPTION_MESSAGE_USAGE: MessageOnlyPolicy.STANDARD,
53 OPTION_UNIQUE_TARGETS: True,
54 OPTION_TARGET_CATEGORIES: [ATTR_ENTITY_ID],
55 OPTION_TARGET_SELECT: [RE_VALID_ALEXA],
56 }
57 return config
59 def validate_action(self, action: str | None) -> bool:
60 """Override in subclass if transport has fixed action or doesn't require one"""
61 return action is not None
63 async def deliver(self, envelope: Envelope, debug_trace: DebugTrace | None = None) -> bool: # noqa: ARG002
64 _LOGGER.debug("SUPERNOTIFY notify_alexa_media %s", envelope.message)
66 media_players = envelope.target.entity_ids or []
68 if not media_players:
69 _LOGGER.debug("SUPERNOTIFY skipping alexa media player, no targets")
70 return False
72 action_data: dict[str, Any] = {"message": envelope.message, ATTR_DATA: {"type": "announce"}, ATTR_TARGET: media_players}
73 # alexa media player expects a non-std list as target, so don't use notify target arg (which expects dict)
74 if envelope.data and envelope.data.get("data"):
75 action_data[ATTR_DATA].update(envelope.data.get("data"))
76 return await self.call_action(envelope, action_data=action_data)