diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 3cecb157d07..a04e815af7f 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -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 . diff --git a/homeassistant/components/syncthru/__init__.py b/homeassistant/components/syncthru/__init__.py index c422bfa6f33..ef3e8c4419d 100644 --- a/homeassistant/components/syncthru/__init__.py +++ b/homeassistant/components/syncthru/__init__.py @@ -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( diff --git a/homeassistant/components/syncthru/config_flow.py b/homeassistant/components/syncthru/config_flow.py index 31bf8c97edc..db822f650dc 100644 --- a/homeassistant/components/syncthru/config_flow.py +++ b/homeassistant/components/syncthru/config_flow.py @@ -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(): diff --git a/homeassistant/components/syncthru/manifest.json b/homeassistant/components/syncthru/manifest.json index 9fd3c2afe06..37b7ed311cb 100644 --- a/homeassistant/components/syncthru/manifest.json +++ b/homeassistant/components/syncthru/manifest.json @@ -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", diff --git a/requirements_all.txt b/requirements_all.txt index 6b396e0609f..1fbc0b445e6 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -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 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 7f5cd0a7a37..62b4ac0cbef 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -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 diff --git a/tests/components/syncthru/test_config_flow.py b/tests/components/syncthru/test_config_flow.py index 70e8a80ad0f..61bc2992f52 100644 --- a/tests/components/syncthru/test_config_flow.py +++ b/tests/components/syncthru/test_config_flow.py @@ -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},