Handle failed connection attempts in opentherm_gw (#75961)
This commit is contained in:
parent
377f56ff5f
commit
abb7495ced
5 changed files with 32 additions and 8 deletions
|
@ -1,9 +1,11 @@
|
|||
"""Support for OpenTherm Gateway devices."""
|
||||
import asyncio
|
||||
from datetime import date, datetime
|
||||
import logging
|
||||
|
||||
import pyotgw
|
||||
import pyotgw.vars as gw_vars
|
||||
from serial import SerialException
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
||||
|
@ -23,6 +25,7 @@ from homeassistant.const import (
|
|||
Platform,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, ServiceCall
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
from homeassistant.helpers import config_validation as cv, device_registry as dr
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
@ -37,6 +40,7 @@ from .const import (
|
|||
CONF_PRECISION,
|
||||
CONF_READ_PRECISION,
|
||||
CONF_SET_PRECISION,
|
||||
CONNECTION_TIMEOUT,
|
||||
DATA_GATEWAYS,
|
||||
DATA_OPENTHERM_GW,
|
||||
DOMAIN,
|
||||
|
@ -107,8 +111,15 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
|
|||
|
||||
config_entry.add_update_listener(options_updated)
|
||||
|
||||
# Schedule directly on the loop to avoid blocking HA startup.
|
||||
hass.loop.create_task(gateway.connect_and_subscribe())
|
||||
try:
|
||||
await asyncio.wait_for(
|
||||
gateway.connect_and_subscribe(),
|
||||
timeout=CONNECTION_TIMEOUT,
|
||||
)
|
||||
except (asyncio.TimeoutError, ConnectionError, SerialException) as ex:
|
||||
raise ConfigEntryNotReady(
|
||||
f"Could not connect to gateway at {gateway.device_path}: {ex}"
|
||||
) from ex
|
||||
|
||||
await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS)
|
||||
|
||||
|
@ -428,6 +439,9 @@ class OpenThermGatewayDevice:
|
|||
async def connect_and_subscribe(self):
|
||||
"""Connect to serial device and subscribe report handler."""
|
||||
self.status = await self.gateway.connect(self.device_path)
|
||||
if not self.status:
|
||||
await self.cleanup()
|
||||
raise ConnectionError
|
||||
version_string = self.status[gw_vars.OTGW].get(gw_vars.OTGW_ABOUT)
|
||||
self.gw_version = version_string[18:] if version_string else None
|
||||
_LOGGER.debug(
|
||||
|
|
|
@ -26,6 +26,7 @@ from .const import (
|
|||
CONF_READ_PRECISION,
|
||||
CONF_SET_PRECISION,
|
||||
CONF_TEMPORARY_OVRD_MODE,
|
||||
CONNECTION_TIMEOUT,
|
||||
)
|
||||
|
||||
|
||||
|
@ -62,15 +63,21 @@ class OpenThermGwConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
otgw = pyotgw.OpenThermGateway()
|
||||
status = await otgw.connect(device)
|
||||
await otgw.disconnect()
|
||||
if not status:
|
||||
raise ConnectionError
|
||||
return status[gw_vars.OTGW].get(gw_vars.OTGW_ABOUT)
|
||||
|
||||
try:
|
||||
res = await asyncio.wait_for(test_connection(), timeout=10)
|
||||
except (asyncio.TimeoutError, SerialException):
|
||||
await asyncio.wait_for(
|
||||
test_connection(),
|
||||
timeout=CONNECTION_TIMEOUT,
|
||||
)
|
||||
except asyncio.TimeoutError:
|
||||
return self._show_form({"base": "timeout_connect"})
|
||||
except (ConnectionError, SerialException):
|
||||
return self._show_form({"base": "cannot_connect"})
|
||||
|
||||
if res:
|
||||
return self._create_entry(gw_id, name, device)
|
||||
return self._create_entry(gw_id, name, device)
|
||||
|
||||
return self._show_form()
|
||||
|
||||
|
|
|
@ -25,6 +25,8 @@ CONF_READ_PRECISION = "read_precision"
|
|||
CONF_SET_PRECISION = "set_precision"
|
||||
CONF_TEMPORARY_OVRD_MODE = "temporary_override_mode"
|
||||
|
||||
CONNECTION_TIMEOUT = 10
|
||||
|
||||
DATA_GATEWAYS = "gateways"
|
||||
DATA_OPENTHERM_GW = "opentherm_gw"
|
||||
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
"error": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
|
||||
"id_exists": "Gateway id already exists",
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
"timeout_connect": "[%key:common::config_flow::error::timeout_connect%]"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
|
|
|
@ -164,7 +164,7 @@ async def test_form_connection_timeout(hass):
|
|||
)
|
||||
|
||||
assert result2["type"] == "form"
|
||||
assert result2["errors"] == {"base": "cannot_connect"}
|
||||
assert result2["errors"] == {"base": "timeout_connect"}
|
||||
assert len(mock_connect.mock_calls) == 1
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue