diff --git a/homeassistant/components/mqtt/client.py b/homeassistant/components/mqtt/client.py index 7ede1e504947b0194d64e562deccb67b05facd36..bd7343189383954efbce021059fa835f090d3869 100644 --- a/homeassistant/components/mqtt/client.py +++ b/homeassistant/components/mqtt/client.py @@ -27,7 +27,14 @@ from homeassistant.const import ( EVENT_HOMEASSISTANT_STARTED, EVENT_HOMEASSISTANT_STOP, ) -from homeassistant.core import CoreState, Event, HassJob, HomeAssistant, callback +from homeassistant.core import ( + CALLBACK_TYPE, + CoreState, + Event, + HassJob, + HomeAssistant, + callback, +) from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.dispatcher import dispatcher_send from homeassistant.helpers.typing import ConfigType @@ -178,7 +185,7 @@ async def async_subscribe( | AsyncDeprecatedMessageCallbackType, qos: int = DEFAULT_QOS, encoding: str | None = DEFAULT_ENCODING, -): +) -> CALLBACK_TYPE: """Subscribe to an MQTT topic. Call the return value to unsubscribe. @@ -357,12 +364,12 @@ class MQTT: hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, async_stop_mqtt) ) - def cleanup(self): + def cleanup(self) -> None: """Clean up listeners.""" while self._cleanup_on_unload: self._cleanup_on_unload.pop()() - def init_client(self): + def init_client(self) -> None: """Initialize paho client.""" self._mqttc = MqttClientSetup(self.conf).client self._mqttc.on_connect = self._mqtt_on_connect @@ -429,10 +436,10 @@ class MQTT: self._mqttc.loop_start() - async def async_disconnect(self): + async def async_disconnect(self) -> None: """Stop the MQTT client.""" - def stop(): + def stop() -> None: """Stop the MQTT client.""" # Do not disconnect, we want the broker to always publish will self._mqttc.loop_stop() diff --git a/homeassistant/components/mqtt/config_flow.py b/homeassistant/components/mqtt/config_flow.py index 55fd68f8b6a24dacb9188c66fa74435aa1bf4bd0..5d21619c4988fd5fa474aa061c959880b5c2b878 100644 --- a/homeassistant/components/mqtt/config_flow.py +++ b/homeassistant/components/mqtt/config_flow.py @@ -18,8 +18,9 @@ from homeassistant.const import ( CONF_PROTOCOL, CONF_USERNAME, ) -from homeassistant.core import HomeAssistant, callback +from homeassistant.core import callback from homeassistant.data_entry_flow import FlowResult +from homeassistant.helpers.typing import ConfigType from .client import MqttClientSetup from .const import ( @@ -73,7 +74,7 @@ class FlowHandler(config_entries.ConfigFlow, domain=DOMAIN): if user_input is not None: can_connect = await self.hass.async_add_executor_job( try_connection, - self.hass, + get_mqtt_data(self.hass, True).config or {}, user_input[CONF_BROKER], user_input[CONF_PORT], user_input.get(CONF_USERNAME), @@ -117,7 +118,7 @@ class FlowHandler(config_entries.ConfigFlow, domain=DOMAIN): data = self._hassio_discovery can_connect = await self.hass.async_add_executor_job( try_connection, - self.hass, + get_mqtt_data(self.hass, True).config or {}, data[CONF_HOST], data[CONF_PORT], data.get(CONF_USERNAME), @@ -164,13 +165,13 @@ class MQTTOptionsFlowHandler(config_entries.OptionsFlow): ) -> FlowResult: """Manage the MQTT broker configuration.""" mqtt_data = get_mqtt_data(self.hass, True) + yaml_config = mqtt_data.config or {} errors = {} current_config = self.config_entry.data - yaml_config = mqtt_data.config or {} if user_input is not None: can_connect = await self.hass.async_add_executor_job( try_connection, - self.hass, + yaml_config, user_input[CONF_BROKER], user_input[CONF_PORT], user_input.get(CONF_USERNAME), @@ -338,7 +339,7 @@ class MQTTOptionsFlowHandler(config_entries.OptionsFlow): def try_connection( - hass: HomeAssistant, + yaml_config: ConfigType, broker: str, port: int, username: str | None, @@ -351,8 +352,6 @@ def try_connection( import paho.mqtt.client as mqtt # pylint: disable=import-outside-toplevel # Get the config from configuration.yaml - mqtt_data = get_mqtt_data(hass, True) - yaml_config = mqtt_data.config or {} entry_config = { CONF_BROKER: broker, CONF_PORT: port, diff --git a/homeassistant/components/mqtt/discovery.py b/homeassistant/components/mqtt/discovery.py index ee0d0a1ac9aafcf6fcfe0c0e7d8c1d742128306e..23453e146ed8ef47229279fb0b2c841cd35e8c0e 100644 --- a/homeassistant/components/mqtt/discovery.py +++ b/homeassistant/components/mqtt/discovery.py @@ -8,6 +8,7 @@ import logging import re import time +from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_DEVICE, CONF_PLATFORM from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResultType @@ -18,6 +19,7 @@ from homeassistant.helpers.dispatcher import ( ) from homeassistant.helpers.json import json_loads from homeassistant.helpers.service_info.mqtt import MqttServiceInfo +from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.loader import async_get_mqtt from .. import mqtt @@ -30,6 +32,7 @@ from .const import ( CONF_TOPIC, DOMAIN, ) +from .models import ReceiveMessage from .util import get_mqtt_data _LOGGER = logging.getLogger(__name__) @@ -62,11 +65,6 @@ SUPPORTED_COMPONENTS = [ "vacuum", ] -ALREADY_DISCOVERED = "mqtt_discovered_components" -PENDING_DISCOVERED = "mqtt_pending_components" -DATA_CONFIG_FLOW_LOCK = "mqtt_discovery_config_flow_lock" -DISCOVERY_UNSUBSCRIBE = "mqtt_discovery_unsubscribe" -INTEGRATION_UNSUBSCRIBE = "mqtt_integration_discovery_unsubscribe" MQTT_DISCOVERY_UPDATED = "mqtt_discovery_updated_{}" MQTT_DISCOVERY_NEW = "mqtt_discovery_new_{}_{}" MQTT_DISCOVERY_DONE = "mqtt_discovery_done_{}" @@ -77,21 +75,21 @@ TOPIC_BASE = "~" class MQTTConfig(dict): """Dummy class to allow adding attributes.""" - discovery_data: dict + discovery_data: DiscoveryInfoType def clear_discovery_hash(hass: HomeAssistant, discovery_hash: tuple[str, str]) -> None: - """Clear entry in ALREADY_DISCOVERED list.""" - del hass.data[ALREADY_DISCOVERED][discovery_hash] + """Clear entry from already discovered list.""" + get_mqtt_data(hass).discovery_already_discovered.remove(discovery_hash) -def set_discovery_hash(hass: HomeAssistant, discovery_hash: tuple[str, str]): - """Clear entry in ALREADY_DISCOVERED list.""" - hass.data[ALREADY_DISCOVERED][discovery_hash] = {} +def set_discovery_hash(hass: HomeAssistant, discovery_hash: tuple[str, str]) -> None: + """Add entry to already discovered list.""" + get_mqtt_data(hass).discovery_already_discovered.add(discovery_hash) async def async_start( # noqa: C901 - hass: HomeAssistant, discovery_topic, config_entry=None + hass: HomeAssistant, discovery_topic: str, config_entry: ConfigEntry ) -> None: """Start MQTT Discovery.""" mqtt_data = get_mqtt_data(hass) @@ -175,8 +173,8 @@ async def async_start( # noqa: C901 payload[CONF_PLATFORM] = "mqtt" - if discovery_hash in hass.data[PENDING_DISCOVERED]: - pending = hass.data[PENDING_DISCOVERED][discovery_hash]["pending"] + if discovery_hash in mqtt_data.discovery_pending_discovered: + pending = mqtt_data.discovery_pending_discovered[discovery_hash]["pending"] pending.appendleft(payload) _LOGGER.info( "Component has already been discovered: %s %s, queuing update", @@ -187,27 +185,31 @@ async def async_start( # noqa: C901 await async_process_discovery_payload(component, discovery_id, payload) - async def async_process_discovery_payload(component, discovery_id, payload): + async def async_process_discovery_payload( + component: str, discovery_id: str, payload: ConfigType + ) -> None: """Process the payload of a new discovery.""" _LOGGER.debug("Process discovery payload %s", payload) discovery_hash = (component, discovery_id) - if discovery_hash in hass.data[ALREADY_DISCOVERED] or payload: + if discovery_hash in mqtt_data.discovery_already_discovered or payload: - async def discovery_done(_): - pending = hass.data[PENDING_DISCOVERED][discovery_hash]["pending"] + async def discovery_done(_) -> None: + pending = mqtt_data.discovery_pending_discovered[discovery_hash][ + "pending" + ] _LOGGER.debug("Pending discovery for %s: %s", discovery_hash, pending) if not pending: - hass.data[PENDING_DISCOVERED][discovery_hash]["unsub"]() - hass.data[PENDING_DISCOVERED].pop(discovery_hash) + mqtt_data.discovery_pending_discovered[discovery_hash]["unsub"]() + mqtt_data.discovery_pending_discovered.pop(discovery_hash) else: payload = pending.pop() await async_process_discovery_payload( component, discovery_id, payload ) - if discovery_hash not in hass.data[PENDING_DISCOVERED]: - hass.data[PENDING_DISCOVERED][discovery_hash] = { + if discovery_hash not in mqtt_data.discovery_pending_discovered: + mqtt_data.discovery_pending_discovered[discovery_hash] = { "unsub": async_dispatcher_connect( hass, MQTT_DISCOVERY_DONE.format(discovery_hash), @@ -216,7 +218,7 @@ async def async_start( # noqa: C901 "pending": deque([]), } - if discovery_hash in hass.data[ALREADY_DISCOVERED]: + if discovery_hash in mqtt_data.discovery_already_discovered: # Dispatch update _LOGGER.info( "Component has already been discovered: %s %s, sending update", @@ -229,7 +231,7 @@ async def async_start( # noqa: C901 elif payload: # Add component _LOGGER.info("Found new component: %s %s", component, discovery_id) - hass.data[ALREADY_DISCOVERED][discovery_hash] = None + mqtt_data.discovery_already_discovered.add(discovery_hash) async_dispatcher_send( hass, MQTT_DISCOVERY_NEW.format(component, "mqtt"), payload ) @@ -239,15 +241,11 @@ async def async_start( # noqa: C901 hass, MQTT_DISCOVERY_DONE.format(discovery_hash), None ) - hass.data.setdefault(DATA_CONFIG_FLOW_LOCK, asyncio.Lock()) - hass.data[ALREADY_DISCOVERED] = {} - hass.data[PENDING_DISCOVERED] = {} - discovery_topics = [ f"{discovery_topic}/+/+/config", f"{discovery_topic}/+/+/+/config", ] - hass.data[DISCOVERY_UNSUBSCRIBE] = await asyncio.gather( + mqtt_data.discovery_unsubscribe = await asyncio.gather( *( mqtt.async_subscribe(hass, topic, async_discovery_message_received, 0) for topic in discovery_topics @@ -257,19 +255,20 @@ async def async_start( # noqa: C901 mqtt_data.last_discovery = time.time() mqtt_integrations = await async_get_mqtt(hass) - hass.data[INTEGRATION_UNSUBSCRIBE] = {} - for (integration, topics) in mqtt_integrations.items(): - async def async_integration_message_received(integration, msg): + async def async_integration_message_received( + integration: str, msg: ReceiveMessage + ) -> None: """Process the received message.""" + assert mqtt_data.data_config_flow_lock key = f"{integration}_{msg.subscribed_topic}" # Lock to prevent initiating many parallel config flows. # Note: The lock is not intended to prevent a race, only for performance - async with hass.data[DATA_CONFIG_FLOW_LOCK]: + async with mqtt_data.data_config_flow_lock: # Already unsubscribed - if key not in hass.data[INTEGRATION_UNSUBSCRIBE]: + if key not in mqtt_data.integration_unsubscribe: return data = MqttServiceInfo( @@ -289,14 +288,14 @@ async def async_start( # noqa: C901 and result["reason"] in ("already_configured", "single_instance_allowed") ): - unsub = hass.data[INTEGRATION_UNSUBSCRIBE].pop(key, None) + unsub = mqtt_data.integration_unsubscribe.pop(key, None) if unsub is None: return unsub() for topic in topics: key = f"{integration}_{topic}" - hass.data[INTEGRATION_UNSUBSCRIBE][key] = await mqtt.async_subscribe( + mqtt_data.integration_unsubscribe[key] = await mqtt.async_subscribe( hass, topic, functools.partial(async_integration_message_received, integration), @@ -306,11 +305,10 @@ async def async_start( # noqa: C901 async def async_stop(hass: HomeAssistant) -> None: """Stop MQTT Discovery.""" - if DISCOVERY_UNSUBSCRIBE in hass.data: - for unsub in hass.data[DISCOVERY_UNSUBSCRIBE]: - unsub() - hass.data[DISCOVERY_UNSUBSCRIBE] = [] - if INTEGRATION_UNSUBSCRIBE in hass.data: - for key, unsub in list(hass.data[INTEGRATION_UNSUBSCRIBE].items()): - unsub() - hass.data[INTEGRATION_UNSUBSCRIBE].pop(key) + mqtt_data = get_mqtt_data(hass) + for unsub in mqtt_data.discovery_unsubscribe: + unsub() + mqtt_data.discovery_unsubscribe = [] + for key, unsub in list(mqtt_data.integration_unsubscribe.items()): + unsub() + mqtt_data.integration_unsubscribe.pop(key) diff --git a/homeassistant/components/mqtt/models.py b/homeassistant/components/mqtt/models.py index 274f7019210d15ca7f0f052224b64f7d4c5ee539..b7cb81b2ea40cffa8d46ad28c17a4711f4cc2b46 100644 --- a/homeassistant/components/mqtt/models.py +++ b/homeassistant/components/mqtt/models.py @@ -2,6 +2,7 @@ from __future__ import annotations from ast import literal_eval +import asyncio from collections import deque from collections.abc import Callable, Coroutine from dataclasses import dataclass, field @@ -22,6 +23,8 @@ if TYPE_CHECKING: from .client import MQTT, Subscription from .debug_info import TimestampedPublishMessage from .device_trigger import Trigger + from .discovery import MQTTConfig + from .tag import MQTTTagScanner _SENTINEL = object() @@ -80,6 +83,13 @@ class TriggerDebugInfo(TypedDict): discovery_data: DiscoveryInfoType +class PendingDiscovered(TypedDict): + """Pending discovered items.""" + + pending: deque[MQTTConfig] + unsub: CALLBACK_TYPE + + class MqttCommandTemplate: """Class for rendering MQTT payload with command templates.""" @@ -237,9 +247,16 @@ class MqttData: default_factory=dict ) device_triggers: dict[str, Trigger] = field(default_factory=dict) + data_config_flow_lock: asyncio.Lock = field(default_factory=asyncio.Lock) + discovery_already_discovered: set[tuple[str, str]] = field(default_factory=set) + discovery_pending_discovered: dict[tuple[str, str], PendingDiscovered] = field( + default_factory=dict + ) discovery_registry_hooks: dict[tuple[str, str], CALLBACK_TYPE] = field( default_factory=dict ) + discovery_unsubscribe: list[CALLBACK_TYPE] = field(default_factory=list) + integration_unsubscribe: dict[str, CALLBACK_TYPE] = field(default_factory=dict) last_discovery: float = 0.0 reload_dispatchers: list[CALLBACK_TYPE] = field(default_factory=list) reload_entry: bool = False @@ -248,4 +265,5 @@ class MqttData: ) reload_needed: bool = False subscriptions_to_restore: list[Subscription] = field(default_factory=list) + tags: dict[str, dict[str, MQTTTagScanner]] = field(default_factory=dict) updated_config: ConfigType = field(default_factory=dict) diff --git a/homeassistant/components/mqtt/tag.py b/homeassistant/components/mqtt/tag.py index dc4cc0e109d7161343becf84ed30f0b3e0ea1c44..23afae35cc9ad5beec4876190cffdcfb3fbae95f 100644 --- a/homeassistant/components/mqtt/tag.py +++ b/homeassistant/components/mqtt/tag.py @@ -23,12 +23,11 @@ from .mixins import ( ) from .models import MqttValueTemplate, ReceiveMessage from .subscription import EntitySubscription -from .util import valid_subscribe_topic +from .util import get_mqtt_data, valid_subscribe_topic LOG_NAME = "Tag" TAG = "tag" -TAGS = "mqtt_tags" PLATFORM_SCHEMA = MQTT_BASE_SCHEMA.extend( { @@ -59,9 +58,8 @@ async def _async_setup_tag( discovery_id = discovery_hash[1] device_id = update_device(hass, config_entry, config) - hass.data.setdefault(TAGS, {}) - if device_id not in hass.data[TAGS]: - hass.data[TAGS][device_id] = {} + if device_id is not None and device_id not in (tags := get_mqtt_data(hass).tags): + tags[device_id] = {} tag_scanner = MQTTTagScanner( hass, @@ -74,16 +72,16 @@ async def _async_setup_tag( await tag_scanner.subscribe_topics() if device_id: - hass.data[TAGS][device_id][discovery_id] = tag_scanner + tags[device_id][discovery_id] = tag_scanner send_discovery_done(hass, discovery_data) def async_has_tags(hass: HomeAssistant, device_id: str) -> bool: """Device has tag scanners.""" - if TAGS not in hass.data or device_id not in hass.data[TAGS]: + if device_id not in (tags := get_mqtt_data(hass).tags): return False - return hass.data[TAGS][device_id] != {} + return tags[device_id] != {} class MQTTTagScanner(MqttDiscoveryDeviceUpdate): @@ -159,4 +157,4 @@ class MQTTTagScanner(MqttDiscoveryDeviceUpdate): self.hass, self._sub_state ) if self.device_id: - self.hass.data[TAGS][self.device_id].pop(discovery_id) + get_mqtt_data(self.hass).tags[self.device_id].pop(discovery_id) diff --git a/homeassistant/components/mqtt_room/sensor.py b/homeassistant/components/mqtt_room/sensor.py index c14611578861b9f3d377e34c6f6d5a0ff97143e6..a69270480510072d3b04cea1bf05effd97358f82 100644 --- a/homeassistant/components/mqtt_room/sensor.py +++ b/homeassistant/components/mqtt_room/sensor.py @@ -133,9 +133,7 @@ class MQTTRoomSensor(SensorEntity): ): update_state(**device) - return await mqtt.async_subscribe( - self.hass, self._state_topic, message_received, 1 - ) + await mqtt.async_subscribe(self.hass, self._state_topic, message_received, 1) @property def name(self): diff --git a/tests/components/mqtt/test_config_flow.py b/tests/components/mqtt/test_config_flow.py index 2ad216a3b7befd9244bad1519ec7e9ca97f5f716..5d67b34db5d15ea845c4774a2b3376503d7807eb 100644 --- a/tests/components/mqtt/test_config_flow.py +++ b/tests/components/mqtt/test_config_flow.py @@ -186,7 +186,18 @@ async def test_manual_config_set( "discovery": True, } # Check we tried the connection, with precedence for config entry settings - mock_try_connection.assert_called_once_with(hass, "127.0.0.1", 1883, None, None) + mock_try_connection.assert_called_once_with( + { + "broker": "bla", + "keepalive": 60, + "discovery_prefix": "homeassistant", + "protocol": "3.1.1", + }, + "127.0.0.1", + 1883, + None, + None, + ) # Check config entry got setup assert len(mock_finish_setup.mock_calls) == 1 config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0] diff --git a/tests/components/mqtt/test_device_tracker_discovery.py b/tests/components/mqtt/test_device_tracker_discovery.py index 876b66e8a4da1dd0d99a5c78f3b015d86e31f965..a39b9b696c5340fe050b8faa6090395e5c95122c 100644 --- a/tests/components/mqtt/test_device_tracker_discovery.py +++ b/tests/components/mqtt/test_device_tracker_discovery.py @@ -6,7 +6,6 @@ import pytest from homeassistant.components import device_tracker, mqtt from homeassistant.components.mqtt.const import DOMAIN as MQTT_DOMAIN -from homeassistant.components.mqtt.discovery import ALREADY_DISCOVERED from homeassistant.const import STATE_HOME, STATE_NOT_HOME, STATE_UNKNOWN, Platform from homeassistant.setup import async_setup_component @@ -60,7 +59,7 @@ async def test_discover_device_tracker(hass, mqtt_mock_entry_no_yaml_config, cap assert state is not None assert state.name == "test" - assert ("device_tracker", "bla") in hass.data[ALREADY_DISCOVERED] + assert ("device_tracker", "bla") in hass.data["mqtt"].discovery_already_discovered @pytest.mark.no_fail_on_log_exception diff --git a/tests/components/mqtt/test_discovery.py b/tests/components/mqtt/test_discovery.py index a9ac66f88513e8d33bd3f4e2f54d2bc370a9d4b3..50c0a50bd40d45c5562f1adcd93f82363dda19bf 100644 --- a/tests/components/mqtt/test_discovery.py +++ b/tests/components/mqtt/test_discovery.py @@ -13,7 +13,7 @@ from homeassistant.components.mqtt.abbreviations import ( ABBREVIATIONS, DEVICE_ABBREVIATIONS, ) -from homeassistant.components.mqtt.discovery import ALREADY_DISCOVERED, async_start +from homeassistant.components.mqtt.discovery import async_start from homeassistant.const import ( EVENT_STATE_CHANGED, STATE_ON, @@ -152,7 +152,7 @@ async def test_correct_config_discovery(hass, mqtt_mock_entry_no_yaml_config, ca assert state is not None assert state.name == "Beer" - assert ("binary_sensor", "bla") in hass.data[ALREADY_DISCOVERED] + assert ("binary_sensor", "bla") in hass.data["mqtt"].discovery_already_discovered @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.FAN]) @@ -170,7 +170,7 @@ async def test_discover_fan(hass, mqtt_mock_entry_no_yaml_config, caplog): assert state is not None assert state.name == "Beer" - assert ("fan", "bla") in hass.data[ALREADY_DISCOVERED] + assert ("fan", "bla") in hass.data["mqtt"].discovery_already_discovered @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.CLIMATE]) @@ -190,7 +190,7 @@ async def test_discover_climate(hass, mqtt_mock_entry_no_yaml_config, caplog): assert state is not None assert state.name == "ClimateTest" - assert ("climate", "bla") in hass.data[ALREADY_DISCOVERED] + assert ("climate", "bla") in hass.data["mqtt"].discovery_already_discovered @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.ALARM_CONTROL_PANEL]) @@ -212,7 +212,9 @@ async def test_discover_alarm_control_panel( assert state is not None assert state.name == "AlarmControlPanelTest" - assert ("alarm_control_panel", "bla") in hass.data[ALREADY_DISCOVERED] + assert ("alarm_control_panel", "bla") in hass.data[ + "mqtt" + ].discovery_already_discovered @pytest.mark.parametrize( @@ -372,7 +374,7 @@ async def test_discovery_with_object_id( assert state is not None assert state.name == name - assert (domain, "object bla") in hass.data[ALREADY_DISCOVERED] + assert (domain, "object bla") in hass.data["mqtt"].discovery_already_discovered @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR]) @@ -390,7 +392,9 @@ async def test_discovery_incl_nodeid(hass, mqtt_mock_entry_no_yaml_config, caplo assert state is not None assert state.name == "Beer" - assert ("binary_sensor", "my_node_id bla") in hass.data[ALREADY_DISCOVERED] + assert ("binary_sensor", "my_node_id bla") in hass.data[ + "mqtt" + ].discovery_already_discovered @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR]) @@ -970,7 +974,7 @@ async def test_discovery_expansion(hass, mqtt_mock_entry_no_yaml_config, caplog) state = hass.states.get("switch.DiscoveryExpansionTest1") assert state is not None assert state.name == "DiscoveryExpansionTest1" - assert ("switch", "bla") in hass.data[ALREADY_DISCOVERED] + assert ("switch", "bla") in hass.data["mqtt"].discovery_already_discovered assert state.state == STATE_UNKNOWN async_fire_mqtt_message(hass, "test_topic/some/base/topic", "ON") @@ -1023,7 +1027,7 @@ async def test_discovery_expansion_2(hass, mqtt_mock_entry_no_yaml_config, caplo state = hass.states.get("switch.DiscoveryExpansionTest1") assert state is not None assert state.name == "DiscoveryExpansionTest1" - assert ("switch", "bla") in hass.data[ALREADY_DISCOVERED] + assert ("switch", "bla") in hass.data["mqtt"].discovery_already_discovered assert state.state == STATE_UNKNOWN @@ -1102,7 +1106,7 @@ async def test_discovery_expansion_without_encoding_and_value_template_1( state = hass.states.get("switch.DiscoveryExpansionTest1") assert state is not None assert state.name == "DiscoveryExpansionTest1" - assert ("switch", "bla") in hass.data[ALREADY_DISCOVERED] + assert ("switch", "bla") in hass.data["mqtt"].discovery_already_discovered assert state.state == STATE_UNKNOWN async_fire_mqtt_message(hass, "some/base/topic/avail_item1", b"\x00") @@ -1151,7 +1155,7 @@ async def test_discovery_expansion_without_encoding_and_value_template_2( state = hass.states.get("switch.DiscoveryExpansionTest1") assert state is not None assert state.name == "DiscoveryExpansionTest1" - assert ("switch", "bla") in hass.data[ALREADY_DISCOVERED] + assert ("switch", "bla") in hass.data["mqtt"].discovery_already_discovered assert state.state == STATE_UNKNOWN async_fire_mqtt_message(hass, "some/base/topic/avail_item1", b"\x00") @@ -1236,7 +1240,7 @@ async def test_no_implicit_state_topic_switch( state = hass.states.get("switch.Test1") assert state is not None assert state.name == "Test1" - assert ("switch", "bla") in hass.data[ALREADY_DISCOVERED] + assert ("switch", "bla") in hass.data["mqtt"].discovery_already_discovered assert state.state == STATE_UNKNOWN assert state.attributes["assumed_state"] is True @@ -1280,7 +1284,9 @@ async def test_complex_discovery_topic_prefix( assert state is not None assert state.name == "Beer" - assert ("binary_sensor", "node1 object1") in hass.data[ALREADY_DISCOVERED] + assert ("binary_sensor", "node1 object1") in hass.data[ + "mqtt" + ].discovery_already_discovered @patch("homeassistant.components.mqtt.PLATFORMS", [])