diff --git a/homeassistant/components/shelly/config_flow.py b/homeassistant/components/shelly/config_flow.py index 9311be1a49e..abcfe689e93 100644 --- a/homeassistant/components/shelly/config_flow.py +++ b/homeassistant/components/shelly/config_flow.py @@ -119,6 +119,8 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): ) except HTTP_CONNECT_ERRORS: errors["base"] = "cannot_connect" + except KeyError: + errors["base"] = "firmware_not_fully_provisioned" except Exception: # pylint: disable=broad-except LOGGER.exception("Unexpected exception") errors["base"] = "unknown" @@ -160,6 +162,8 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): errors["base"] = "cannot_connect" except aioshelly.exceptions.JSONRPCError: errors["base"] = "cannot_connect" + except KeyError: + errors["base"] = "firmware_not_fully_provisioned" except Exception: # pylint: disable=broad-except LOGGER.exception("Unexpected exception") errors["base"] = "unknown" @@ -219,6 +223,8 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): try: self.device_info = await validate_input(self.hass, self.host, self.info, {}) + except KeyError: + LOGGER.debug("Shelly host %s firmware not fully provisioned", self.host) except HTTP_CONNECT_ERRORS: return self.async_abort(reason="cannot_connect") @@ -229,18 +235,21 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): ) -> FlowResult: """Handle discovery confirm.""" errors: dict[str, str] = {} - if user_input is not None: - return self.async_create_entry( - title=self.device_info["title"], - data={ - "host": self.host, - CONF_SLEEP_PERIOD: self.device_info[CONF_SLEEP_PERIOD], - "model": self.device_info["model"], - "gen": self.device_info["gen"], - }, - ) - - self._set_confirm_only() + try: + if user_input is not None: + return self.async_create_entry( + title=self.device_info["title"], + data={ + "host": self.host, + CONF_SLEEP_PERIOD: self.device_info[CONF_SLEEP_PERIOD], + "model": self.device_info["model"], + "gen": self.device_info["gen"], + }, + ) + except KeyError: + errors["base"] = "firmware_not_fully_provisioned" + else: + self._set_confirm_only() return self.async_show_form( step_id="confirm_discovery", diff --git a/homeassistant/components/shelly/strings.json b/homeassistant/components/shelly/strings.json index 209ae6682b8..db1c6043187 100644 --- a/homeassistant/components/shelly/strings.json +++ b/homeassistant/components/shelly/strings.json @@ -21,7 +21,8 @@ "error": { "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", "invalid_auth": "[%key:common::config_flow::error::invalid_auth%]", - "unknown": "[%key:common::config_flow::error::unknown%]" + "unknown": "[%key:common::config_flow::error::unknown%]", + "firmware_not_fully_provisioned": "Device not fully provisioned. Please contact Shelly support" }, "abort": { "already_configured": "[%key:common::config_flow::abort::already_configured_device%]", diff --git a/homeassistant/components/shelly/translations/en.json b/homeassistant/components/shelly/translations/en.json index c23eb13840c..f3e882c3016 100644 --- a/homeassistant/components/shelly/translations/en.json +++ b/homeassistant/components/shelly/translations/en.json @@ -6,6 +6,7 @@ }, "error": { "cannot_connect": "Failed to connect", + "firmware_not_fully_provisioned": "Device not fully provisioned. Please contact Shelly support", "invalid_auth": "Invalid authentication", "unknown": "Unexpected error" }, diff --git a/tests/components/shelly/test_config_flow.py b/tests/components/shelly/test_config_flow.py index 1293fe92760..713999de36f 100644 --- a/tests/components/shelly/test_config_flow.py +++ b/tests/components/shelly/test_config_flow.py @@ -225,6 +225,29 @@ async def test_form_errors_get_info(hass, error): assert result2["errors"] == {"base": base_error} +@pytest.mark.parametrize("error", [(KeyError, "firmware_not_fully_provisioned")]) +async def test_form_missing_key_get_info(hass, error): + """Test we handle missing key.""" + exc, base_error = error + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": config_entries.SOURCE_USER} + ) + with patch( + "aioshelly.common.get_info", + return_value={"mac": "test-mac", "type": "SHSW-1", "auth": False, "gen": "2"}, + ), patch( + "homeassistant.components.shelly.config_flow.validate_input", + side_effect=KeyError, + ): + result2 = await hass.config_entries.flow.async_configure( + result["flow_id"], + {"host": "1.1.1.1"}, + ) + + assert result2["type"] == data_entry_flow.RESULT_TYPE_FORM + assert result2["errors"] == {"base": base_error} + + @pytest.mark.parametrize( "error", [(asyncio.TimeoutError, "cannot_connect"), (ValueError, "unknown")] )