1 """Handle legacy notification platforms."""
3 from __future__
import annotations
6 from collections.abc
import Coroutine, Mapping
7 from functools
import partial
8 from typing
import Any, Protocol, cast
20 async_prepare_setup_platform,
34 NOTIFY_SERVICE_SCHEMA,
38 CONF_FIELDS =
"fields"
39 NOTIFY_SERVICES: HassKey[dict[str, list[BaseNotificationService]]] =
HassKey(
42 NOTIFY_DISCOVERY_DISPATCHER: HassKey[CALLBACK_TYPE |
None] =
HassKey(
43 f
"{DOMAIN}_discovery_dispatcher"
48 """Define the format of legacy notify platforms."""
54 discovery_info: DiscoveryInfoType |
None = ...,
55 ) -> BaseNotificationService |
None:
56 """Set up notification service."""
62 discovery_info: DiscoveryInfoType |
None = ...,
63 ) -> BaseNotificationService |
None:
64 """Set up notification service."""
69 hass: HomeAssistant, config: ConfigType
70 ) -> list[Coroutine[Any, Any,
None]]:
71 """Set up legacy notify services."""
72 hass.data.setdefault(NOTIFY_SERVICES, {})
73 hass.data.setdefault(NOTIFY_DISCOVERY_DISPATCHER,
None)
76 integration_name: str,
77 p_config: ConfigType |
None =
None,
78 discovery_info: DiscoveryInfoType |
None =
None,
80 """Set up a notify platform."""
85 LegacyNotifyPlatform |
None,
90 LOGGER.error(
"Unknown notification service specified")
93 full_name = f
"{DOMAIN}.{integration_name}"
94 LOGGER.info(
"Setting up %s", full_name)
97 integration=integration_name,
98 group=
str(id(p_config)),
99 phase=SetupPhases.PLATFORM_SETUP,
101 notify_service: BaseNotificationService |
None =
None
103 if hasattr(platform,
"async_get_service"):
104 notify_service = await platform.async_get_service(
105 hass, p_config, discovery_info
107 elif hasattr(platform,
"get_service"):
108 notify_service = await hass.async_add_executor_job(
109 platform.get_service, hass, p_config, discovery_info
114 if notify_service
is None:
117 if discovery_info
is None:
119 "Failed to initialize notification service %s",
125 LOGGER.exception(
"Error setting up platform %s", integration_name)
128 if discovery_info
is None:
131 conf_name = p_config.get(CONF_NAME)
or discovery_info.get(CONF_NAME)
132 target_service_name_prefix = conf_name
or integration_name
133 service_name =
slugify(conf_name
or SERVICE_NOTIFY)
135 await notify_service.async_setup(
136 hass, service_name, target_service_name_prefix
138 await notify_service.async_register_services()
140 hass.data[NOTIFY_SERVICES].setdefault(integration_name, []).append(
143 hass.config.components.add(f
"{integration_name}.{DOMAIN}")
145 async
def async_platform_discovered(
146 platform: str, info: DiscoveryInfoType |
None
148 """Handle for discovered platform."""
151 hass.data[NOTIFY_DISCOVERY_DISPATCHER] = discovery.async_listen_platform(
152 hass, DOMAIN, async_platform_discovered
158 if integration_name
is not None
163 async
def async_reload(hass: HomeAssistant, integration_name: str) ->
None:
164 """Register notify services for an integration."""
169 notify_service.async_register_services()
170 for notify_service
in hass.data[NOTIFY_SERVICES][integration_name]
173 await asyncio.gather(*tasks)
178 """Unregister notify services for an integration."""
179 notify_discovery_dispatcher = hass.data.get(NOTIFY_DISCOVERY_DISPATCHER)
180 if notify_discovery_dispatcher:
181 notify_discovery_dispatcher()
182 hass.data[NOTIFY_DISCOVERY_DISPATCHER] =
None
187 notify_service.async_unregister_services()
188 for notify_service
in hass.data[NOTIFY_SERVICES][integration_name]
191 await asyncio.gather(*tasks)
193 del hass.data[NOTIFY_SERVICES][integration_name]
197 hass: HomeAssistant, integration_name: str
199 """Determine if an integration has notify services registered."""
201 NOTIFY_SERVICES
not in hass.data
202 or integration_name
not in hass.data[NOTIFY_SERVICES]
210 """An abstract class for notification services."""
214 hass: HomeAssistant =
None
217 registered_targets: dict[str, Any]
220 def targets(self) -> Mapping[str, Any] | None:
221 """Return a dictionary of registered targets."""
227 kwargs can contain ATTR_TITLE to specify a title.
229 raise NotImplementedError
234 kwargs can contain ATTR_TITLE to specify a title.
236 await self.
hasshass.async_add_executor_job(
237 partial(self.
send_messagesend_message, message, **kwargs)
241 """Handle sending notification message service calls."""
243 message: str = service.data[ATTR_MESSAGE]
245 if title := service.data.get(ATTR_TITLE):
246 kwargs[ATTR_TITLE] = title
250 elif service.data.get(ATTR_TARGET)
is not None:
251 kwargs[ATTR_TARGET] = service.data.get(ATTR_TARGET)
253 kwargs[ATTR_MESSAGE] = message
254 kwargs[ATTR_DATA] = service.data.get(ATTR_DATA)
262 target_service_name_prefix: str,
264 """Store the data for the notify service."""
273 services_yaml = integration.file_path /
"services.yaml"
275 load_yaml_dict,
str(services_yaml)
279 """Create or update the notify services."""
280 if self.
targetstargets
is not None:
283 for name, target
in self.
targetstargets.items():
284 target_name =
slugify(f
"{self._target_service_name_prefix}_{name}")
285 if target_name
in stale_targets:
286 stale_targets.remove(target_name)
293 self.
hasshass.services.async_register(
297 schema=NOTIFY_SERVICE_SCHEMA,
301 CONF_NAME: f
"Send a notification via {target_name}",
303 "Sends a notification message using the"
304 f
" {target_name} integration."
306 CONF_FIELDS: self.
services_dictservices_dict[SERVICE_NOTIFY][CONF_FIELDS],
310 for stale_target_name
in stale_targets:
312 self.
hasshass.services.async_remove(
320 self.
hasshass.services.async_register(
324 schema=NOTIFY_SERVICE_SCHEMA,
329 CONF_NAME: f
"Send a notification with {self._service_name}",
331 f
"Sends a notification message using the {self._service_name} service."
333 CONF_FIELDS: self.
services_dictservices_dict[SERVICE_NOTIFY][CONF_FIELDS],
338 """Unregister the notify services."""
341 for remove_target_name
in remove_targets:
343 self.
hasshass.services.async_remove(
348 if not self.
hasshass.services.has_service(DOMAIN, self.
_service_name_service_name):
351 self.
hasshass.services.async_remove(
Mapping[str, Any]|None targets(self)
None async_send_message(self, str message, **Any kwargs)
None _async_notify_message_service(self, ServiceCall service)
None send_message(self, str message, **Any kwargs)
None async_setup(self, HomeAssistant hass, str service_name, str target_service_name_prefix)
None async_unregister_services(self)
None async_register_services(self)
_target_service_name_prefix
None async_setup_platform(HomeAssistant hass, ConfigType config, AddEntitiesCallback async_add_entities, DiscoveryInfoType|None discovery_info=None)
AppriseNotificationService|None get_service(HomeAssistant hass, ConfigType config, DiscoveryInfoType|None discovery_info=None)
web.Response get(self, web.Request request, str config_key)
None async_reload(HomeAssistant hass, str integration_name)
list[Coroutine[Any, Any, None]] async_setup_legacy(HomeAssistant hass, ConfigType config)
bool _async_integration_has_notify_services(HomeAssistant hass, str integration_name)
None async_reset_platform(HomeAssistant hass, str integration_name)
Iterable[tuple[str|None, ConfigType]] config_per_platform(ConfigType config, str domain)
None async_set_service_schema(HomeAssistant hass, str domain, str service, dict[str, Any] schema)
Integration async_get_integration(HomeAssistant hass, str domain)
ModuleType|None async_prepare_setup_platform(core.HomeAssistant hass, ConfigType hass_config, str domain, str platform_name)
Generator[None] async_start_setup(core.HomeAssistant hass, str integration, SetupPhases phase, str|None group=None)