Correctly handle offline and unsupported printers during setup (#55894)

This commit is contained in:
Niels Mündler 2021-09-30 16:29:51 +02:00 committed by GitHub
parent 8196a84538
commit 3a56e3a823
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 31 additions and 17 deletions

View File

@ -580,7 +580,7 @@ jobs:
python -m venv venv
. venv/bin/activate
pip install -U "pip<20.3" "setuptools<58" wheel
pip install -U "pip<20.3" setuptools wheel
pip install -r requirements_all.txt
pip install -r requirements_test.txt
pip install -e .

View File

@ -5,14 +5,13 @@ from datetime import timedelta
import logging
import async_timeout
from pysyncthru import SyncThru
from pysyncthru import ConnectionMode, SyncThru, SyncThruAPINotSupported
from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_URL
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import aiohttp_client, device_registry as dr
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
@ -28,22 +27,29 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
session = aiohttp_client.async_get_clientsession(hass)
hass.data.setdefault(DOMAIN, {})
printer = SyncThru(entry.data[CONF_URL], session)
printer = SyncThru(
entry.data[CONF_URL], session, connection_mode=ConnectionMode.API
)
async def async_update_data() -> SyncThru:
"""Fetch data from the printer."""
try:
async with async_timeout.timeout(10):
await printer.update()
except ValueError as value_error:
except SyncThruAPINotSupported as api_error:
# if an exception is thrown, printer does not support syncthru
raise UpdateFailed(
f"Configured printer at {printer.url} does not respond. "
"Please make sure it supports SyncThru and check your configuration."
) from value_error
_LOGGER.info(
"Configured printer at %s does not provide SyncThru JSON API",
printer.url,
exc_info=api_error,
)
raise api_error
else:
# if the printer is offline, we raise an UpdateFailed
if printer.is_unknown_state():
raise ConfigEntryNotReady
raise UpdateFailed(
f"Configured printer at {printer.url} does not respond."
)
return printer
coordinator: DataUpdateCoordinator = DataUpdateCoordinator(
@ -55,6 +61,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
)
hass.data[DOMAIN][entry.entry_id] = coordinator
await coordinator.async_config_entry_first_refresh()
if isinstance(coordinator.last_exception, SyncThruAPINotSupported):
# this means that the printer does not support the syncthru JSON API
# and the config should simply be discarded
return False
device_registry = await dr.async_get_registry(hass)
device_registry.async_get_or_create(

View File

@ -3,7 +3,7 @@
import re
from urllib.parse import urlparse
from pysyncthru import SyncThru
from pysyncthru import ConnectionMode, SyncThru, SyncThruAPINotSupported
from url_normalize import url_normalize
import voluptuous as vol
@ -109,7 +109,9 @@ class SyncThruConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
break
session = aiohttp_client.async_get_clientsession(self.hass)
printer = SyncThru(user_input[CONF_URL], session)
printer = SyncThru(
user_input[CONF_URL], session, connection_mode=ConnectionMode.API
)
errors = {}
try:
await printer.update()
@ -117,7 +119,7 @@ class SyncThruConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
user_input[CONF_NAME] = DEFAULT_NAME_TEMPLATE.format(
printer.model() or DEFAULT_MODEL
)
except ValueError:
except SyncThruAPINotSupported:
errors[CONF_URL] = "syncthru_not_supported"
else:
if printer.is_unknown_state():

View File

@ -3,7 +3,7 @@
"name": "Samsung SyncThru Printer",
"documentation": "https://www.home-assistant.io/integrations/syncthru",
"config_flow": true,
"requirements": ["pysyncthru==0.7.3", "url-normalize==1.4.1"],
"requirements": ["pysyncthru==0.7.10", "url-normalize==1.4.1"],
"ssdp": [
{
"deviceType": "urn:schemas-upnp-org:device:Printer:1",

View File

@ -1835,7 +1835,7 @@ pystiebeleltron==0.0.1.dev2
pysuez==0.1.19
# homeassistant.components.syncthru
pysyncthru==0.7.3
pysyncthru==0.7.10
# homeassistant.components.tankerkoenig
pytankerkoenig==0.0.6

View File

@ -1082,7 +1082,7 @@ pyspcwebgw==0.4.0
pysqueezebox==0.5.5
# homeassistant.components.syncthru
pysyncthru==0.7.3
pysyncthru==0.7.10
# homeassistant.components.ecobee
python-ecobee-api==0.2.11

View File

@ -3,6 +3,8 @@
import re
from unittest.mock import patch
from pysyncthru import SyncThruAPINotSupported
from homeassistant import config_entries, data_entry_flow, setup
from homeassistant.components import ssdp
from homeassistant.components.syncthru.config_flow import SyncThru
@ -71,7 +73,7 @@ async def test_already_configured_by_url(hass, aioclient_mock):
async def test_syncthru_not_supported(hass):
"""Test we show user form on unsupported device."""
with patch.object(SyncThru, "update", side_effect=ValueError):
with patch.object(SyncThru, "update", side_effect=SyncThruAPINotSupported):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_USER},