diff --git a/homeassistant/components/opower/coordinator.py b/homeassistant/components/opower/coordinator.py index 629dce0823c..36e23c4098e 100644 --- a/homeassistant/components/opower/coordinator.py +++ b/homeassistant/components/opower/coordinator.py @@ -5,9 +5,11 @@ import logging from types import MappingProxyType from typing import Any, cast +import aiohttp from opower import ( Account, AggregateType, + CannotConnect, CostRead, Forecast, InvalidAuth, @@ -27,7 +29,7 @@ from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, UnitOfEnergy, Unit from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers import aiohttp_client -from homeassistant.helpers.update_coordinator import DataUpdateCoordinator +from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.util import dt as dt_util from .const import CONF_TOTP_SECRET, CONF_UTILITY, DOMAIN @@ -80,8 +82,16 @@ class OpowerCoordinator(DataUpdateCoordinator[dict[str, Forecast]]): # assume previous session has expired and re-login. await self.api.async_login() except InvalidAuth as err: + _LOGGER.error("Error during login: %s", err) raise ConfigEntryAuthFailed from err - forecasts: list[Forecast] = await self.api.async_get_forecast() + except CannotConnect as err: + _LOGGER.error("Error during login: %s", err) + raise UpdateFailed(f"Error during login: {err}") from err + try: + forecasts: list[Forecast] = await self.api.async_get_forecast() + except aiohttp.ClientError as err: + _LOGGER.error("Error getting forecasts: %s", err) + raise _LOGGER.debug("Updating sensor data with: %s", forecasts) # Because Opower provides historical usage/cost with a delay of a couple of days # we need to insert data into statistics. @@ -90,7 +100,12 @@ class OpowerCoordinator(DataUpdateCoordinator[dict[str, Forecast]]): async def _insert_statistics(self) -> None: """Insert Opower statistics.""" - for account in await self.api.async_get_accounts(): + try: + accounts = await self.api.async_get_accounts() + except aiohttp.ClientError as err: + _LOGGER.error("Error getting forecasts: %s", err) + raise + for account in accounts: id_prefix = "_".join( ( self.api.utility.subdomain(), @@ -252,9 +267,13 @@ class OpowerCoordinator(DataUpdateCoordinator[dict[str, Forecast]]): start = datetime.fromtimestamp(start_time, tz=tz) - timedelta(days=30) end = dt_util.now(tz) _LOGGER.debug("Getting monthly cost reads: %s - %s", start, end) - cost_reads = await self.api.async_get_cost_reads( - account, AggregateType.BILL, start, end - ) + try: + cost_reads = await self.api.async_get_cost_reads( + account, AggregateType.BILL, start, end + ) + except aiohttp.ClientError as err: + _LOGGER.error("Error getting monthly cost reads: %s", err) + raise _LOGGER.debug("Got %s monthly cost reads", len(cost_reads)) if account.read_resolution == ReadResolution.BILLING: return cost_reads @@ -267,9 +286,13 @@ class OpowerCoordinator(DataUpdateCoordinator[dict[str, Forecast]]): assert start start = max(start, end - timedelta(days=3 * 365)) _LOGGER.debug("Getting daily cost reads: %s - %s", start, end) - daily_cost_reads = await self.api.async_get_cost_reads( - account, AggregateType.DAY, start, end - ) + try: + daily_cost_reads = await self.api.async_get_cost_reads( + account, AggregateType.DAY, start, end + ) + except aiohttp.ClientError as err: + _LOGGER.error("Error getting daily cost reads: %s", err) + raise _LOGGER.debug("Got %s daily cost reads", len(daily_cost_reads)) _update_with_finer_cost_reads(cost_reads, daily_cost_reads) if account.read_resolution == ReadResolution.DAY: @@ -281,9 +304,13 @@ class OpowerCoordinator(DataUpdateCoordinator[dict[str, Forecast]]): assert start start = max(start, end - timedelta(days=2 * 30)) _LOGGER.debug("Getting hourly cost reads: %s - %s", start, end) - hourly_cost_reads = await self.api.async_get_cost_reads( - account, AggregateType.HOUR, start, end - ) + try: + hourly_cost_reads = await self.api.async_get_cost_reads( + account, AggregateType.HOUR, start, end + ) + except aiohttp.ClientError as err: + _LOGGER.error("Error getting hourly cost reads: %s", err) + raise _LOGGER.debug("Got %s hourly cost reads", len(hourly_cost_reads)) _update_with_finer_cost_reads(cost_reads, hourly_cost_reads) _LOGGER.debug("Got %s cost reads", len(cost_reads))