diff --git a/homeassistant/components/shelly/config_flow.py b/homeassistant/components/shelly/config_flow.py index 8679edf5382..70d2c2492e8 100644 --- a/homeassistant/components/shelly/config_flow.py +++ b/homeassistant/components/shelly/config_flow.py @@ -53,6 +53,8 @@ BLE_SCANNER_OPTIONS = [ selector.SelectOptionDict(value=BLEScannerMode.PASSIVE, label="Passive"), ] +INTERNAL_WIFI_AP_IP = "192.168.33.1" + async def validate_input( hass: HomeAssistant, @@ -217,7 +219,17 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): current_entry := await self.async_set_unique_id(mac) ) and current_entry.data[CONF_HOST] == host: await async_reconnect_soon(self.hass, current_entry) - self._abort_if_unique_id_configured({CONF_HOST: host}) + if host == INTERNAL_WIFI_AP_IP: + # If the device is broadcasting the internal wifi ap ip + # we can't connect to it, so we should not update the + # entry with the new host as it will be unreachable + # + # This is a workaround for a bug in the firmware 0.12 (and older?) + # which should be removed once the firmware is fixed + # and the old version is no longer in use + self._abort_if_unique_id_configured() + else: + self._abort_if_unique_id_configured({CONF_HOST: host}) async def async_step_zeroconf( self, discovery_info: zeroconf.ZeroconfServiceInfo diff --git a/tests/components/shelly/test_config_flow.py b/tests/components/shelly/test_config_flow.py index 6795049a207..1c0a32853e1 100644 --- a/tests/components/shelly/test_config_flow.py +++ b/tests/components/shelly/test_config_flow.py @@ -1,6 +1,7 @@ """Test the Shelly config flow.""" from __future__ import annotations +from dataclasses import replace from unittest.mock import AsyncMock, Mock, patch from aioshelly.exceptions import ( @@ -12,6 +13,7 @@ import pytest from homeassistant import config_entries, data_entry_flow from homeassistant.components import zeroconf +from homeassistant.components.shelly import config_flow from homeassistant.components.shelly.const import ( CONF_BLE_SCANNER_MODE, DOMAIN, @@ -704,6 +706,30 @@ async def test_zeroconf_already_configured(hass): assert entry.data["host"] == "1.1.1.1" +async def test_zeroconf_with_wifi_ap_ip(hass): + """Test we ignore the Wi-FI AP IP.""" + + entry = MockConfigEntry( + domain="shelly", unique_id="test-mac", data={"host": "2.2.2.2"} + ) + entry.add_to_hass(hass) + + with patch( + "aioshelly.common.get_info", + return_value={"mac": "test-mac", "type": "SHSW-1", "auth": False}, + ): + result = await hass.config_entries.flow.async_init( + DOMAIN, + data=replace(DISCOVERY_INFO, host=config_flow.INTERNAL_WIFI_AP_IP), + context={"source": config_entries.SOURCE_ZEROCONF}, + ) + assert result["type"] == data_entry_flow.FlowResultType.ABORT + assert result["reason"] == "already_configured" + + # Test config entry was not updated with the wifi ap ip + assert entry.data["host"] == "2.2.2.2" + + async def test_zeroconf_firmware_unsupported(hass): """Test we abort if device firmware is unsupported.""" with patch("aioshelly.common.get_info", side_effect=FirmwareUnsupported):