Repository: home-assistant/core
Pull request: Avoid importing MQTT into core for ServiceInfo dataclass
## Proposed change
<!--
  Describe the big picture of your changes here to communicate to the
  maintainers why we should accept this pull request. If it fixes a bug
  or resolves a feature request, be sure to link to that issue in the
  additional information section.
-->
Which ever integration triggered the first discovery flow would trigger the python code for mqtt to be loaded.  Since most flows would wait until after startup [since we queue them](https://github.com/home-assistant/core/blob/b3fec4c40147d98bc74a9047d8f34ba803ab5413/homeassistant/helpers/discovery_flow.py#L19) until the started event if they come from discovery, this meant that the `rpi_power` integration which is triggered from the `raspberry_pi` hardware integration would cause this to happen a lot sooner on RPI platforms.  MQTT python code loading would happen at an unexpected time which is a blocking operation since the python files have to be loaded from disk.  This caused warnings since everything was waiting for MQTT code load (which takes 8s on my x86_64 spinning disk machine and likely longer on RPi3b+s with an sd card)

Likely fixes #73863

A nice side effect is that if you aren't using MQTT, this saves ~20MiB of RAM on 64bit platforms

I will move the rest of them in a followup PR but I didn't want to do that now since this one should go into beta since they will already be [loaded anyways](https://github.com/home-assistant/core/blob/b3fec4c40147d98bc74a9047d8f34ba803ab5413/homeassistant/bootstrap.py#L73) if they are enabled and don't have this issue, but its better to be consistant and have them all in one place in case we add more in the future.

MQTT was getting loaded via config flow since it was needed to type `async_step_mqtt`
<img width="1270" alt="Screen Shot 2022-07-04 at 09 47 10" src="https://user-images.githubusercontent.com/663432/177177738-e07c7263-e387-4fc8-9438-5107df58f0db.png">

## Type of change
<!--
  What type of change does your PR introduce to Home Assistant?
  NOTE: Please, check only 1! box!
  If your PR requires multiple boxes to be checked, you'll most likely need to
  split it into multiple PRs. This makes things easier and faster to code review.
-->

- [ ] Dependency upgrade
- [x] Bugfix (non-breaking change which fixes an issue)
- [ ] New integration (thank you!)
- [ ] New feature (which adds functionality to an existing integration)
- [ ] Breaking change (fix/feature causing existing functionality to break)
- [x] Code quality improvements to existing code or addition of tests

## Additional information
<!--
  Details are important, and help maintainers processing your PR.
  Please be sure to fill out additional details, if applicable.
-->

- This PR fixes or closes issue: fixes #
- This PR is related to issue: 
- Link to documentation pull request: 

## Checklist
<!--
  Put an `x` in the boxes that apply. You can also fill these out after
  creating the PR. If you're unsure about any of them, don't hesitate to ask.
  We're here to help! This is simply a reminder of what we are going to look
  for before merging your code.
-->

- [x] The code change is tested and works locally.
- [ ] Local tests pass. **Your PR cannot be merged unless tests pass**
- [ ] There is no commented out code in this PR.
- [ ] I have followed the [development checklist][dev-checklist]
- [ ] The code has been formatted using Black (`black --fast homeassistant tests`)
- [ ] Tests have been added to verify that the new code works.

If user exposed functionality or configuration variables are added/changed:

- [ ] Documentation added/updated for [www.home-assistant.io][docs-repository]

If the code communicates with devices, web services, or third-party tools:

- [ ] The [manifest file][manifest-docs] has all fields filled out correctly.  
      Updated and included derived files by running: `python3 -m script.hassfest`.
- [ ] New or updated dependencies have been added to `requirements_all.txt`.  
      Updated by running `python3 -m script.gen_requirements_all`.
- [ ] For the updated dependencies - a link to the changelog, or at minimum a diff between library versions is added to the PR description.
- [ ] Untested files have been added to `.coveragerc`.

The integration reached or maintains the following [Integration Quality Scale][quality-scale]:
<!--
  The Integration Quality Scale scores an integration on the code quality
  and user experience. Each level of the quality scale consists of a list
  of requirements. We highly recommend getting your integration scored!
-->

- [ ] No score or internal
- [ ] 🥈 Silver
- [ ] 🥇 Gold
- [ ] 🏆 Platinum

<!--
  This project is very active and we have a high turnover of pull requests.

  Unfortunately, the number of incoming pull requests is higher than what our
  reviewers can review and merge so there is a long backlog of pull requests
  waiting for review. You can help here!
  
  By reviewing another pull request, you will help raise the code quality of
  that pull request and the final review will be faster. This way the general
  pace of pull request reviews will go up and your wait time will go down.
  
  When picking a pull request to review, try to choose one that hasn't yet
  been reviewed.

  Thanks for helping out!
-->

To help with the load of incoming pull requests:

- [ ] I have reviewed two other [open pull requests][prs] in this repository.

[prs]: https://github.com/home-assistant/core/pulls?q=is%3Aopen+is%3Apr+-author%3A%40me+-draft%3Atrue+-label%3Awaiting-for-upstream+sort%3Acreated-desc+review%3Anone+-status%3Afailure

<!--
  Thank you for contributing <3

  Below, some useful links you could explore:
-->
[dev-checklist]: https://developers.home-assistant.io/docs/en/development_checklist.html
[manifest-docs]: https://developers.home-assistant.io/docs/en/creating_integration_manifest.html
[quality-scale]: https://developers.home-assistant.io/docs/en/next/integration_quality_scale_index.html
[docs-repository]: https://github.com/home-assistant/home-assistant.io


Problem statement:
Multiple "is taking over 10 seconds" warnings after updating to 2022.6.7
### The problem

The following warnings appeared in my log after the update to b 2022.6.7.
Nothing else changed and everything seems to be working fine.


```
Setup of update platform hassio is taking over 10 seconds.
21:33:23 – (WARNING) Update

Setup of binary_sensor platform hassio is taking over 10 seconds.
21:33:23 – (WARNING) Binary sensor

Setup of input_text is taking over 10 seconds.
21:33:23 – (WARNING) /usr/local/lib/python3.9/asyncio/events.py - message first occurred at 21:33:23 and shows up 10 times

Setup of scene platform homeassistant is taking over 10 seconds.
21:33:23 – (WARNING) Scene
```

### What version of Home Assistant Core has the issue?

core-2022.6.7

### What was the last working version of Home Assistant Core?

core-2022.6.6

### What type of installation are you running?

Home Assistant OS

### Integration causing the issue

unknown

### Link to integration documentation on our website

_No response_

### Diagnostics information

_No response_

### Example YAML snippet

_No response_

### Anything in the logs that might be useful for us?

```txt
2022-06-22 21:33:23 WARNING (MainThread) [homeassistant.setup] Setup of zone is taking over 10 seconds.
2022-06-22 21:33:23 WARNING (MainThread) [homeassistant.setup] Setup of group is taking over 10 seconds.
2022-06-22 21:33:23 WARNING (MainThread) [homeassistant.setup] Setup of input_boolean is taking over 10 seconds.
2022-06-22 21:33:23 WARNING (MainThread) [homeassistant.components.scene] Setup of scene platform homeassistant is taking over 10 seconds.
2022-06-22 21:33:23 WARNING (MainThread) [homeassistant.setup] Setup of input_number is taking over 10 seconds.
2022-06-22 21:33:23 WARNING (MainThread) [homeassistant.setup] Setup of counter is taking over 10 seconds.
2022-06-22 21:33:23 WARNING (MainThread) [homeassistant.setup] Setup of input_text is taking over 10 seconds.
2022-06-22 21:33:23 WARNING (MainThread) [homeassistant.setup] Setup of input_datetime is taking over 10 seconds.
2022-06-22 21:33:23 WARNING (MainThread) [homeassistant.setup] Setup of timer is taking over 10 seconds.
2022-06-22 21:33:23 WARNING (MainThread) [homeassistant.setup] Setup of input_button is taking over 10 seconds.
2022-06-22 21:33:23 WARNING (MainThread) [homeassistant.setup] Setup of input_select is taking over 10 seconds.
2022-06-22 21:33:23 WARNING (MainThread) [homeassistant.components.binary_sensor] Setup of binary_sensor platform hassio is taking over 10 seconds.
```


### Additional information

_No response_

Hints from issue discussion:
the same here:

```
2022-06-22 21:29:57 WARNING (MainThread) [homeassistant.components.binary_sensor] Setup of binary_sensor platform hassio is taking over 10 seconds.
2022-06-22 21:29:57 WARNING (MainThread) [homeassistant.components.update] Setup of update platform hassio is taking over 10 seconds.
2022-06-22 21:29:57 WARNING (MainThread) [homeassistant.setup] Setup of timer is taking over 10 seconds.
2022-06-22 21:29:57 WARNING (MainThread) [homeassistant.setup] Setup of input_button is taking over 10 seconds.
2022-06-22 21:29:57 WARNING (MainThread) [homeassistant.setup] Setup of input_boolean is taking over 10 seconds.
2022-06-22 21:29:57 WARNING (MainThread) [homeassistant.setup] Setup of input_text is taking over 10 seconds.
2022-06-22 21:29:57 WARNING (MainThread) [homeassistant.setup] Setup of group is taking over 10 seconds.
2022-06-22 21:29:57 WARNING (MainThread) [homeassistant.setup] Setup of application_credentials is taking over 10 seconds.
2022-06-22 21:29:57 WARNING (MainThread) [homeassistant.setup] Setup of input_number is taking over 10 seconds.
2022-06-22 21:29:57 WARNING (MainThread) [homeassistant.setup] Setup of zone is taking over 10 seconds.
2022-06-22 21:29:57 WARNING (MainThread) [homeassistant.setup] Setup of input_select is taking over 10 seconds.
2022-06-22 21:29:57 WARNING (MainThread) [homeassistant.setup] Setup of counter is taking over 10 seconds.
2022-06-22 21:29:57 WARNING (MainThread) [homeassistant.setup] Setup of input_datetime is taking over 10 seconds.
2022-06-22 21:29:57 WARNING (MainThread) [homeassistant.setup] Setup of tag is taking over 10 seconds.
2022-06-22 21:29:57 WARNING (MainThread) [homeassistant.components.scene] Setup of scene platform homeassistant is taking over 10 seconds.
2022-06-22 21:30:04 WARNING (MainThread) [homeassistant.components.switch] Setup of switch platform wake_on_lan is taking over 10 seconds.
2022-06-22 21:31:01 WARNING (MainThread) [homeassistant.components.button] Setup of button platform nam is taking over 10 seconds.
2022-06-22 21:31:01 WARNING (MainThread) [homeassistant.components.sensor] Setup of sensor platform nam is taking over 10 seconds.
```

Same here, even after multiple restarts.. I've moved from 2022.6.5 to 2022.6.7

```
2022-06-23 20:25:37 WARNING (MainThread) [homeassistant.components.binary_sensor] Setup of binary_sensor platform hassio is taking over 10 seconds.
2022-06-23 20:25:37 WARNING (MainThread) [homeassistant.setup] Setup of folder_watcher is taking over 10 seconds.
2022-06-23 20:25:37 WARNING (MainThread) [homeassistant.setup] Setup of input_number is taking over 10 seconds.
2022-06-23 20:25:37 WARNING (MainThread) [homeassistant.setup] Setup of input_boolean is taking over 10 seconds.
2022-06-23 20:25:37 WARNING (MainThread) [homeassistant.setup] Setup of counter is taking over 10 seconds.
2022-06-23 20:25:37 WARNING (MainThread) [homeassistant.setup] Setup of input_datetime is taking over 10 seconds.
2022-06-23 20:25:37 WARNING (MainThread) [homeassistant.setup] Setup of timer is taking over 10 seconds.
2022-06-23 20:25:37 WARNING (MainThread) [homeassistant.setup] Setup of tag is taking over 10 seconds.
2022-06-23 20:25:37 WARNING (MainThread) [homeassistant.setup] Setup of input_text is taking over 10 seconds.
2022-06-23 20:25:37 WARNING (MainThread) [homeassistant.setup] Setup of zone is taking over 10 seconds.
2022-06-23 20:25:37 WARNING (MainThread) [homeassistant.setup] Setup of input_button is taking over 10 seconds.
2022-06-23 20:25:37 WARNING (MainThread) [homeassistant.setup] Setup of group is taking over 10 seconds.
2022-06-23 20:25:37 WARNING (MainThread) [homeassistant.setup] Setup of application_credentials is taking over 10 seconds.
2022-06-23 20:25:37 WARNING (MainThread) [homeassistant.setup] Setup of input_select is taking over 10 seconds.
2022-06-23 20:25:37 WARNING (MainThread) [homeassistant.components.update] Setup of update platform hassio is taking over 10 seconds.
```


Same here. I moved from 2022.5.4 to 2022.6.7. It's breaking my Wake On Lan switches.

I'm running HA on Oracle VM VirtualBox 6.1, installed on Windows 10. 
@ShadowRep @KitHubek @mbuico 
Hello all. Has anyone found a solution to this? I have several "is taking over 10 seconds" warnings. One of them is a wake_on_lan switch I have set up. The wake on lan functionality works for the first couple hours after a fresh reboot, but the error messages keep piling up in the log and ultimately the WOL functionality stops working. 
Same issue with multiple "taking over 10 seconds" warnings, HA Supervised on Debian 11.

Disappears upon reversion to 2022.6.6.

So which change in [2022.6.7](https://github.com/home-assistant/core/releases/tag/2022.6.7) is causing this? Not seeing an obvious candidate on initial glance.
> @ShadowRep @KitHubek @mbuico Hello all. Has anyone found a solution to this? I have several "is taking over 10 seconds" warnings. One of them is a wake_on_lan switch I have set up. The wake on lan functionality works for the first couple hours after a fresh reboot, but the error messages keep piling up in the log and ultimately the WOL functionality stops working.

I don't know what causes this and I have no idea where to even start to look for a solution.
I am not even sure someone who has the knowledge to correct this error has even seen this.
The WOL feature breaking after a few hours seems to be an even bigger problem.
Sorry. Did not mean to close this.
Have exactly the same issue since updating to 2022.6.7.
I'm running hassio on Rpi4 8gb on SSD drive.

Logs from everyday on scheduled reboot:

2022-06-28 03:09:43 WARNING (MainThread) [homeassistant.setup] Setup of zone is taking over 10 seconds.
2022-06-28 03:09:43 WARNING (MainThread) [homeassistant.setup] Setup of timer is taking over 10 seconds.
2022-06-28 03:09:43 WARNING (MainThread) [homeassistant.setup] Setup of input_button is taking over 10 seconds.
2022-06-28 03:09:43 WARNING (MainThread) [homeassistant.setup] Setup of input_text is taking over 10 seconds.
2022-06-28 03:09:43 WARNING (MainThread) [homeassistant.setup] Setup of input_datetime is taking over 10 seconds.
2022-06-28 03:09:43 WARNING (MainThread) [homeassistant.setup] Setup of counter is taking over 10 seconds.
2022-06-28 03:09:43 WARNING (MainThread) [homeassistant.setup] Setup of input_boolean is taking over 10 seconds.
2022-06-28 03:09:43 WARNING (MainThread) [homeassistant.setup] Setup of input_select is taking over 10 seconds.
2022-06-28 03:09:43 WARNING (MainThread) [homeassistant.setup] Setup of input_number is taking over 10 seconds.
Same issue - I have noticed that I have multiple homeassistant processes running when these errors occur. I've written a sensor and automation to kill them off when they appear. System has been a lot happier since! This is a straight 64bit HASSOS install on an RPI4
Same is happening to me since upgrading to 2022.6.7 - running on RPi4 as well

Commit message: fix conflict correctly

Patch to review:
diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py
index 906923138b9ca..394e4af3e2ee3 100644
--- a/homeassistant/components/mqtt/__init__.py
+++ b/homeassistant/components/mqtt/__init__.py
@@ -3,8 +3,6 @@
 
 import asyncio
 from collections.abc import Callable
-from dataclasses import dataclass
-import datetime as dt
 import logging
 from typing import Any, cast
 
@@ -23,7 +21,6 @@
     SERVICE_RELOAD,
 )
 from homeassistant.core import HassJob, HomeAssistant, ServiceCall, callback
-from homeassistant.data_entry_flow import BaseServiceInfo
 from homeassistant.exceptions import TemplateError, Unauthorized
 from homeassistant.helpers import config_validation as cv, event, template
 from homeassistant.helpers.device_registry import DeviceEntry
@@ -145,18 +142,6 @@
 )
 
 
-@dataclass
-class MqttServiceInfo(BaseServiceInfo):
-    """Prepared info from mqtt entries."""
-
-    topic: str
-    payload: ReceivePayloadType
-    qos: int
-    retain: bool
-    subscribed_topic: str
-    timestamp: dt.datetime
-
-
 async def _async_setup_discovery(
     hass: HomeAssistant, conf: ConfigType, config_entry
 ) -> None:
diff --git a/homeassistant/components/mqtt/discovery.py b/homeassistant/components/mqtt/discovery.py
index a480cdd568024..ebc3a170aeba4 100644
--- a/homeassistant/components/mqtt/discovery.py
+++ b/homeassistant/components/mqtt/discovery.py
@@ -17,6 +17,7 @@
     async_dispatcher_send,
 )
 from homeassistant.helpers.json import json_loads
+from homeassistant.helpers.service_info.mqtt import MqttServiceInfo
 from homeassistant.loader import async_get_mqtt
 
 from .. import mqtt
@@ -267,7 +268,7 @@ async def async_integration_message_received(integration, msg):
                 if key not in hass.data[INTEGRATION_UNSUBSCRIBE]:
                     return
 
-                data = mqtt.MqttServiceInfo(
+                data = MqttServiceInfo(
                     topic=msg.topic,
                     payload=msg.payload,
                     qos=msg.qos,
diff --git a/homeassistant/components/mqtt/models.py b/homeassistant/components/mqtt/models.py
index 9bce6baab8bfc..d5560f6954eeb 100644
--- a/homeassistant/components/mqtt/models.py
+++ b/homeassistant/components/mqtt/models.py
@@ -12,12 +12,12 @@
 from homeassistant.core import HomeAssistant, callback
 from homeassistant.helpers import template
 from homeassistant.helpers.entity import Entity
+from homeassistant.helpers.service_info.mqtt import ReceivePayloadType
 from homeassistant.helpers.typing import TemplateVarsType
 
 _SENTINEL = object()
 
 PublishPayloadType = Union[str, bytes, int, float, None]
-ReceivePayloadType = Union[str, bytes]
 
 
 @attr.s(slots=True, frozen=True)
diff --git a/homeassistant/components/tasmota/config_flow.py b/homeassistant/components/tasmota/config_flow.py
index e2109a16afe06..d8981090d5879 100644
--- a/homeassistant/components/tasmota/config_flow.py
+++ b/homeassistant/components/tasmota/config_flow.py
@@ -6,8 +6,9 @@
 import voluptuous as vol
 
 from homeassistant import config_entries
-from homeassistant.components.mqtt import MqttServiceInfo, valid_subscribe_topic
+from homeassistant.components.mqtt import valid_subscribe_topic
 from homeassistant.data_entry_flow import FlowResult
+from homeassistant.helpers.service_info.mqtt import MqttServiceInfo
 
 from .const import CONF_DISCOVERY_PREFIX, DEFAULT_PREFIX, DOMAIN
 
diff --git a/homeassistant/config_entries.py b/homeassistant/config_entries.py
index 4b76f63681a95..6e2b70be7cc5a 100644
--- a/homeassistant/config_entries.py
+++ b/homeassistant/config_entries.py
@@ -31,10 +31,10 @@
     from .components.bluetooth import BluetoothServiceInfo
     from .components.dhcp import DhcpServiceInfo
     from .components.hassio import HassioServiceInfo
-    from .components.mqtt import MqttServiceInfo
     from .components.ssdp import SsdpServiceInfo
     from .components.usb import UsbServiceInfo
     from .components.zeroconf import ZeroconfServiceInfo
+    from .helpers.service_info.mqtt import MqttServiceInfo
 
 _LOGGER = logging.getLogger(__name__)
 
diff --git a/homeassistant/helpers/config_entry_flow.py b/homeassistant/helpers/config_entry_flow.py
index 75a4dcd20f4e5..5334dc0960b61 100644
--- a/homeassistant/helpers/config_entry_flow.py
+++ b/homeassistant/helpers/config_entry_flow.py
@@ -6,7 +6,7 @@
 from typing import TYPE_CHECKING, Any, Generic, TypeVar, Union, cast
 
 from homeassistant import config_entries
-from homeassistant.components import bluetooth, dhcp, onboarding, ssdp, zeroconf
+from homeassistant.components import onboarding
 from homeassistant.core import HomeAssistant
 from homeassistant.data_entry_flow import FlowResult
 
@@ -15,8 +15,12 @@
 if TYPE_CHECKING:
     import asyncio
 
-    from homeassistant.components import mqtt
+    from homeassistant.components.bluetooh import BluetoothServiceInfo
+    from homeassistant.components.dhcp import DhcpServiceInfo
+    from homeassistant.components.ssdp import SsdpServiceInfo
+    from homeassistant.components.zeroconf import ZeroconfServiceInfo
 
+    from .service_info.mqtt import MqttServiceInfo
 
 _R = TypeVar("_R", bound="Awaitable[bool] | bool")
 DiscoveryFunctionType = Callable[[HomeAssistant], _R]
@@ -92,9 +96,7 @@ async def async_step_discovery(
 
         return await self.async_step_confirm()
 
-    async def async_step_bluetooth(
-        self, discovery_info: bluetooth.BluetoothServiceInfo
-    ) -> FlowResult:
+    async def async_step_bluetooth(self, discovery_info: BluetoothServiceInfo) -> FlowResult:
         """Handle a flow initialized by bluetooth discovery."""
         if self._async_in_progress() or self._async_current_entries():
             return self.async_abort(reason="single_instance_allowed")
@@ -103,7 +105,7 @@ async def async_step_bluetooth(
 
         return await self.async_step_confirm()
 
-    async def async_step_dhcp(self, discovery_info: dhcp.DhcpServiceInfo) -> FlowResult:
+    async def async_step_dhcp(self, discovery_info: DhcpServiceInfo) -> FlowResult:
         """Handle a flow initialized by dhcp discovery."""
         if self._async_in_progress() or self._async_current_entries():
             return self.async_abort(reason="single_instance_allowed")
@@ -113,7 +115,7 @@ async def async_step_dhcp(self, discovery_info: dhcp.DhcpServiceInfo) -> FlowRes
         return await self.async_step_confirm()
 
     async def async_step_homekit(
-        self, discovery_info: zeroconf.ZeroconfServiceInfo
+        self, discovery_info: ZeroconfServiceInfo
     ) -> FlowResult:
         """Handle a flow initialized by Homekit discovery."""
         if self._async_in_progress() or self._async_current_entries():
@@ -123,7 +125,7 @@ async def async_step_homekit(
 
         return await self.async_step_confirm()
 
-    async def async_step_mqtt(self, discovery_info: mqtt.MqttServiceInfo) -> FlowResult:
+    async def async_step_mqtt(self, discovery_info: MqttServiceInfo) -> FlowResult:
         """Handle a flow initialized by mqtt discovery."""
         if self._async_in_progress() or self._async_current_entries():
             return self.async_abort(reason="single_instance_allowed")
@@ -133,7 +135,7 @@ async def async_step_mqtt(self, discovery_info: mqtt.MqttServiceInfo) -> FlowRes
         return await self.async_step_confirm()
 
     async def async_step_zeroconf(
-        self, discovery_info: zeroconf.ZeroconfServiceInfo
+        self, discovery_info: ZeroconfServiceInfo
     ) -> FlowResult:
         """Handle a flow initialized by Zeroconf discovery."""
         if self._async_in_progress() or self._async_current_entries():
@@ -143,7 +145,7 @@ async def async_step_zeroconf(
 
         return await self.async_step_confirm()
 
-    async def async_step_ssdp(self, discovery_info: ssdp.SsdpServiceInfo) -> FlowResult:
+    async def async_step_ssdp(self, discovery_info: SsdpServiceInfo) -> FlowResult:
         """Handle a flow initialized by Ssdp discovery."""
         if self._async_in_progress() or self._async_current_entries():
             return self.async_abort(reason="single_instance_allowed")
diff --git a/homeassistant/helpers/service_info/mqtt.py b/homeassistant/helpers/service_info/mqtt.py
new file mode 100644
index 0000000000000..fcf5d4744f197
--- /dev/null
+++ b/homeassistant/helpers/service_info/mqtt.py
@@ -0,0 +1,20 @@
+"""MQTT Discovery data."""
+from dataclasses import dataclass
+import datetime as dt
+from typing import Union
+
+from homeassistant.data_entry_flow import BaseServiceInfo
+
+ReceivePayloadType = Union[str, bytes]
+
+
+@dataclass
+class MqttServiceInfo(BaseServiceInfo):
+    """Prepared info from mqtt entries."""
+
+    topic: str
+    payload: ReceivePayloadType
+    qos: int
+    retain: bool
+    subscribed_topic: str
+    timestamp: dt.datetime
diff --git a/tests/components/tasmota/test_config_flow.py b/tests/components/tasmota/test_config_flow.py
index 3413817892bc2..77a2787c0d5cc 100644
--- a/tests/components/tasmota/test_config_flow.py
+++ b/tests/components/tasmota/test_config_flow.py
@@ -1,6 +1,6 @@
 """Test config flow."""
 from homeassistant import config_entries
-from homeassistant.components import mqtt
+from homeassistant.helpers.service_info.mqtt import MqttServiceInfo
 
 from tests.common import MockConfigEntry
 
@@ -19,7 +19,7 @@ async def test_mqtt_abort_if_existing_entry(hass, mqtt_mock):
 
 async def test_mqtt_abort_invalid_topic(hass, mqtt_mock):
     """Check MQTT flow aborts if discovery topic is invalid."""
-    discovery_info = mqtt.MqttServiceInfo(
+    discovery_info = MqttServiceInfo(
         topic="tasmota/discovery/DC4F220848A2/bla",
         payload=(
             '{"ip":"192.168.0.136","dn":"Tasmota","fn":["Tasmota",null,null,null,null,'
@@ -42,7 +42,7 @@ async def test_mqtt_abort_invalid_topic(hass, mqtt_mock):
     assert result["type"] == "abort"
     assert result["reason"] == "invalid_discovery_info"
 
-    discovery_info = mqtt.MqttServiceInfo(
+    discovery_info = MqttServiceInfo(
         topic="tasmota/discovery/DC4F220848A2/config",
         payload="",
         qos=0,
@@ -56,7 +56,7 @@ async def test_mqtt_abort_invalid_topic(hass, mqtt_mock):
     assert result["type"] == "abort"
     assert result["reason"] == "invalid_discovery_info"
 
-    discovery_info = mqtt.MqttServiceInfo(
+    discovery_info = MqttServiceInfo(
         topic="tasmota/discovery/DC4F220848A2/config",
         payload=(
             '{"ip":"192.168.0.136","dn":"Tasmota","fn":["Tasmota",null,null,null,null,'
@@ -81,7 +81,7 @@ async def test_mqtt_abort_invalid_topic(hass, mqtt_mock):
 
 async def test_mqtt_setup(hass, mqtt_mock) -> None:
     """Test we can finish a config flow through MQTT with custom prefix."""
-    discovery_info = mqtt.MqttServiceInfo(
+    discovery_info = MqttServiceInfo(
         topic="tasmota/discovery/DC4F220848A2/config",
         payload=(
             '{"ip":"192.168.0.136","dn":"Tasmota","fn":["Tasmota",null,null,null,null,'


Code review comments:
diff_hunk: @@ -15,8 +15,12 @@
 if TYPE_CHECKING:
     import asyncio
 
-    from homeassistant.components import mqtt
+    from homeassistant.components.bluetooh import BluetoothServiceInfo
path: homeassistant/helpers/config_entry_flow.py
text: @author:
```suggestion
    from homeassistant.components.bluetooth import BluetoothServiceInfo
```