From 540d6e9fa5f5eed5a34caed01d08b6dabda9d333 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Klomp?= Date: Mon, 28 Jun 2021 16:59:17 +0200 Subject: [PATCH] Use pysma exceptions (#52252) --- homeassistant/components/sma/__init__.py | 24 ++++++++++++++------ homeassistant/components/sma/config_flow.py | 25 +++++---------------- homeassistant/components/sma/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/sma/test_config_flow.py | 12 ++++++---- 6 files changed, 34 insertions(+), 33 deletions(-) diff --git a/homeassistant/components/sma/__init__.py b/homeassistant/components/sma/__init__.py index 5db3039af40..0df3ef8cb7c 100644 --- a/homeassistant/components/sma/__init__.py +++ b/homeassistant/components/sma/__init__.py @@ -142,10 +142,16 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: session = async_get_clientsession(hass, verify_ssl=verify_ssl) sma = pysma.SMA(session, url, password, group) - # Get updated device info - device_info = await sma.device_info() - # Get all device sensors - sensor_def = await sma.get_sensors() + try: + # Get updated device info + device_info = await sma.device_info() + # Get all device sensors + sensor_def = await sma.get_sensors() + except ( + pysma.exceptions.SmaReadException, + pysma.exceptions.SmaConnectionException, + ) as exc: + raise ConfigEntryNotReady from exc # Parse legacy options if initial setup was done from yaml if entry.source == SOURCE_IMPORT: @@ -155,9 +161,13 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: # Define the coordinator async def async_update_data(): """Update the used SMA sensors.""" - values = await sma.read(sensor_def) - if not values: - raise UpdateFailed + try: + await sma.read(sensor_def) + except ( + pysma.exceptions.SmaReadException, + pysma.exceptions.SmaConnectionException, + ) as exc: + raise UpdateFailed from exc interval = timedelta( seconds=entry.options.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL) diff --git a/homeassistant/components/sma/config_flow.py b/homeassistant/components/sma/config_flow.py index 66d875562ab..b95e4e4fe06 100644 --- a/homeassistant/components/sma/config_flow.py +++ b/homeassistant/components/sma/config_flow.py @@ -4,11 +4,10 @@ from __future__ import annotations import logging from typing import Any -import aiohttp import pysma import voluptuous as vol -from homeassistant import config_entries, core, exceptions +from homeassistant import config_entries, core from homeassistant.const import ( CONF_HOST, CONF_PASSWORD, @@ -36,15 +35,11 @@ async def validate_input( sma = pysma.SMA(session, url, data[CONF_PASSWORD], group=data[CONF_GROUP]) - if await sma.new_session() is False: - raise InvalidAuth - + # new_session raises SmaAuthenticationException on failure + await sma.new_session() device_info = await sma.device_info() await sma.close_session() - if not device_info: - raise CannotRetrieveDeviceInfo - return device_info @@ -79,11 +74,11 @@ class SmaConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): try: device_info = await validate_input(self.hass, user_input) - except aiohttp.ClientError: + except pysma.exceptions.SmaConnectionException: errors["base"] = "cannot_connect" - except InvalidAuth: + except pysma.exceptions.SmaAuthenticationException: errors["base"] = "invalid_auth" - except CannotRetrieveDeviceInfo: + except pysma.exceptions.SmaReadException: errors["base"] = "cannot_retrieve_device_info" except Exception: # pylint: disable=broad-except _LOGGER.exception("Unexpected exception") @@ -128,11 +123,3 @@ class SmaConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): return self.async_create_entry( title=import_config[CONF_HOST], data=import_config ) - - -class InvalidAuth(exceptions.HomeAssistantError): - """Error to indicate there is invalid auth.""" - - -class CannotRetrieveDeviceInfo(exceptions.HomeAssistantError): - """Error to indicate we cannot retrieve the device information.""" diff --git a/homeassistant/components/sma/manifest.json b/homeassistant/components/sma/manifest.json index 66b845ac39f..721431b89a7 100644 --- a/homeassistant/components/sma/manifest.json +++ b/homeassistant/components/sma/manifest.json @@ -3,7 +3,7 @@ "name": "SMA Solar", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/sma", - "requirements": ["pysma==0.5.0"], + "requirements": ["pysma==0.6.0"], "codeowners": ["@kellerza", "@rklomp"], "iot_class": "local_polling" } diff --git a/requirements_all.txt b/requirements_all.txt index 74df44077ce..ee617b75b74 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1747,7 +1747,7 @@ pysignalclirestapi==0.3.4 pyskyqhub==0.1.3 # homeassistant.components.sma -pysma==0.5.0 +pysma==0.6.0 # homeassistant.components.smappee pysmappee==0.2.25 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index e1fc86963eb..3a46d378017 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -989,7 +989,7 @@ pysiaalarm==3.0.0 pysignalclirestapi==0.3.4 # homeassistant.components.sma -pysma==0.5.0 +pysma==0.6.0 # homeassistant.components.smappee pysmappee==0.2.25 diff --git a/tests/components/sma/test_config_flow.py b/tests/components/sma/test_config_flow.py index dbcecbeb43c..f262f7eeba1 100644 --- a/tests/components/sma/test_config_flow.py +++ b/tests/components/sma/test_config_flow.py @@ -1,7 +1,11 @@ """Test the sma config flow.""" from unittest.mock import patch -import aiohttp +from pysma.exceptions import ( + SmaAuthenticationException, + SmaConnectionException, + SmaReadException, +) from homeassistant import setup from homeassistant.components.sma.const import DOMAIN @@ -54,7 +58,7 @@ async def test_form_cannot_connect(hass): ) with patch( - "pysma.SMA.new_session", side_effect=aiohttp.ClientError + "pysma.SMA.new_session", side_effect=SmaConnectionException ), _patch_async_setup_entry() as mock_setup_entry: result = await hass.config_entries.flow.async_configure( result["flow_id"], @@ -73,7 +77,7 @@ async def test_form_invalid_auth(hass): ) with patch( - "pysma.SMA.new_session", return_value=False + "pysma.SMA.new_session", side_effect=SmaAuthenticationException ), _patch_async_setup_entry() as mock_setup_entry: result = await hass.config_entries.flow.async_configure( result["flow_id"], @@ -92,7 +96,7 @@ async def test_form_cannot_retrieve_device_info(hass): ) with patch("pysma.SMA.new_session", return_value=True), patch( - "pysma.SMA.read", return_value=False + "pysma.SMA.read", side_effect=SmaReadException ), _patch_async_setup_entry() as mock_setup_entry: result = await hass.config_entries.flow.async_configure( result["flow_id"],