From 30d465e9dd461700af6426018ae42cde904b659c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 13 Jul 2021 23:44:58 -1000 Subject: [PATCH] Update homekit to use network integration (#52946) --- homeassistant/components/homekit/__init__.py | 12 ++++---- .../components/homekit/manifest.json | 2 +- .../components/homekit/type_cameras.py | 3 +- tests/components/homekit/test_homekit.py | 29 +++++++++++-------- 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/homeassistant/components/homekit/__init__.py b/homeassistant/components/homekit/__init__.py index c0cc5867799..842bcf81efe 100644 --- a/homeassistant/components/homekit/__init__.py +++ b/homeassistant/components/homekit/__init__.py @@ -8,7 +8,7 @@ from aiohttp import web from pyhap.const import STANDALONE_AID import voluptuous as vol -from homeassistant.components import zeroconf +from homeassistant.components import network, zeroconf from homeassistant.components.binary_sensor import ( DEVICE_CLASS_BATTERY_CHARGING, DEVICE_CLASS_MOTION, @@ -40,7 +40,6 @@ import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entityfilter import BASE_FILTER_SCHEMA, FILTER_SCHEMA from homeassistant.helpers.reload import async_integration_yaml_config from homeassistant.loader import IntegrationNotFound, async_get_integration -from homeassistant.util import get_local_ip from . import ( # noqa: F401 type_cameras, @@ -119,6 +118,8 @@ STATUS_WAIT = 3 PORT_CLEANUP_CHECK_INTERVAL_SECS = 1 +MDNS_TARGET_IP = "224.0.0.251" + def _has_all_unique_names_and_ports(bridges): """Validate that each homekit bridge configured has a unique name.""" @@ -243,7 +244,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: _LOGGER.debug("Begin setup HomeKit for %s", name) # ip_address and advertise_ip are yaml only - ip_address = conf.get(CONF_IP_ADDRESS) + ip_address = conf.get( + CONF_IP_ADDRESS, await network.async_get_source_ip(hass, MDNS_TARGET_IP) + ) advertise_ip = conf.get(CONF_ADVERTISE_IP) # exclude_accessory_mode is only used for config flow # to indicate that the config entry was setup after @@ -458,7 +461,6 @@ class HomeKit: def setup(self, async_zeroconf_instance): """Set up bridge and accessory driver.""" - ip_addr = self._ip_address or get_local_ip() persist_file = get_persist_fullpath_for_entry_id(self.hass, self._entry_id) self.driver = HomeDriver( @@ -467,7 +469,7 @@ class HomeKit: self._name, self._entry_title, loop=self.hass.loop, - address=ip_addr, + address=self._ip_address, port=self._port, persist_file=persist_file, advertised_address=self._advertise_ip, diff --git a/homeassistant/components/homekit/manifest.json b/homeassistant/components/homekit/manifest.json index 39c40e03614..40bca03bae0 100644 --- a/homeassistant/components/homekit/manifest.json +++ b/homeassistant/components/homekit/manifest.json @@ -9,7 +9,7 @@ "base36==0.1.1", "PyTurboJPEG==1.5.0" ], - "dependencies": ["http", "camera", "ffmpeg"], + "dependencies": ["http", "camera", "ffmpeg", "network"], "after_dependencies": ["zeroconf"], "codeowners": ["@bdraco"], "zeroconf": ["_homekit._tcp.local."], diff --git a/homeassistant/components/homekit/type_cameras.py b/homeassistant/components/homekit/type_cameras.py index 48f7ad9b064..e21ca189b4e 100644 --- a/homeassistant/components/homekit/type_cameras.py +++ b/homeassistant/components/homekit/type_cameras.py @@ -18,7 +18,6 @@ from homeassistant.helpers.event import ( async_track_state_change_event, async_track_time_interval, ) -from homeassistant.util import get_local_ip from .accessories import TYPES, HomeAccessory from .const import ( @@ -181,7 +180,7 @@ class Camera(HomeAccessory, PyhapCamera): ] } - stream_address = config.get(CONF_STREAM_ADDRESS, get_local_ip()) + stream_address = config.get(CONF_STREAM_ADDRESS, driver.state.address) options = { "video": video_options, diff --git a/tests/components/homekit/test_homekit.py b/tests/components/homekit/test_homekit.py index 5e9ea4fd4b6..7fd588e62d0 100644 --- a/tests/components/homekit/test_homekit.py +++ b/tests/components/homekit/test_homekit.py @@ -156,7 +156,9 @@ async def test_setup_min(hass, mock_zeroconf): ) entry.add_to_hass(hass) - with patch(f"{PATH_HOMEKIT}.HomeKit") as mock_homekit: + with patch(f"{PATH_HOMEKIT}.HomeKit") as mock_homekit, patch( + "homeassistant.components.network.async_get_source_ip", return_value="1.2.3.4" + ): mock_homekit.return_value = homekit = Mock() type(homekit).async_start = AsyncMock() assert await hass.config_entries.async_setup(entry.entry_id) @@ -166,7 +168,7 @@ async def test_setup_min(hass, mock_zeroconf): hass, BRIDGE_NAME, DEFAULT_PORT, - None, + "1.2.3.4", ANY, ANY, {}, @@ -249,7 +251,7 @@ async def test_homekit_setup(hass, hk_driver, mock_zeroconf): hass, BRIDGE_NAME, DEFAULT_PORT, - None, + IP_ADDRESS, True, {}, {}, @@ -262,10 +264,7 @@ async def test_homekit_setup(hass, hk_driver, mock_zeroconf): hass.states.async_set("light.demo", "on") hass.states.async_set("light.demo2", "on") zeroconf_mock = MagicMock() - with patch( - f"{PATH_HOMEKIT}.HomeDriver", return_value=hk_driver - ) as mock_driver, patch("homeassistant.util.get_local_ip") as mock_ip: - mock_ip.return_value = IP_ADDRESS + with patch(f"{PATH_HOMEKIT}.HomeDriver", return_value=hk_driver) as mock_driver: await hass.async_add_executor_job(homekit.setup, zeroconf_mock) path = get_persist_fullpath_for_entry_id(hass, entry.entry_id) @@ -842,7 +841,9 @@ async def test_yaml_updates_update_config_entry_for_name(hass, mock_zeroconf): ) entry.add_to_hass(hass) - with patch(f"{PATH_HOMEKIT}.HomeKit") as mock_homekit: + with patch(f"{PATH_HOMEKIT}.HomeKit") as mock_homekit, patch( + "homeassistant.components.network.async_get_source_ip", return_value="1.2.3.4" + ): mock_homekit.return_value = homekit = Mock() type(homekit).async_start = AsyncMock() assert await async_setup_component( @@ -854,7 +855,7 @@ async def test_yaml_updates_update_config_entry_for_name(hass, mock_zeroconf): hass, BRIDGE_NAME, 12345, - None, + "1.2.3.4", ANY, ANY, {}, @@ -1109,7 +1110,9 @@ async def test_reload(hass, mock_zeroconf): ) entry.add_to_hass(hass) - with patch(f"{PATH_HOMEKIT}.HomeKit") as mock_homekit: + with patch(f"{PATH_HOMEKIT}.HomeKit") as mock_homekit, patch( + "homeassistant.components.network.async_get_source_ip", return_value="1.2.3.4" + ): mock_homekit.return_value = homekit = Mock() assert await async_setup_component( hass, "homekit", {"homekit": {CONF_NAME: "reloadable", CONF_PORT: 12345}} @@ -1120,7 +1123,7 @@ async def test_reload(hass, mock_zeroconf): hass, "reloadable", 12345, - None, + "1.2.3.4", ANY, False, {}, @@ -1142,6 +1145,8 @@ async def test_reload(hass, mock_zeroconf): f"{PATH_HOMEKIT}.get_accessory" ), patch( "pyhap.accessory_driver.AccessoryDriver.async_start" + ), patch( + "homeassistant.components.network.async_get_source_ip", return_value="1.2.3.4" ): mock_homekit2.return_value = homekit = Mock() await hass.services.async_call( @@ -1156,7 +1161,7 @@ async def test_reload(hass, mock_zeroconf): hass, "reloadable", 45678, - None, + "1.2.3.4", ANY, False, {},