Home Assistant Unofficial Reference 2024.12.1
__init__.py
Go to the documentation of this file.
1 """Support for MQTT message handling."""
2 
3 from __future__ import annotations
4 
5 import asyncio
6 from collections.abc import Callable
7 from datetime import datetime
8 import logging
9 from typing import TYPE_CHECKING, Any, cast
10 
11 import voluptuous as vol
12 
13 from homeassistant import config as conf_util
14 from homeassistant.components import websocket_api
15 from homeassistant.config_entries import ConfigEntry
16 from homeassistant.const import CONF_DISCOVERY, CONF_PAYLOAD, SERVICE_RELOAD
17 from homeassistant.core import HomeAssistant, ServiceCall, callback
18 from homeassistant.exceptions import (
19  ConfigValidationError,
20  ServiceValidationError,
21  Unauthorized,
22 )
23 from homeassistant.helpers import (
24  config_validation as cv,
25  entity_registry as er,
26  event as ev,
27  issue_registry as ir,
28  template,
29 )
30 from homeassistant.helpers.device_registry import DeviceEntry
31 from homeassistant.helpers.dispatcher import async_dispatcher_connect
32 from homeassistant.helpers.entity_platform import async_get_platforms
33 from homeassistant.helpers.reload import async_integration_yaml_config
34 from homeassistant.helpers.service import async_register_admin_service
35 from homeassistant.helpers.typing import ConfigType
36 from homeassistant.loader import async_get_integration, async_get_loaded_integration
37 from homeassistant.setup import SetupPhases, async_pause_setup
38 from homeassistant.util.async_ import create_eager_task
39 
40 # Loading the config flow file will register the flow
41 from . import debug_info, discovery
42 from .client import ( # noqa: F401
43  MQTT,
44  async_publish,
45  async_subscribe,
46  async_subscribe_internal,
47  publish,
48  subscribe,
49 )
50 from .config import MQTT_BASE_SCHEMA, MQTT_RO_SCHEMA, MQTT_RW_SCHEMA # noqa: F401
51 from .config_integration import CONFIG_SCHEMA_BASE
52 from .const import ( # noqa: F401
53  ATTR_PAYLOAD,
54  ATTR_QOS,
55  ATTR_RETAIN,
56  ATTR_TOPIC,
57  CONF_BIRTH_MESSAGE,
58  CONF_BROKER,
59  CONF_CERTIFICATE,
60  CONF_CLIENT_CERT,
61  CONF_CLIENT_KEY,
62  CONF_COMMAND_TOPIC,
63  CONF_DISCOVERY_PREFIX,
64  CONF_KEEPALIVE,
65  CONF_QOS,
66  CONF_STATE_TOPIC,
67  CONF_TLS_INSECURE,
68  CONF_TOPIC,
69  CONF_TRANSPORT,
70  CONF_WILL_MESSAGE,
71  CONF_WS_HEADERS,
72  CONF_WS_PATH,
73  DEFAULT_DISCOVERY,
74  DEFAULT_ENCODING,
75  DEFAULT_PREFIX,
76  DEFAULT_QOS,
77  DEFAULT_RETAIN,
78  DOMAIN,
79  ENTITY_PLATFORMS,
80  MQTT_CONNECTION_STATE,
81  TEMPLATE_ERRORS,
82 )
83 from .models import ( # noqa: F401
84  DATA_MQTT,
85  DATA_MQTT_AVAILABLE,
86  MqttCommandTemplate,
87  MqttData,
88  MqttValueTemplate,
89  PayloadSentinel,
90  PublishPayloadType,
91  ReceiveMessage,
92  convert_outgoing_mqtt_payload,
93 )
94 from .subscription import ( # noqa: F401
95  EntitySubscription,
96  async_prepare_subscribe_topics,
97  async_subscribe_topics,
98  async_unsubscribe_topics,
99 )
100 from .util import ( # noqa: F401
101  async_create_certificate_temp_files,
102  async_forward_entry_setup_and_setup_discovery,
103  async_wait_for_mqtt_client,
104  mqtt_config_entry_enabled,
105  platforms_from_config,
106  valid_publish_topic,
107  valid_qos_schema,
108  valid_subscribe_topic,
109 )
110 
111 _LOGGER = logging.getLogger(__name__)
112 
113 SERVICE_PUBLISH = "publish"
114 SERVICE_DUMP = "dump"
115 
116 ATTR_TOPIC_TEMPLATE = "topic_template"
117 ATTR_PAYLOAD_TEMPLATE = "payload_template"
118 ATTR_EVALUATE_PAYLOAD = "evaluate_payload"
119 
120 MAX_RECONNECT_WAIT = 300 # seconds
121 
122 CONNECTION_SUCCESS = "connection_success"
123 CONNECTION_FAILED = "connection_failed"
124 CONNECTION_FAILED_RECOVERABLE = "connection_failed_recoverable"
125 
126 # We accept 2 schemes for configuring manual MQTT items
127 #
128 # Preferred style:
129 #
130 # mqtt:
131 # - {domain}:
132 # name: ""
133 # ...
134 # - {domain}:
135 # name: ""
136 # ...
137 # ```
138 #
139 # Legacy supported style:
140 #
141 # mqtt:
142 # {domain}:
143 # - name: ""
144 # ...
145 # - name: ""
146 # ...
147 CONFIG_SCHEMA = vol.Schema(
148  {
149  DOMAIN: vol.All(
150  cv.ensure_list,
151  cv.remove_falsy,
152  [CONFIG_SCHEMA_BASE],
153  )
154  },
155  extra=vol.ALLOW_EXTRA,
156 )
157 
158 
159 # The use of a topic_template and payload_template in an mqtt publish action call
160 # have been deprecated with HA Core 2024.8.0 and will be removed with HA Core 2025.2.0
161 
162 # Publish action call validation schema
163 MQTT_PUBLISH_SCHEMA = vol.All(
164  vol.Schema(
165  {
166  vol.Exclusive(ATTR_TOPIC, CONF_TOPIC): valid_publish_topic,
167  vol.Exclusive(ATTR_TOPIC_TEMPLATE, CONF_TOPIC): cv.string,
168  vol.Exclusive(ATTR_PAYLOAD, CONF_PAYLOAD): cv.string,
169  vol.Exclusive(ATTR_PAYLOAD_TEMPLATE, CONF_PAYLOAD): cv.string,
170  vol.Optional(ATTR_EVALUATE_PAYLOAD): cv.boolean,
171  vol.Optional(ATTR_QOS, default=DEFAULT_QOS): valid_qos_schema,
172  vol.Optional(ATTR_RETAIN, default=DEFAULT_RETAIN): cv.boolean,
173  },
174  required=True,
175  ),
176  cv.has_at_least_one_key(ATTR_TOPIC, ATTR_TOPIC_TEMPLATE),
177 )
178 
179 
180 async def _async_config_entry_updated(hass: HomeAssistant, entry: ConfigEntry) -> None:
181  """Handle signals of config entry being updated.
182 
183  Causes for this is config entry options changing.
184  """
185  await hass.config_entries.async_reload(entry.entry_id)
186 
187 
188 @callback
189 def _async_remove_mqtt_issues(hass: HomeAssistant, mqtt_data: MqttData) -> None:
190  """Unregister open config issues."""
191  issue_registry = ir.async_get(hass)
192  open_issues = [
193  issue_id
194  for (domain, issue_id), issue_entry in issue_registry.issues.items()
195  if domain == DOMAIN and issue_entry.translation_key == "invalid_platform_config"
196  ]
197  for issue in open_issues:
198  ir.async_delete_issue(hass, DOMAIN, issue)
199 
200 
202  hass: HomeAssistant, config_yaml: ConfigType
203 ) -> None:
204  """Validate manually configured MQTT items."""
205  mqtt_data = hass.data[DATA_MQTT]
206  mqtt_config: list[dict[str, list[ConfigType]]] = config_yaml.get(DOMAIN, {})
207  for mqtt_config_item in mqtt_config:
208  for domain, config_items in mqtt_config_item.items():
209  schema = mqtt_data.reload_schema[domain]
210  for config in config_items:
211  try:
212  schema(config)
213  except vol.Invalid as exc:
214  integration = await async_get_integration(hass, DOMAIN)
215  message = conf_util.format_schema_error(
216  hass, exc, domain, config, integration.documentation
217  )
219  message,
220  translation_domain=DOMAIN,
221  translation_key="invalid_platform_config",
222  translation_placeholders={
223  "domain": domain,
224  },
225  ) from exc
226 
227 
228 async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
229  """Set up the actions and websocket API for the MQTT component."""
230 
231  websocket_api.async_register_command(hass, websocket_subscribe)
232  websocket_api.async_register_command(hass, websocket_mqtt_info)
233 
234  async def async_publish_service(call: ServiceCall) -> None:
235  """Handle MQTT publish service calls."""
236  msg_topic: str | None = call.data.get(ATTR_TOPIC)
237  msg_topic_template: str | None = call.data.get(ATTR_TOPIC_TEMPLATE)
238 
239  if not mqtt_config_entry_enabled(hass):
241  translation_key="mqtt_not_setup_cannot_publish",
242  translation_domain=DOMAIN,
243  translation_placeholders={
244  "topic": str(msg_topic or msg_topic_template)
245  },
246  )
247 
248  mqtt_data = hass.data[DATA_MQTT]
249  payload: PublishPayloadType = call.data.get(ATTR_PAYLOAD)
250  evaluate_payload: bool = call.data.get(ATTR_EVALUATE_PAYLOAD, False)
251  payload_template: str | None = call.data.get(ATTR_PAYLOAD_TEMPLATE)
252  qos: int = call.data[ATTR_QOS]
253  retain: bool = call.data[ATTR_RETAIN]
254  if msg_topic_template is not None:
255  # The use of a topic_template in an mqtt publish action call
256  # has been deprecated with HA Core 2024.8.0
257  # and will be removed with HA Core 2025.2.0
258  rendered_topic: Any = MqttCommandTemplate(
259  template.Template(msg_topic_template, hass),
260  ).async_render()
261  ir.async_create_issue(
262  hass,
263  DOMAIN,
264  f"topic_template_deprecation_{rendered_topic}",
265  breaks_in_ha_version="2025.2.0",
266  is_fixable=False,
267  severity=ir.IssueSeverity.WARNING,
268  translation_key="topic_template_deprecation",
269  translation_placeholders={
270  "topic_template": msg_topic_template,
271  "topic": rendered_topic,
272  },
273  )
274  try:
275  msg_topic = valid_publish_topic(rendered_topic)
276  except vol.Invalid as err:
277  err_str = str(err)
279  translation_domain=DOMAIN,
280  translation_key="invalid_publish_topic",
281  translation_placeholders={
282  "error": err_str,
283  "topic": str(rendered_topic),
284  "topic_template": str(msg_topic_template),
285  },
286  ) from err
287 
288  if payload_template is not None:
289  # The use of a payload_template in an mqtt publish action call
290  # has been deprecated with HA Core 2024.8.0
291  # and will be removed with HA Core 2025.2.0
292  if TYPE_CHECKING:
293  assert msg_topic is not None
294  ir.async_create_issue(
295  hass,
296  DOMAIN,
297  f"payload_template_deprecation_{msg_topic}",
298  breaks_in_ha_version="2025.2.0",
299  is_fixable=False,
300  severity=ir.IssueSeverity.WARNING,
301  translation_key="payload_template_deprecation",
302  translation_placeholders={
303  "topic": msg_topic,
304  "payload_template": payload_template,
305  },
306  )
307  payload = MqttCommandTemplate(
308  template.Template(payload_template, hass)
309  ).async_render()
310  elif evaluate_payload:
311  # Convert quoted binary literal to raw data
312  payload = convert_outgoing_mqtt_payload(payload)
313 
314  if TYPE_CHECKING:
315  assert msg_topic is not None
316  await mqtt_data.client.async_publish(msg_topic, payload, qos, retain)
317 
318  hass.services.async_register(
319  DOMAIN, SERVICE_PUBLISH, async_publish_service, schema=MQTT_PUBLISH_SCHEMA
320  )
321 
322  async def async_dump_service(call: ServiceCall) -> None:
323  """Handle MQTT dump service calls."""
324  messages: list[tuple[str, str]] = []
325 
326  @callback
327  def collect_msg(msg: ReceiveMessage) -> None:
328  messages.append((msg.topic, str(msg.payload).replace("\n", "")))
329 
330  unsub = async_subscribe_internal(hass, call.data["topic"], collect_msg)
331 
332  def write_dump() -> None:
333  with open(hass.config.path("mqtt_dump.txt"), "w", encoding="utf8") as fp:
334  for msg in messages:
335  fp.write(",".join(msg) + "\n")
336 
337  async def finish_dump(_: datetime) -> None:
338  """Write dump to file."""
339  unsub()
340  await hass.async_add_executor_job(write_dump)
341 
342  ev.async_call_later(hass, call.data["duration"], finish_dump)
343 
344  hass.services.async_register(
345  DOMAIN,
346  SERVICE_DUMP,
347  async_dump_service,
348  schema=vol.Schema(
349  {
350  vol.Required("topic"): valid_subscribe_topic,
351  vol.Optional("duration", default=5): int,
352  }
353  ),
354  )
355  return True
356 
357 
358 async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
359  """Load a config entry."""
360  conf: dict[str, Any]
361  mqtt_data: MqttData
362 
363  async def _setup_client() -> tuple[MqttData, dict[str, Any]]:
364  """Set up the MQTT client."""
365  # Fetch configuration
366  conf = dict(entry.data)
367  hass_config = await conf_util.async_hass_config_yaml(hass)
368  mqtt_yaml = CONFIG_SCHEMA(hass_config).get(DOMAIN, [])
369  await async_create_certificate_temp_files(hass, conf)
370  client = MQTT(hass, entry, conf)
371  if DOMAIN in hass.data:
372  mqtt_data = hass.data[DATA_MQTT]
373  mqtt_data.config = mqtt_yaml
374  mqtt_data.client = client
375  else:
376  # Initial setup
377  hass.data[DATA_MQTT] = mqtt_data = MqttData(config=mqtt_yaml, client=client)
378  await client.async_start(mqtt_data)
379 
380  # Restore saved subscriptions
381  if mqtt_data.subscriptions_to_restore:
382  mqtt_data.client.async_restore_tracked_subscriptions(
383  mqtt_data.subscriptions_to_restore
384  )
385  mqtt_data.subscriptions_to_restore = set()
386  mqtt_data.reload_dispatchers.append(
387  entry.add_update_listener(_async_config_entry_updated)
388  )
389 
390  return (mqtt_data, conf)
391 
392  client_available: asyncio.Future[bool]
393  if DATA_MQTT_AVAILABLE not in hass.data:
394  client_available = hass.data[DATA_MQTT_AVAILABLE] = hass.loop.create_future()
395  else:
396  client_available = hass.data[DATA_MQTT_AVAILABLE]
397 
398  mqtt_data, conf = await _setup_client()
399  platforms_used = platforms_from_config(mqtt_data.config)
400  platforms_used.update(
401  entry.domain
402  for entry in er.async_entries_for_config_entry(
403  er.async_get(hass), entry.entry_id
404  )
405  )
406  integration = async_get_loaded_integration(hass, DOMAIN)
407  # Preload platforms we know we are going to use so
408  # discovery can setup each platform synchronously
409  # and avoid creating a flood of tasks at startup
410  # while waiting for the the imports to complete
411  if not integration.platforms_are_loaded(platforms_used):
412  with async_pause_setup(hass, SetupPhases.WAIT_IMPORT_PLATFORMS):
413  await integration.async_get_platforms(platforms_used)
414 
415  # Wait to connect until the platforms are loaded so
416  # we can be sure discovery does not have to wait for
417  # each platform to load when we get the flood of retained
418  # messages on connect
419  await mqtt_data.client.async_connect(client_available)
420 
421  # setup platforms and discovery
422  async def _reload_config(call: ServiceCall) -> None:
423  """Reload the platforms."""
424  # Fetch updated manually configured items and validate
425  try:
426  config_yaml = await async_integration_yaml_config(
427  hass, DOMAIN, raise_on_failure=True
428  )
429  except ConfigValidationError as ex:
431  translation_domain=ex.translation_domain,
432  translation_key=ex.translation_key,
433  translation_placeholders=ex.translation_placeholders,
434  ) from ex
435 
436  new_config: list[ConfigType] = config_yaml.get(DOMAIN, [])
437  platforms_used = platforms_from_config(new_config)
438  new_platforms = platforms_used - mqtt_data.platforms_loaded
439  await async_forward_entry_setup_and_setup_discovery(hass, entry, new_platforms)
440  # Check the schema before continuing reload
441  await async_check_config_schema(hass, config_yaml)
442 
443  # Remove repair issues
444  _async_remove_mqtt_issues(hass, mqtt_data)
445 
446  mqtt_data.config = new_config
447 
448  # Reload the modern yaml platforms
449  mqtt_platforms = async_get_platforms(hass, DOMAIN)
450  tasks = [
451  create_eager_task(entity.async_remove())
452  for mqtt_platform in mqtt_platforms
453  for entity in list(mqtt_platform.entities.values())
454  if getattr(entity, "_discovery_data", None) is None
455  and mqtt_platform.config_entry
456  and mqtt_platform.domain in ENTITY_PLATFORMS
457  ]
458  await asyncio.gather(*tasks)
459 
460  for component in mqtt_data.reload_handlers.values():
461  component()
462 
463  # Fire event
464  hass.bus.async_fire(f"event_{DOMAIN}_reloaded", context=call.context)
465 
466  await async_forward_entry_setup_and_setup_discovery(hass, entry, platforms_used)
467  # Setup reload service after all platforms have loaded
468  if not hass.services.has_service(DOMAIN, SERVICE_RELOAD):
469  async_register_admin_service(hass, DOMAIN, SERVICE_RELOAD, _reload_config)
470  # Setup discovery
471  if conf.get(CONF_DISCOVERY, DEFAULT_DISCOVERY):
472  await discovery.async_start(
473  hass, conf.get(CONF_DISCOVERY_PREFIX, DEFAULT_PREFIX), entry
474  )
475 
476  return True
477 
478 
479 @websocket_api.websocket_command( {vol.Required("type"): "mqtt/device/debug_info", vol.Required("device_id"): str}
480 )
481 @callback
483  hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any]
484 ) -> None:
485  """Get MQTT debug info for device."""
486  device_id = msg["device_id"]
487  mqtt_info = debug_info.info_for_device(hass, device_id)
488 
489  connection.send_result(msg["id"], mqtt_info)
490 
491 
492 @websocket_api.websocket_command( { vol.Required("type"): "mqtt/subscribe",
493  vol.Required("topic"): valid_subscribe_topic,
494  vol.Optional("qos"): valid_qos_schema,
495  }
496 )
497 @websocket_api.async_response
498 async def websocket_subscribe(
499  hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any]
500 ) -> None:
501  """Subscribe to a MQTT topic."""
502  if not connection.user.is_admin:
503  raise Unauthorized
504 
505  @callback
506  def forward_messages(mqttmsg: ReceiveMessage) -> None:
507  """Forward events to websocket."""
508  try:
509  payload = cast(bytes, mqttmsg.payload).decode(
510  DEFAULT_ENCODING
511  ) # not str because encoding is set to None
512  except (AttributeError, UnicodeDecodeError):
513  # Convert non UTF-8 payload to a string presentation
514  payload = str(mqttmsg.payload)
515 
516  connection.send_message(
517  websocket_api.event_message(
518  msg["id"],
519  {
520  "topic": mqttmsg.topic,
521  "payload": payload,
522  "qos": mqttmsg.qos,
523  "retain": mqttmsg.retain,
524  },
525  )
526  )
527 
528  # Perform UTF-8 decoding directly in callback routine
529  qos: int = msg.get("qos", DEFAULT_QOS)
530  connection.subscriptions[msg["id"]] = async_subscribe_internal(
531  hass, msg["topic"], forward_messages, encoding=None, qos=qos
532  )
533 
534  connection.send_message(websocket_api.result_message(msg["id"]))
535 
536 
537 type ConnectionStatusCallback = Callable[[bool], None]
538 
539 
540 @callback
542  hass: HomeAssistant, connection_status_callback: ConnectionStatusCallback
543 ) -> Callable[[], None]:
544  """Subscribe to MQTT connection changes."""
546  hass, MQTT_CONNECTION_STATE, connection_status_callback
547  )
548 
549 
550 def is_connected(hass: HomeAssistant) -> bool:
551  """Return if MQTT client is connected."""
552  mqtt_data = hass.data[DATA_MQTT]
553  return mqtt_data.client.connected
554 
555 
557  hass: HomeAssistant, config_entry: ConfigEntry, device_entry: DeviceEntry
558 ) -> bool:
559  """Remove MQTT config entry from a device."""
560  # pylint: disable-next=import-outside-toplevel
561  from . import device_automation
562 
563  await device_automation.async_removed_from_device(hass, device_entry.id)
564  return True
565 
566 
567 async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
568  """Unload MQTT dump and publish service when the config entry is unloaded."""
569  mqtt_data = hass.data[DATA_MQTT]
570  mqtt_client = mqtt_data.client
571 
572  # Stop the discovery
573  await discovery.async_stop(hass)
574  # Unload the platforms
575  await hass.config_entries.async_unload_platforms(entry, mqtt_data.platforms_loaded)
576  mqtt_data.platforms_loaded = set()
577  await asyncio.sleep(0)
578  # Unsubscribe reload dispatchers
579  while reload_dispatchers := mqtt_data.reload_dispatchers:
580  reload_dispatchers.pop()()
581  # Cleanup listeners
582  mqtt_client.cleanup()
583 
584  # Cleanup entity registry hooks
585  registry_hooks = mqtt_data.discovery_registry_hooks
586  while registry_hooks:
587  registry_hooks.popitem()[1]()
588  # Wait for all ACKs, stop the loop and disconnect the client
589  await mqtt_client.async_disconnect(disconnect_paho_client=True)
590 
591  # Cleanup MQTT client availability
592  hass.data.pop(DATA_MQTT_AVAILABLE, None)
593  # Store remaining subscriptions to be able to restore or reload them
594  # when the entry is set up again
595  if subscriptions := mqtt_client.subscriptions:
596  mqtt_data.subscriptions_to_restore = subscriptions
597 
598  # Remove repair issues
599  _async_remove_mqtt_issues(hass, mqtt_data)
600 
601  return True
602 
web.Response get(self, web.Request request, str config_key)
Definition: view.py:88
CALLBACK_TYPE async_subscribe_internal(HomeAssistant hass, str topic, Callable[[ReceiveMessage], Coroutine[Any, Any, None]|None] msg_callback, int qos=DEFAULT_QOS, str|None encoding=DEFAULT_ENCODING, HassJobType|None job_type=None)
Definition: client.py:210
PublishPayloadType convert_outgoing_mqtt_payload(PublishPayloadType payload)
Definition: models.py:56
None async_create_certificate_temp_files(HomeAssistant hass, ConfigType config)
Definition: util.py:342
bool|None mqtt_config_entry_enabled(HomeAssistant hass)
Definition: util.py:192
set[Platform|str] platforms_from_config(list[ConfigType] config)
Definition: util.py:148
str valid_publish_topic(Any topic)
Definition: util.py:308
None async_forward_entry_setup_and_setup_discovery(HomeAssistant hass, ConfigEntry config_entry, set[Platform|str] platforms, bool late=False)
Definition: util.py:158
Callable[[], None] async_subscribe_connection_status(HomeAssistant hass, ConnectionStatusCallback connection_status_callback)
Definition: __init__.py:546
bool async_setup_entry(HomeAssistant hass, ConfigEntry entry)
Definition: __init__.py:358
None websocket_subscribe(HomeAssistant hass, websocket_api.ActiveConnection connection, dict[str, Any] msg)
Definition: __init__.py:503
None websocket_mqtt_info(HomeAssistant hass, websocket_api.ActiveConnection connection, dict[str, Any] msg)
Definition: __init__.py:485
None async_check_config_schema(HomeAssistant hass, ConfigType config_yaml)
Definition: __init__.py:203
bool is_connected(HomeAssistant hass)
Definition: __init__.py:553
None _async_config_entry_updated(HomeAssistant hass, ConfigEntry entry)
Definition: __init__.py:180
None _async_remove_mqtt_issues(HomeAssistant hass, MqttData mqtt_data)
Definition: __init__.py:189
bool async_unload_entry(HomeAssistant hass, ConfigEntry entry)
Definition: __init__.py:570
bool async_remove_config_entry_device(HomeAssistant hass, ConfigEntry config_entry, DeviceEntry device_entry)
Definition: __init__.py:561
bool async_setup(HomeAssistant hass, ConfigType config)
Definition: __init__.py:228
None open(self, **Any kwargs)
Definition: lock.py:86
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)
Definition: dispatcher.py:103
list[EntityPlatform] async_get_platforms(HomeAssistant hass, str integration_name)
ConfigType|None async_integration_yaml_config(HomeAssistant hass, str integration_name)
Definition: reload.py:142
None async_register_admin_service(HomeAssistant hass, str domain, str service, Callable[[ServiceCall], Awaitable[None]|None] service_func, VolSchemaType schema=vol.Schema({}, extra=vol.PREVENT_EXTRA))
Definition: service.py:1121
Integration async_get_loaded_integration(HomeAssistant hass, str domain)
Definition: loader.py:1341
Integration async_get_integration(HomeAssistant hass, str domain)
Definition: loader.py:1354
Generator[None] async_pause_setup(core.HomeAssistant hass, SetupPhases phase)
Definition: setup.py:691