diff --git a/homeassistant/components/dlna_dmr/manifest.json b/homeassistant/components/dlna_dmr/manifest.json index d11b32a6dd5..e9ac437fe46 100644 --- a/homeassistant/components/dlna_dmr/manifest.json +++ b/homeassistant/components/dlna_dmr/manifest.json @@ -3,6 +3,7 @@ "name": "DLNA Digital Media Renderer", "documentation": "https://www.home-assistant.io/integrations/dlna_dmr", "requirements": ["async-upnp-client==0.19.1"], + "dependencies": ["network"], "codeowners": [], "iot_class": "local_push" } diff --git a/homeassistant/components/dlna_dmr/media_player.py b/homeassistant/components/dlna_dmr/media_player.py index b2999a5ae56..36f62155b2d 100644 --- a/homeassistant/components/dlna_dmr/media_player.py +++ b/homeassistant/components/dlna_dmr/media_player.py @@ -24,6 +24,8 @@ from homeassistant.components.media_player.const import ( SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET, ) +from homeassistant.components.network import async_get_source_ip +from homeassistant.components.network.const import PUBLIC_TARGET_IP from homeassistant.const import ( CONF_NAME, CONF_URL, @@ -38,7 +40,6 @@ from homeassistant.core import HomeAssistant from homeassistant.exceptions import PlatformNotReady from homeassistant.helpers.aiohttp_client import async_get_clientsession import homeassistant.helpers.config_validation as cv -from homeassistant.util import get_local_ip import homeassistant.util.dt as dt_util _LOGGER = logging.getLogger(__name__) @@ -142,7 +143,7 @@ async def async_setup_platform( async with hass.data[DLNA_DMR_DATA]["lock"]: server_host = config.get(CONF_LISTEN_IP) if server_host is None: - server_host = get_local_ip() + server_host = await async_get_source_ip(hass, PUBLIC_TARGET_IP) server_port = config.get(CONF_LISTEN_PORT, DEFAULT_LISTEN_PORT) callback_url_override = config.get(CONF_CALLBACK_URL_OVERRIDE) event_handler = await async_start_event_handler( diff --git a/homeassistant/components/fritz/switch.py b/homeassistant/components/fritz/switch.py index b1ec63e0ce9..10eb6553dbd 100644 --- a/homeassistant/components/fritz/switch.py +++ b/homeassistant/components/fritz/switch.py @@ -16,13 +16,14 @@ from fritzconnection.core.exceptions import ( import slugify as unicode_slug import xmltodict +from homeassistant.components.network import async_get_source_ip from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.util import get_local_ip, slugify +from homeassistant.util import slugify from .common import ( FritzBoxBaseEntity, @@ -161,7 +162,7 @@ def deflection_entities_list( def port_entities_list( - fritzbox_tools: FritzBoxTools, device_friendly_name: str + fritzbox_tools: FritzBoxTools, device_friendly_name: str, local_ip: str ) -> list[FritzBoxPortSwitch]: """Get list of port forwarding entities.""" @@ -194,7 +195,6 @@ def port_entities_list( port_forwards_count, ) - local_ip = get_local_ip() _LOGGER.debug("IP source for %s is %s", fritzbox_tools.host, local_ip) for i in range(port_forwards_count): @@ -290,12 +290,15 @@ def profile_entities_list( def all_entities_list( - fritzbox_tools: FritzBoxTools, device_friendly_name: str, data_fritz: FritzData + fritzbox_tools: FritzBoxTools, + device_friendly_name: str, + data_fritz: FritzData, + local_ip: str, ) -> list[Entity]: """Get a list of all entities.""" return [ *deflection_entities_list(fritzbox_tools, device_friendly_name), - *port_entities_list(fritzbox_tools, device_friendly_name), + *port_entities_list(fritzbox_tools, device_friendly_name, local_ip), *wifi_entities_list(fritzbox_tools, device_friendly_name), *profile_entities_list(fritzbox_tools, data_fritz), ] @@ -311,8 +314,12 @@ async def async_setup_entry( _LOGGER.debug("Fritzbox services: %s", fritzbox_tools.connection.services) + local_ip = await async_get_source_ip( + fritzbox_tools.hass, target_ip=fritzbox_tools.host + ) + entities_list = await hass.async_add_executor_job( - all_entities_list, fritzbox_tools, entry.title, data_fritz + all_entities_list, fritzbox_tools, entry.title, data_fritz, local_ip ) async_add_entities(entities_list) diff --git a/homeassistant/components/local_ip/manifest.json b/homeassistant/components/local_ip/manifest.json index f7e245aac05..cec6e094f50 100644 --- a/homeassistant/components/local_ip/manifest.json +++ b/homeassistant/components/local_ip/manifest.json @@ -3,6 +3,7 @@ "name": "Local IP Address", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/local_ip", + "dependencies": ["network"], "codeowners": ["@issacg"], "iot_class": "local_polling" } diff --git a/homeassistant/components/local_ip/sensor.py b/homeassistant/components/local_ip/sensor.py index c7bc53caa69..661ef88e641 100644 --- a/homeassistant/components/local_ip/sensor.py +++ b/homeassistant/components/local_ip/sensor.py @@ -1,11 +1,12 @@ """Sensor platform for local_ip.""" +from homeassistant.components.network import async_get_source_ip +from homeassistant.components.network.const import PUBLIC_TARGET_IP from homeassistant.components.sensor import SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.util import get_local_ip from .const import DOMAIN, SENSOR @@ -30,6 +31,8 @@ class IPSensor(SensorEntity): """Initialize the sensor.""" self._attr_name = name - def update(self) -> None: + async def async_update(self) -> None: """Fetch new state data for the sensor.""" - self._attr_state = get_local_ip() + self._attr_state = await async_get_source_ip( + self.hass, target_ip=PUBLIC_TARGET_IP + ) diff --git a/homeassistant/components/network/__init__.py b/homeassistant/components/network/__init__.py index 6f11b0947d8..48903d145e7 100644 --- a/homeassistant/components/network/__init__.py +++ b/homeassistant/components/network/__init__.py @@ -33,7 +33,7 @@ async def async_get_adapters(hass: HomeAssistant) -> list[Adapter]: @bind_hass -async def async_get_source_ip(hass: HomeAssistant, target_ip: str) -> str | None: +async def async_get_source_ip(hass: HomeAssistant, target_ip: str) -> str: """Get the source ip for a target ip.""" adapters = await async_get_adapters(hass) all_ipv4s = [] diff --git a/homeassistant/components/network/const.py b/homeassistant/components/network/const.py index ff69f026fef..8b695a52e13 100644 --- a/homeassistant/components/network/const.py +++ b/homeassistant/components/network/const.py @@ -16,7 +16,7 @@ ATTR_CONFIGURED_ADAPTERS: Final = "configured_adapters" DEFAULT_CONFIGURED_ADAPTERS: list[str] = [] MDNS_TARGET_IP: Final = "224.0.0.251" - +PUBLIC_TARGET_IP: Final = "8.8.8.8" NETWORK_CONFIG_SCHEMA = vol.Schema( { diff --git a/homeassistant/components/upnp/__init__.py b/homeassistant/components/upnp/__init__.py index 5788ec1b3ef..6ad7111ae12 100644 --- a/homeassistant/components/upnp/__init__.py +++ b/homeassistant/components/upnp/__init__.py @@ -6,12 +6,13 @@ import voluptuous as vol from homeassistant import config_entries from homeassistant.components import ssdp +from homeassistant.components.network import async_get_source_ip +from homeassistant.components.network.const import PUBLIC_TARGET_IP from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.helpers import config_validation as cv, device_registry as dr from homeassistant.helpers.typing import ConfigType -from homeassistant.util import get_local_ip from .const import ( CONF_LOCAL_IP, @@ -63,7 +64,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType): _LOGGER.debug("async_setup, config: %s", config) conf_default = CONFIG_SCHEMA({DOMAIN: {}})[DOMAIN] conf = config.get(DOMAIN, conf_default) - local_ip = await hass.async_add_executor_job(get_local_ip) + local_ip = await async_get_source_ip(hass, PUBLIC_TARGET_IP) hass.data[DOMAIN] = { DOMAIN_CONFIG: conf, DOMAIN_DEVICES: {}, diff --git a/homeassistant/components/upnp/manifest.json b/homeassistant/components/upnp/manifest.json index 810a53c9e28..41d50b4bae8 100644 --- a/homeassistant/components/upnp/manifest.json +++ b/homeassistant/components/upnp/manifest.json @@ -4,7 +4,7 @@ "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/upnp", "requirements": ["async-upnp-client==0.19.1"], - "dependencies": ["ssdp"], + "dependencies": ["network", "ssdp"], "codeowners": ["@StevenLooman"], "ssdp": [ { diff --git a/homeassistant/components/zeroconf/__init__.py b/homeassistant/components/zeroconf/__init__.py index d8d664b63c5..907ec680cb4 100644 --- a/homeassistant/components/zeroconf/__init__.py +++ b/homeassistant/components/zeroconf/__init__.py @@ -19,8 +19,9 @@ from zeroconf import ( ) from zeroconf.asyncio import AsyncServiceInfo -from homeassistant import config_entries, util +from homeassistant import config_entries from homeassistant.components import network +from homeassistant.components.network import async_get_source_ip from homeassistant.components.network.models import Adapter from homeassistant.const import ( EVENT_HOMEASSISTANT_START, @@ -222,7 +223,7 @@ async def _async_register_hass_zc_service( # Set old base URL based on external or internal params["base_url"] = params["external_url"] or params["internal_url"] - host_ip = util.get_local_ip() + host_ip = await async_get_source_ip(hass, target_ip=MDNS_TARGET_IP) try: host_ip_pton = socket.inet_pton(socket.AF_INET, host_ip) diff --git a/tests/components/local_ip/test_init.py b/tests/components/local_ip/test_init.py index a7ebfba28e2..be1e689ca16 100644 --- a/tests/components/local_ip/test_init.py +++ b/tests/components/local_ip/test_init.py @@ -1,6 +1,7 @@ """Tests for the local_ip component.""" from homeassistant.components.local_ip import DOMAIN -from homeassistant.util import get_local_ip +from homeassistant.components.network import async_get_source_ip +from homeassistant.components.zeroconf import MDNS_TARGET_IP from tests.common import MockConfigEntry @@ -13,7 +14,7 @@ async def test_basic_setup(hass): await hass.config_entries.async_setup(entry.entry_id) await hass.async_block_till_done() - local_ip = await hass.async_add_executor_job(get_local_ip) + local_ip = await async_get_source_ip(hass, target_ip=MDNS_TARGET_IP) state = hass.states.get(f"sensor.{DOMAIN}") assert state assert state.state == local_ip