Make sure MQTT client is available when starting depending platforms (#91164)
* Make sure MQTT is available starting mqtt_json * Wait for mqtt client * Sync client connect * Simplify * Addiitional tests async_wait_for_mqtt_client * Improve comment waiting for mqtt * Improve docstr * Do not wait unless the MQTT client is in setup * Handle entry errors during setup * More comments - do not clear event * Add snips and mqtt_room * Add manual_mqtt * Update homeassistant/components/mqtt/__init__.py Co-authored-by: J. Nick Koston <nick@koston.org> * Use a fixture, improve tests * Simplify --------- Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
parent
adc472862b
commit
0bcda9fe9c
11 changed files with 346 additions and 34 deletions
|
@ -2,13 +2,16 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
from typing import Any
|
||||
|
||||
import async_timeout
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import config_validation as cv, template
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
@ -22,6 +25,7 @@ from .const import (
|
|||
CONF_CLIENT_CERT,
|
||||
CONF_CLIENT_KEY,
|
||||
DATA_MQTT,
|
||||
DATA_MQTT_AVAILABLE,
|
||||
DEFAULT_ENCODING,
|
||||
DEFAULT_QOS,
|
||||
DEFAULT_RETAIN,
|
||||
|
@ -29,6 +33,8 @@ from .const import (
|
|||
)
|
||||
from .models import MqttData
|
||||
|
||||
AVAILABILITY_TIMEOUT = 30.0
|
||||
|
||||
TEMP_DIR_NAME = f"home-assistant-{DOMAIN}"
|
||||
|
||||
_VALID_QOS_SCHEMA = vol.All(vol.Coerce(int), vol.In([0, 1, 2]))
|
||||
|
@ -41,6 +47,37 @@ def mqtt_config_entry_enabled(hass: HomeAssistant) -> bool | None:
|
|||
return not bool(hass.config_entries.async_entries(DOMAIN)[0].disabled_by)
|
||||
|
||||
|
||||
async def async_wait_for_mqtt_client(hass: HomeAssistant) -> bool:
|
||||
"""Wait for the MQTT client to become available.
|
||||
|
||||
Waits when mqtt set up is in progress,
|
||||
It is not needed that the client is connected.
|
||||
Returns True if the mqtt client is available.
|
||||
Returns False when the client is not available.
|
||||
"""
|
||||
if not mqtt_config_entry_enabled(hass):
|
||||
return False
|
||||
|
||||
entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
if entry.state == ConfigEntryState.LOADED:
|
||||
return True
|
||||
|
||||
state_reached_future: asyncio.Future[bool]
|
||||
if DATA_MQTT_AVAILABLE not in hass.data:
|
||||
hass.data[DATA_MQTT_AVAILABLE] = state_reached_future = asyncio.Future()
|
||||
else:
|
||||
state_reached_future = hass.data[DATA_MQTT_AVAILABLE]
|
||||
if state_reached_future.done():
|
||||
return state_reached_future.result()
|
||||
|
||||
try:
|
||||
async with async_timeout.timeout(AVAILABILITY_TIMEOUT):
|
||||
# Await the client setup or an error state was received
|
||||
return await state_reached_future
|
||||
except asyncio.TimeoutError:
|
||||
return False
|
||||
|
||||
|
||||
def valid_topic(topic: Any) -> str:
|
||||
"""Validate that this is a valid topic name/filter."""
|
||||
validated_topic = cv.string(topic)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue