diff --git a/homeassistant/components/tplink/__init__.py b/homeassistant/components/tplink/__init__.py index 9b21e532776..e365f0f2453 100644 --- a/homeassistant/components/tplink/__init__.py +++ b/homeassistant/components/tplink/__init__.py @@ -1,6 +1,7 @@ """Component to embed TP-Link smart home devices.""" from __future__ import annotations +import asyncio from typing import Any from kasa import SmartDevice, SmartDeviceException @@ -8,6 +9,7 @@ from kasa.discover import Discover import voluptuous as vol from homeassistant import config_entries +from homeassistant.components import network from homeassistant.config_entries import ConfigEntry, ConfigEntryNotReady from homeassistant.const import CONF_HOST, CONF_MAC, CONF_NAME from homeassistant.core import HomeAssistant, callback @@ -79,6 +81,17 @@ def async_trigger_discovery( ) +async def async_discover_devices(hass: HomeAssistant) -> dict[str, SmartDevice]: + """Discover TPLink devices on configured network interfaces.""" + broadcast_addresses = await network.async_get_ipv4_broadcast_addresses(hass) + tasks = [Discover.discover(target=str(address)) for address in broadcast_addresses] + discovered_devices: dict[str, SmartDevice] = {} + for device_list in await asyncio.gather(*tasks): + for device in device_list.values(): + discovered_devices[dr.format_mac(device.mac)] = device + return discovered_devices + + async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up the TP-Link component.""" conf = config.get(DOMAIN) @@ -91,10 +104,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: elif entry.unique_id: config_entries_by_mac[entry.unique_id] = entry - discovered_devices = { - dr.format_mac(device.mac): device - for device in (await Discover.discover()).values() - } + discovered_devices = await async_discover_devices(hass) hosts_by_mac = {mac: device.host for mac, device in discovered_devices.items()} if legacy_entry: diff --git a/homeassistant/components/tplink/config_flow.py b/homeassistant/components/tplink/config_flow.py index e8f1fb0a702..d9bed10ee42 100644 --- a/homeassistant/components/tplink/config_flow.py +++ b/homeassistant/components/tplink/config_flow.py @@ -16,7 +16,7 @@ from homeassistant.data_entry_flow import FlowResult from homeassistant.helpers import device_registry as dr from homeassistant.helpers.typing import DiscoveryInfoType -from . import async_entry_is_legacy +from . import async_discover_devices, async_entry_is_legacy from .const import DOMAIN _LOGGER = logging.getLogger(__name__) @@ -119,10 +119,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): for entry in self._async_current_entries() if not async_entry_is_legacy(entry) } - self._discovered_devices = { - dr.format_mac(device.mac): device - for device in (await Discover.discover()).values() - } + self._discovered_devices = await async_discover_devices(self.hass) devices_name = { formatted_mac: f"{device.alias} {device.model} ({device.host}) {formatted_mac}" for formatted_mac, device in self._discovered_devices.items() diff --git a/homeassistant/components/tplink/manifest.json b/homeassistant/components/tplink/manifest.json index 03e63720dea..cfc9fce5213 100644 --- a/homeassistant/components/tplink/manifest.json +++ b/homeassistant/components/tplink/manifest.json @@ -5,6 +5,7 @@ "documentation": "https://www.home-assistant.io/integrations/tplink", "requirements": ["python-kasa==0.4.0"], "codeowners": ["@rytilahti", "@thegardenmonkey"], + "dependencies": ["network"], "quality_scale": "platinum", "iot_class": "local_polling", "dhcp": [ diff --git a/tests/components/tplink/__init__.py b/tests/components/tplink/__init__.py index f49f93258a3..1507685245b 100644 --- a/tests/components/tplink/__init__.py +++ b/tests/components/tplink/__init__.py @@ -87,7 +87,7 @@ def _mocked_strip() -> SmartStrip: def _patch_discovery(device=None, no_device=False): - async def _discovery(*_): + async def _discovery(*args, **kwargs): if no_device: return {} return {IP_ADDRESS: _mocked_bulb()}