diff --git a/homeassistant/components/huawei_lte/.translations/en.json b/homeassistant/components/huawei_lte/.translations/en.json index 8681e3355a4..4e366e0ce31 100644 --- a/homeassistant/components/huawei_lte/.translations/en.json +++ b/homeassistant/components/huawei_lte/.translations/en.json @@ -5,6 +5,7 @@ }, "error": { "connection_failed": "Connection failed", + "connection_timeout": "Connection timeout", "incorrect_password": "Incorrect password", "incorrect_username": "Incorrect username", "incorrect_username_or_password": "Incorrect username or password", diff --git a/homeassistant/components/huawei_lte/__init__.py b/homeassistant/components/huawei_lte/__init__.py index e224f45ba90..112fcb6ec52 100644 --- a/homeassistant/components/huawei_lte/__init__.py +++ b/homeassistant/components/huawei_lte/__init__.py @@ -18,6 +18,7 @@ from huawei_lte_api.exceptions import ( ResponseErrorLoginRequiredException, ResponseErrorNotSupportedException, ) +from requests.exceptions import Timeout from url_normalize import url_normalize from homeassistant.components.device_tracker import DOMAIN as DEVICE_TRACKER_DOMAIN @@ -33,6 +34,7 @@ from homeassistant.const import ( EVENT_HOMEASSISTANT_STOP, ) from homeassistant.core import CALLBACK_TYPE +from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.helpers import config_validation as cv, discovery from homeassistant.helpers.dispatcher import ( async_dispatcher_connect, @@ -44,6 +46,7 @@ from homeassistant.helpers.event import async_track_time_interval from homeassistant.helpers.typing import HomeAssistantType from .const import ( ALL_KEYS, + CONNECTION_TIMEOUT, DEFAULT_DEVICE_NAME, DOMAIN, KEY_DEVICE_BASIC_INFORMATION, @@ -254,16 +257,21 @@ async def async_setup_entry(hass: HomeAssistantType, config_entry: ConfigEntry) username = config_entry.data.get(CONF_USERNAME) password = config_entry.data.get(CONF_PASSWORD) if username or password: - connection = AuthorizedConnection(url, username=username, password=password) + connection = AuthorizedConnection( + url, username=username, password=password, timeout=CONNECTION_TIMEOUT + ) else: - connection = Connection(url) + connection = Connection(url, timeout=CONNECTION_TIMEOUT) return connection def signal_update() -> None: """Signal updates to data.""" dispatcher_send(hass, UPDATE_SIGNAL, url) - connection = await hass.async_add_executor_job(get_connection) + try: + connection = await hass.async_add_executor_job(get_connection) + except Timeout as ex: + raise ConfigEntryNotReady from ex # Set up router and store reference to it router = Router(connection, url, mac, signal_update) diff --git a/homeassistant/components/huawei_lte/config_flow.py b/homeassistant/components/huawei_lte/config_flow.py index 52d586d088a..992dc33a697 100644 --- a/homeassistant/components/huawei_lte/config_flow.py +++ b/homeassistant/components/huawei_lte/config_flow.py @@ -14,13 +14,14 @@ from huawei_lte_api.exceptions import ( LoginErrorUsernamePasswordOverrunException, ResponseErrorException, ) +from requests.exceptions import Timeout from url_normalize import url_normalize import voluptuous as vol from homeassistant import config_entries from homeassistant.const import CONF_PASSWORD, CONF_RECIPIENT, CONF_URL, CONF_USERNAME from homeassistant.core import callback -from .const import DEFAULT_DEVICE_NAME +from .const import CONNECTION_TIMEOUT, DEFAULT_DEVICE_NAME # https://github.com/PyCQA/pylint/issues/3202 from .const import DOMAIN # pylint: disable=unused-import @@ -115,12 +116,18 @@ class ConfigFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): """Try connecting with given credentials.""" if username or password: conn = AuthorizedConnection( - user_input[CONF_URL], username=username, password=password + user_input[CONF_URL], + username=username, + password=password, + timeout=CONNECTION_TIMEOUT, ) else: try: conn = AuthorizedConnection( - user_input[CONF_URL], username="", password="" + user_input[CONF_URL], + username="", + password="", + timeout=CONNECTION_TIMEOUT, ) user_input[CONF_USERNAME] = "" user_input[CONF_PASSWORD] = "" @@ -129,7 +136,7 @@ class ConfigFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): "Could not login with empty credentials, proceeding unauthenticated", exc_info=True, ) - conn = Connection(user_input[CONF_URL]) + conn = Connection(user_input[CONF_URL], timeout=CONNECTION_TIMEOUT) del user_input[CONF_USERNAME] del user_input[CONF_PASSWORD] return conn @@ -170,6 +177,9 @@ class ConfigFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): except ResponseErrorException: _LOGGER.warning("Response error", exc_info=True) errors["base"] = "response_error" + except Timeout: + _LOGGER.warning("Connection timeout", exc_info=True) + errors[CONF_URL] = "connection_timeout" except Exception: # pylint: disable=broad-except _LOGGER.warning("Unknown error connecting to device", exc_info=True) errors[CONF_URL] = "unknown_connection_error" diff --git a/homeassistant/components/huawei_lte/const.py b/homeassistant/components/huawei_lte/const.py index 3d99261e6ed..8dae63f6538 100644 --- a/homeassistant/components/huawei_lte/const.py +++ b/homeassistant/components/huawei_lte/const.py @@ -10,6 +10,8 @@ UPDATE_OPTIONS_SIGNAL = f"{DOMAIN}_options_update" UNIT_BYTES = "B" UNIT_SECONDS = "s" +CONNECTION_TIMEOUT = 10 + KEY_DEVICE_BASIC_INFORMATION = "device_basic_information" KEY_DEVICE_INFORMATION = "device_information" KEY_DEVICE_SIGNAL = "device_signal" diff --git a/homeassistant/components/huawei_lte/strings.json b/homeassistant/components/huawei_lte/strings.json index 8681e3355a4..2e76cf1b343 100644 --- a/homeassistant/components/huawei_lte/strings.json +++ b/homeassistant/components/huawei_lte/strings.json @@ -11,6 +11,7 @@ "invalid_url": "Invalid URL", "login_attempts_exceeded": "Maximum login attempts exceeded, please try again later", "response_error": "Unknown error from device", + "connection_timeout": "Connection timeout", "unknown_connection_error": "Unknown error connecting to device" }, "step": {