diff --git a/homeassistant/components/shelly/config_flow.py b/homeassistant/components/shelly/config_flow.py index 0ebf70d2f00..b13c4090a10 100644 --- a/homeassistant/components/shelly/config_flow.py +++ b/homeassistant/components/shelly/config_flow.py @@ -62,6 +62,8 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): info = await self._async_get_info(host) except HTTP_CONNECT_ERRORS: errors["base"] = "cannot_connect" + except aioshelly.FirmwareUnsupported: + return self.async_abort(reason="unsupported_firmware") except Exception: # pylint: disable=broad-except _LOGGER.exception("Unexpected exception") errors["base"] = "unknown" @@ -133,6 +135,8 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): self.info = info = await self._async_get_info(zeroconf_info["host"]) except HTTP_CONNECT_ERRORS: return self.async_abort(reason="cannot_connect") + except aioshelly.FirmwareUnsupported: + return self.async_abort(reason="unsupported_firmware") await self.async_set_unique_id(info["mac"]) self._abort_if_unique_id_configured({CONF_HOST: zeroconf_info["host"]}) diff --git a/homeassistant/components/shelly/manifest.json b/homeassistant/components/shelly/manifest.json index eebf53dd69c..1757bb28d9d 100644 --- a/homeassistant/components/shelly/manifest.json +++ b/homeassistant/components/shelly/manifest.json @@ -3,7 +3,7 @@ "name": "Shelly", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/shelly", - "requirements": ["aioshelly==0.3.2"], + "requirements": ["aioshelly==0.3.3"], "zeroconf": [{"type": "_http._tcp.local.", "name":"shelly*"}], "codeowners": ["@balloob", "@bieniu"] } diff --git a/homeassistant/components/shelly/strings.json b/homeassistant/components/shelly/strings.json index 16dc331e452..1a7c8c78189 100644 --- a/homeassistant/components/shelly/strings.json +++ b/homeassistant/components/shelly/strings.json @@ -24,7 +24,8 @@ "unknown": "[%key:common::config_flow::error::unknown%]" }, "abort": { - "already_configured": "[%key:common::config_flow::abort::already_configured_device%]" + "already_configured": "[%key:common::config_flow::abort::already_configured_device%]", + "unsupported_firmware": "The device is using an unsupported firmware version." } } } diff --git a/requirements_all.txt b/requirements_all.txt index 6406f32bad6..a6b7a549620 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -221,7 +221,7 @@ aiopvpc==2.0.2 aiopylgtv==0.3.3 # homeassistant.components.shelly -aioshelly==0.3.2 +aioshelly==0.3.3 # homeassistant.components.switcher_kis aioswitcher==1.2.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 455341a2483..4025059a6b7 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -134,7 +134,7 @@ aiopvpc==2.0.2 aiopylgtv==0.3.3 # homeassistant.components.shelly -aioshelly==0.3.2 +aioshelly==0.3.3 # homeassistant.components.switcher_kis aioswitcher==1.2.1 diff --git a/tests/components/shelly/test_config_flow.py b/tests/components/shelly/test_config_flow.py index 366b52ca4e7..03eb907d09b 100644 --- a/tests/components/shelly/test_config_flow.py +++ b/tests/components/shelly/test_config_flow.py @@ -2,6 +2,7 @@ import asyncio import aiohttp +import aioshelly import pytest from homeassistant import config_entries, setup @@ -113,10 +114,7 @@ async def test_form_errors_get_info(hass, error): DOMAIN, context={"source": config_entries.SOURCE_USER} ) - with patch( - "aioshelly.get_info", - side_effect=exc, - ): + with patch("aioshelly.get_info", side_effect=exc): result2 = await hass.config_entries.flow.async_configure( result["flow_id"], {"host": "1.1.1.1"}, @@ -138,10 +136,7 @@ async def test_form_errors_test_connection(hass, error): with patch( "aioshelly.get_info", return_value={"mac": "test-mac", "auth": False} - ), patch( - "aioshelly.Device.create", - new=AsyncMock(side_effect=exc), - ): + ), patch("aioshelly.Device.create", new=AsyncMock(side_effect=exc)): result2 = await hass.config_entries.flow.async_configure( result["flow_id"], {"host": "1.1.1.1"}, @@ -179,6 +174,22 @@ async def test_form_already_configured(hass): assert entry.data["host"] == "1.1.1.1" +async def test_form_firmware_unsupported(hass): + """Test we abort if device firmware is unsupported.""" + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": config_entries.SOURCE_USER} + ) + + with patch("aioshelly.get_info", side_effect=aioshelly.FirmwareUnsupported): + result2 = await hass.config_entries.flow.async_configure( + result["flow_id"], + {"host": "1.1.1.1"}, + ) + + assert result2["type"] == "abort" + assert result2["reason"] == "unsupported_firmware" + + @pytest.mark.parametrize( "error", [ @@ -315,12 +326,22 @@ async def test_zeroconf_already_configured(hass): assert entry.data["host"] == "1.1.1.1" +async def test_zeroconf_firmware_unsupported(hass): + """Test we abort if device firmware is unsupported.""" + with patch("aioshelly.get_info", side_effect=aioshelly.FirmwareUnsupported): + result = await hass.config_entries.flow.async_init( + DOMAIN, + data={"host": "1.1.1.1", "name": "shelly1pm-12345"}, + context={"source": config_entries.SOURCE_ZEROCONF}, + ) + + assert result["type"] == "abort" + assert result["reason"] == "unsupported_firmware" + + async def test_zeroconf_cannot_connect(hass): """Test we get the form.""" - with patch( - "aioshelly.get_info", - side_effect=asyncio.TimeoutError, - ): + with patch("aioshelly.get_info", side_effect=asyncio.TimeoutError): result = await hass.config_entries.flow.async_init( DOMAIN, data={"host": "1.1.1.1", "name": "shelly1pm-12345"},