diff --git a/homeassistant/components/bond/config_flow.py b/homeassistant/components/bond/config_flow.py index 179c9d678f3d..bbc39a620284 100644 --- a/homeassistant/components/bond/config_flow.py +++ b/homeassistant/components/bond/config_flow.py @@ -123,7 +123,18 @@ class BondConfigFlow(ConfigFlow, domain=DOMAIN): name: str = discovery_info.name host: str = discovery_info.host bond_id = name.partition(".")[0] - await self.async_set_unique_id(bond_id) + entry = await self.async_set_unique_id(bond_id) + + # A bridge on both Wi-Fi and Ethernet announces every address it has, + # and host is whichever one refreshed its record last. Stay on the + # address we already talk to as long as the bridge still answers to it. + if ( + entry is not None + and (known_host := entry.data.get(CONF_HOST)) + and known_host in {str(ip) for ip in discovery_info.ip_addresses} + ): + host = known_host + return await self.async_step_any_discovery(bond_id, host) async def async_step_any_discovery( diff --git a/tests/components/bond/test_config_flow.py b/tests/components/bond/test_config_flow.py index 68f27bd9567a..e39ef5954cac 100644 --- a/tests/components/bond/test_config_flow.py +++ b/tests/components/bond/test_config_flow.py @@ -732,6 +732,42 @@ async def test_zeroconf_already_configured_no_reload_same_host( assert len(mock_setup_entry.mock_calls) == 0 +async def test_zeroconf_already_configured_keeps_valid_host( + hass: HomeAssistant, +) -> None: + """Test zeroconf keeps the stored host when the bridge still announces it.""" + entry = MockConfigEntry( + domain=DOMAIN, + unique_id="already-registered-bond-id", + data={CONF_HOST: "127.0.0.3", CONF_ACCESS_TOKEN: "correct-token"}, + ) + entry.add_to_hass(hass) + + with ( + _patch_async_setup_entry() as mock_setup_entry, + patch_bond_token(return_value={"token": "correct-token"}), + ): + result = await hass.config_entries.flow.async_init( + DOMAIN, + context={"source": config_entries.SOURCE_ZEROCONF}, + data=ZeroconfServiceInfo( + ip_address=ip_address("127.0.0.2"), + ip_addresses=[ip_address("127.0.0.2"), ip_address("127.0.0.3")], + hostname="mock_hostname", + name="already-registered-bond-id.some-other-tail-info", + port=None, + properties={}, + type="mock_type", + ), + ) + await hass.async_block_till_done() + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "already_configured" + assert entry.data[CONF_HOST] == "127.0.0.3" + assert len(mock_setup_entry.mock_calls) == 0 + + async def test_zeroconf_form_unexpected_error(hass: HomeAssistant) -> None: """Test we handle unexpected error gracefully.""" await _help_test_form_unexpected_error(