1 """Helper methods to help with platform discovery.
3 There are two different types of discoveries that can be fired/listened for.
4 - listen/discover is for services. These are targeted at a component.
5 - listen_platform/discover_platform is for platforms. These are used by
6 components to allow discovery of their platforms.
9 from __future__
import annotations
11 from collections.abc
import Callable, Coroutine
12 from typing
import Any, TypedDict
14 from homeassistant
import core, setup
19 from .dispatcher
import async_dispatcher_connect, async_dispatcher_send_internal
20 from .typing
import ConfigType, DiscoveryInfoType
22 SIGNAL_PLATFORM_DISCOVERED: SignalTypeFormat[DiscoveryDict] =
SignalTypeFormat(
23 "discovery.platform_discovered_{}"
25 EVENT_LOAD_PLATFORM =
"load_platform.{}"
26 ATTR_PLATFORM =
"platform"
27 ATTR_DISCOVERED =
"discovered"
35 discovered: DiscoveryInfoType |
None
41 hass: core.HomeAssistant,
44 [str, DiscoveryInfoType |
None], Coroutine[Any, Any,
None] |
None
47 """Set up listener for discovery of specific service.
49 Service can be a string or a list/tuple.
51 job =
core.HassJob(callback, f
"discovery listener {service}")
54 def _async_discovery_event_listener(discovered: DiscoveryDict) ->
None:
55 """Listen for discovery events."""
56 hass.async_run_hass_job(job, discovered[
"service"], discovered[
"discovered"])
60 SIGNAL_PLATFORM_DISCOVERED.format(service),
61 _async_discovery_event_listener,
67 hass: core.HomeAssistant,
69 discovered: DiscoveryInfoType,
71 hass_config: ConfigType,
73 """Fire discovery event. Can ensure a component is loaded."""
76 f
"discover {service} {component} {discovered}",
82 hass: core.HomeAssistant,
84 discovered: DiscoveryInfoType |
None,
85 component: str |
None,
86 hass_config: ConfigType,
88 """Fire discovery event. Can ensure a component is loaded."""
89 if component
is not None and component
not in hass.config.components:
90 await setup.async_setup_component(hass, component, hass_config)
92 data: DiscoveryDict = {
95 "discovered": discovered,
98 async_dispatcher_send_internal(
99 hass, SIGNAL_PLATFORM_DISCOVERED.format(service), data
105 hass: core.HomeAssistant,
107 callback: Callable[[str, dict[str, Any] |
None], Any],
108 ) -> Callable[[],
None]:
109 """Register a platform loader listener.
111 This method must be run in the event loop.
113 service = EVENT_LOAD_PLATFORM.format(component)
114 job =
core.HassJob(callback, f
"platform loaded {component}")
117 def _async_discovery_platform_listener(discovered: DiscoveryDict) ->
None:
118 """Listen for platform discovery events."""
119 if not (platform := discovered[
"platform"]):
121 hass.async_run_hass_job(job, platform, discovered.get(
"discovered"))
125 SIGNAL_PLATFORM_DISCOVERED.format(service),
126 _async_discovery_platform_listener,
132 hass: core.HomeAssistant,
133 component: Platform | str,
135 discovered: DiscoveryInfoType |
None,
136 hass_config: ConfigType,
138 """Load a component and platform dynamically."""
141 f
"discovery load_platform {component} {platform}",
147 hass: core.HomeAssistant,
148 component: Platform | str,
150 discovered: DiscoveryInfoType |
None,
151 hass_config: ConfigType,
153 """Load a component and platform dynamically.
155 Use `async_listen_platform` to register a callback for these events.
157 Warning: This method can load a base component if its not loaded which
158 can take a long time since base components currently have to import
159 every platform integration listed under it to do config validation.
160 To avoid waiting for this, use
161 `hass.async_create_task(async_load_platform(..))` instead.
163 assert hass_config
is not None,
"You need to pass in the real hass config"
167 if component
not in hass.config.components:
168 setup_success = await setup.async_setup_component(hass, component, hass_config)
171 if not setup_success:
174 service = EVENT_LOAD_PLATFORM.format(component)
176 data: DiscoveryDict = {
178 "platform": platform,
179 "discovered": discovered,
182 async_dispatcher_send_internal(
183 hass, SIGNAL_PLATFORM_DISCOVERED.format(service), data
None discover(core.HomeAssistant hass, str service, DiscoveryInfoType discovered, str component, ConfigType hass_config)
None async_load_platform(core.HomeAssistant hass, Platform|str component, str platform, DiscoveryInfoType|None discovered, ConfigType hass_config)
None load_platform(core.HomeAssistant hass, Platform|str component, str platform, DiscoveryInfoType|None discovered, ConfigType hass_config)
None async_discover(core.HomeAssistant hass, str service, DiscoveryInfoType|None discovered, str|None component, ConfigType hass_config)
None async_listen(core.HomeAssistant hass, str service, Callable[[str, DiscoveryInfoType|None], Coroutine[Any, Any, None]|None] callback)
Callable[[], None] async_listen_platform(core.HomeAssistant hass, str component, Callable[[str, dict[str, Any]|None], Any] callback)
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)