From e9c9e0338b38dd4e0d57eb20f0ddc8af441b11b7 Mon Sep 17 00:00:00 2001 From: Erik Kastelec Date: Sun, 7 May 2023 17:26:28 +0200 Subject: [PATCH] Increase time between retries #68 & add logging #66 --- custom_components/wemportal/__init__.py | 2 ++ custom_components/wemportal/coordinator.py | 25 ++++++++++++++++----- custom_components/wemportal/manifest.json | 2 +- custom_components/wemportal/number.py | 4 ++++ custom_components/wemportal/select.py | 4 ++++ custom_components/wemportal/sensor.py | 4 ++++ custom_components/wemportal/switch.py | 4 ++++ custom_components/wemportal/wemportalapi.py | 11 +++++++-- 8 files changed, 47 insertions(+), 9 deletions(-) diff --git a/custom_components/wemportal/__init__.py b/custom_components/wemportal/__init__.py index 6e29e95..a4293f3 100644 --- a/custom_components/wemportal/__init__.py +++ b/custom_components/wemportal/__init__.py @@ -50,6 +50,8 @@ async def migrate_unique_ids( change = False for unique_id, values in data.items(): + if isinstance(values, int): + continue name_id = er.async_get_entity_id(values["platform"], DOMAIN, unique_id) new_id = get_wemportal_unique_id(config_entry.entry_id, device_id, unique_id) if name_id is not None: diff --git a/custom_components/wemportal/coordinator.py b/custom_components/wemportal/coordinator.py index 572db90..3bd6846 100644 --- a/custom_components/wemportal/coordinator.py +++ b/custom_components/wemportal/coordinator.py @@ -1,5 +1,6 @@ """ WemPortal integration coordinator """ from __future__ import annotations +from time import monotonic import async_timeout from homeassistant.config_entries import ConfigEntry @@ -9,7 +10,7 @@ UpdateFailed, ) from .exceptions import ForbiddenError, ServerError, WemPortalError -from .const import _LOGGER, DEFAULT_TIMEOUT +from .const import _LOGGER, DEFAULT_CONF_SCAN_INTERVAL_API_VALUE, DEFAULT_TIMEOUT from homeassistant.const import CONF_PASSWORD, CONF_USERNAME from .wemportalapi import WemPortalApi @@ -34,15 +35,22 @@ def __init__( self.api = api self.hass = hass self.config_entry = config_entry + self.last_try = None + self.num_failed = 0 async def _async_update_data(self): """Fetch data from the wemportal api""" + if self.num_failed > 2 and monotonic() - self.last_try < DEFAULT_CONF_SCAN_INTERVAL_API_VALUE: + raise UpdateFailed("Waiting for more time to pass before retrying") async with async_timeout.timeout(DEFAULT_TIMEOUT): try: - return await self.hass.async_add_executor_job(self.api.fetch_data) + x = await self.hass.async_add_executor_job(self.api.fetch_data) + self.num_failed = 0 + return x except WemPortalError as exc: + self.num_failed += 1 # if isinstance(exc.__cause__, (ServerError, ForbiddenError)): - _LOGGER.error("Creating new wemportal api instance") + _LOGGER.warning("Creating new wemportal api instance", exc_info=exc) # TODO: This is a temporary solution and should be removed when api cause from #28 is resolved try: new_api = WemPortalApi( @@ -53,14 +61,17 @@ async def _async_update_data(self): self.api = new_api except Exception as exc2: raise UpdateFailed from exc2 - if isinstance(exc.__cause__, (ServerError, ForbiddenError)): + if isinstance(exc.__cause__, (ServerError, ForbiddenError)) and self.num_failed <= 1: try: - return await self.hass.async_add_executor_job( + x = await self.hass.async_add_executor_job( self.api.fetch_data ) + self.num_failed = 0 + return x except WemPortalError as exc2: + self.num_failed += 1 _LOGGER.error( - "Error fetching data from wemportal", exc_info=exc + "Error fetching data from wemportal", exc_info=exc2 ) raise UpdateFailed from exc2 else: @@ -68,3 +79,5 @@ async def _async_update_data(self): # else: # _LOGGER.error("Error fetching data from wemportal", exc_info=exc) # raise UpdateFailed from exc + finally: + self.last_try = monotonic() diff --git a/custom_components/wemportal/manifest.json b/custom_components/wemportal/manifest.json index dd4aa23..91d5616 100644 --- a/custom_components/wemportal/manifest.json +++ b/custom_components/wemportal/manifest.json @@ -4,7 +4,7 @@ "documentation": "https://github.com/erikkastelec/hass-WEM-Portal", "issue_tracker": "https://github.com/erikkastelec/hass-WEM-Portal/issues", "dependencies": [], - "version": "1.5.2", + "version": "1.5.3", "codeowners": [ "@erikkastelec" ], diff --git a/custom_components/wemportal/number.py b/custom_components/wemportal/number.py index 8674fe6..49adabe 100644 --- a/custom_components/wemportal/number.py +++ b/custom_components/wemportal/number.py @@ -25,6 +25,8 @@ async def async_setup_platform( entities: list[WemPortalNumber] = [] for device_id, entity_data in coordinator.data.items(): for unique_id, values in entity_data.items(): + if isinstance(values, int): + continue if values["platform"] == "number": entities.append( WemPortalNumber( @@ -46,6 +48,8 @@ async def async_setup_entry( entities: list[WemPortalNumber] = [] for device_id, entity_data in coordinator.data.items(): for unique_id, values in entity_data.items(): + if isinstance(values, int): + continue if values["platform"] == "number": entities.append( WemPortalNumber( diff --git a/custom_components/wemportal/select.py b/custom_components/wemportal/select.py index 74f1d5c..6dd3c0d 100644 --- a/custom_components/wemportal/select.py +++ b/custom_components/wemportal/select.py @@ -26,6 +26,8 @@ async def async_setup_platform( entities: list[WemPortalSelect] = [] for device_id, entity_data in coordinator.data.items(): for unique_id, values in entity_data.items(): + if isinstance(values, int): + continue if values["platform"] == "select": entities.append( WemPortalSelect( @@ -47,6 +49,8 @@ async def async_setup_entry( entities: list[WemPortalSelect] = [] for device_id, entity_data in coordinator.data.items(): for unique_id, values in entity_data.items(): + if isinstance(values, int): + continue if values["platform"] == "select": entities.append( WemPortalSelect( diff --git a/custom_components/wemportal/sensor.py b/custom_components/wemportal/sensor.py index e06bb84..8aaa2dc 100644 --- a/custom_components/wemportal/sensor.py +++ b/custom_components/wemportal/sensor.py @@ -30,6 +30,8 @@ async def async_setup_platform( entities: list[WemPortalSensor] = [] for device_id, entity_data in coordinator.data.items(): for unique_id, values in entity_data.items(): + if isinstance(values, int): + continue if values["platform"] == "sensor": entities.append( WemPortalSensor( @@ -51,6 +53,8 @@ async def async_setup_entry( entities: list[WemPortalSensor] = [] for device_id, entity_data in coordinator.data.items(): for unique_id, values in entity_data.items(): + if isinstance(values, int): + continue if values["platform"] == "sensor": entities.append( WemPortalSensor( diff --git a/custom_components/wemportal/switch.py b/custom_components/wemportal/switch.py index c36f97b..a7547a5 100644 --- a/custom_components/wemportal/switch.py +++ b/custom_components/wemportal/switch.py @@ -25,6 +25,8 @@ async def async_setup_platform( entities: list[WemPortalSwitch] = [] for device_id, entity_data in coordinator.data.items(): for unique_id, values in entity_data.items(): + if isinstance(values, int): + continue if values["platform"] == "switch": entities.append( WemPortalSwitch( @@ -46,6 +48,8 @@ async def async_setup_entry( entities: list[WemPortalSwitch] = [] for device_id, entity_data in coordinator.data.items(): for unique_id, values in entity_data.items(): + if isinstance(values, int): + continue if values["platform"] == "switch": entities.append( WemPortalSwitch( diff --git a/custom_components/wemportal/wemportalapi.py b/custom_components/wemportal/wemportalapi.py index ce5170c..7560142 100644 --- a/custom_components/wemportal/wemportalapi.py +++ b/custom_components/wemportal/wemportalapi.py @@ -279,10 +279,17 @@ def get_devices(self): "Type": module["Type"], "Name": module["Name"], } + self.data[device["ID"]]["ConnectionStatus"] = device["ConnectionStatus"] + + # TODO: remove when we implement multiple device support + break def get_parameters(self): for device_id in self.data.keys(): - _LOGGER.debug("Fetching api parameters data") + if self.data[device_id]["ConnectionStatus"] != 0: + continue + _LOGGER.debug("Fetching api parameters data for device %s", device_id) + _LOGGER.debug(self.data) delete_candidates = [] for key, values in self.modules[device_id].items(): data = { @@ -293,7 +300,7 @@ def get_parameters(self): response = self.make_api_call( "https://www.wemportal.com/app/EventType/Read", data=data ) - + _LOGGER.debug(response.json()) parameters = {} try: for parameter in response.json()["Parameters"]: