From f3e04ee733b177d3a437ff28fab34cfcb80fff67 Mon Sep 17 00:00:00 2001 From: Elad Bar Date: Sun, 16 Jun 2024 14:52:25 +0300 Subject: [PATCH] update interval is being set by the minimum update interval of endpoints --- custom_components/hpprinter/__init__.py | 6 +- .../hpprinter/managers/ha_config_manager.py | 69 ++++++++++++++++--- .../hpprinter/managers/ha_coordinator.py | 3 +- .../hpprinter/managers/rest_api.py | 33 +-------- 4 files changed, 63 insertions(+), 48 deletions(-) diff --git a/custom_components/hpprinter/__init__.py b/custom_components/hpprinter/__init__.py index e8f66e4..64533ea 100644 --- a/custom_components/hpprinter/__init__.py +++ b/custom_components/hpprinter/__init__.py @@ -2,7 +2,7 @@ import sys from homeassistant.config_entries import ConfigEntry -from homeassistant.const import EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP +from homeassistant.const import EVENT_HOMEASSISTANT_START from homeassistant.core import HomeAssistant from .common.consts import DEFAULT_NAME, DOMAIN @@ -41,10 +41,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: EVENT_HOMEASSISTANT_START, coordinator.on_home_assistant_start ) - hass.bus.async_listen_once( - EVENT_HOMEASSISTANT_STOP, coordinator.on_home_assistant_stop - ) - _LOGGER.info("Finished loading integration") initialized = is_initialized diff --git a/custom_components/hpprinter/managers/ha_config_manager.py b/custom_components/hpprinter/managers/ha_config_manager.py index 58d5809..2498065 100644 --- a/custom_components/hpprinter/managers/ha_config_manager.py +++ b/custom_components/hpprinter/managers/ha_config_manager.py @@ -1,3 +1,4 @@ +from datetime import timedelta import json import logging import os @@ -13,7 +14,14 @@ from homeassistant.helpers.json import JSONEncoder from homeassistant.helpers.storage import Store -from ..common.consts import CONFIGURATION_FILE, DEFAULT_ENTRY_ID, DEFAULT_NAME, DOMAIN +from ..common.consts import ( + CONFIGURATION_FILE, + DEFAULT_ENTRY_ID, + DEFAULT_INTERVAL, + DEFAULT_NAME, + DOMAIN, + DURATION_UNITS, +) from ..common.entity_descriptions import ( IntegrationBinarySensorEntityDescription, IntegrationEntityDescription, @@ -32,6 +40,13 @@ class HAConfigManager: _entry_title: str _config_data: ConfigData _store: Store | None + _update_intervals: dict[str, int] | None + _data_points: dict | None + _endpoints: list[str] | None + _exclude_uri_list: list[str] | None + _exclude_type_list: list[str] | None + _entity_descriptions: list[IntegrationEntityDescription] | None + _minimum_update_interval: timedelta def __init__(self, hass: HomeAssistant | None, entry: ConfigEntry | None): self._hass = hass @@ -39,15 +54,19 @@ def __init__(self, hass: HomeAssistant | None, entry: ConfigEntry | None): self._data = None self.platforms = [] - self._entity_descriptions: list[IntegrationEntityDescription] | None = None + self._entity_descriptions = None self._translations = None - self._endpoints: list[str] | None = None + self._endpoints = None + + self._default_update_interval = self._convert_to_seconds(DEFAULT_INTERVAL) - self._data_points: dict | None = None - self._exclude_uri_list: list[str] | None = None - self._exclude_type_list: list[str] | None = None + self._update_intervals = None + self._minimum_update_interval = timedelta(seconds=self._default_update_interval) + self._data_points = None + self._exclude_uri_list = None + self._exclude_type_list = None self._entry = entry self._entry_id = DEFAULT_ENTRY_ID if entry is None else entry.entry_id @@ -81,6 +100,10 @@ def entry_title(self) -> str: return entry_title + @property + def minimum_update_interval(self) -> timedelta: + return self._minimum_update_interval + @property def entry(self) -> ConfigEntry: entry = self._entry @@ -358,20 +381,27 @@ def _is_valid_entity( return is_valid async def _load_data_points_configuration(self): - self._endpoints = [] - + self._update_intervals = {} self._data_points = await self._get_parameters(ParameterType.DATA_POINTS) endpoint_objects = self._data_points for endpoint in endpoint_objects: endpoint_uri = endpoint.get("endpoint") + interval = endpoint.get("interval", DEFAULT_INTERVAL) if ( - endpoint_uri not in self._endpoints + endpoint_uri not in self._update_intervals and endpoint_uri not in self._exclude_uri_list ): - self._endpoints.append(endpoint_uri) + self._update_intervals[endpoint_uri] = self._convert_to_seconds( + interval + ) + + minimum_update_interval = min(self._update_intervals.values()) + self._minimum_update_interval = timedelta(seconds=minimum_update_interval) + + self._endpoints = list(self._update_intervals.keys()) async def _load_exclude_endpoints_configuration(self): endpoints = await self._get_parameters(ParameterType.ENDPOINT_VALIDATIONS) @@ -379,6 +409,13 @@ async def _load_exclude_endpoints_configuration(self): self._exclude_uri_list = endpoints.get("exclude_uri") self._exclude_type_list = endpoints.get("exclude_type") + def get_update_interval(self, endpoint: str) -> int: + update_interval = self._update_intervals.get( + endpoint, self._default_update_interval + ) + + return update_interval + @staticmethod async def _get_parameters(parameter_type: ParameterType) -> dict: config_file = f"{parameter_type}.json" @@ -394,6 +431,18 @@ async def _get_parameters(parameter_type: ParameterType) -> dict: return data + @staticmethod + def _convert_to_seconds(duration: str | None) -> int: + if duration is None: + duration = DEFAULT_INTERVAL + + count = int(duration[:-1]) + unit = DURATION_UNITS[duration[-1]] + td = timedelta(**{unit: count}) + seconds = td.seconds + 60 * 60 * 24 * td.days + + return seconds + def is_valid_endpoint(self, endpoint: dict): endpoint_type = endpoint.get("type") uri = endpoint.get("uri") diff --git a/custom_components/hpprinter/managers/ha_coordinator.py b/custom_components/hpprinter/managers/ha_coordinator.py index e28e724..baf0589 100644 --- a/custom_components/hpprinter/managers/ha_coordinator.py +++ b/custom_components/hpprinter/managers/ha_coordinator.py @@ -15,7 +15,6 @@ PRINTER_MAIN_DEVICE, SIGNAL_HA_DEVICE_CREATED, SIGNAL_HA_DEVICE_DISCOVERED, - UPDATE_API_INTERVAL, ) from .ha_config_manager import HAConfigManager from .rest_api import RestAPIv2 @@ -36,7 +35,7 @@ def __init__( hass, _LOGGER, name=config_manager.entry_title, - update_interval=UPDATE_API_INTERVAL, + update_interval=config_manager.minimum_update_interval, update_method=self._async_update_data, ) diff --git a/custom_components/hpprinter/managers/rest_api.py b/custom_components/hpprinter/managers/rest_api.py index b41b333..b86f3ce 100644 --- a/custom_components/hpprinter/managers/rest_api.py +++ b/custom_components/hpprinter/managers/rest_api.py @@ -1,4 +1,4 @@ -from datetime import datetime, timedelta +from datetime import datetime import json import logging import sys @@ -20,8 +20,6 @@ from homeassistant.util.ssl import SSLCipherList from ..common.consts import ( - DEFAULT_INTERVAL, - DURATION_UNITS, IGNORED_KEYS, PRODUCT_STATUS_ENDPOINT, PRODUCT_STATUS_OFFLINE_PAYLOAD, @@ -45,7 +43,6 @@ def __init__(self, hass, config_manager: HAConfigManager): self._data: dict = {} self._data_config: dict = {} self._last_update: dict[str, float] = {} - self._update_intervals: dict[str, int] = {} self._raw_data: dict = {} @@ -95,7 +92,6 @@ async def initialize(self, throw_exception: bool = False): else: self._session = async_create_clientsession(hass=self._hass) - self._load_update_intervals() await self._load_metadata() except Exception as ex: @@ -188,15 +184,9 @@ async def _update_data( self._last_update.get(endpoint, 0) if connectivity_check else 0 ) last_update_diff = int(now_ts - last_update) - interval = self._update_intervals.get(endpoint, 0) + interval = self._config_manager.get_update_interval(endpoint) if interval > last_update_diff: - _LOGGER.debug( - f"Skip updating '{endpoint}', " - f"it's too soon, " - f"interval: {interval}s, " - f"time since last update: {last_update_diff}s" - ) continue resource_data = await self._get_request(endpoint) @@ -328,13 +318,6 @@ def _get_data_section(data: dict, path: str) -> dict: return result - def _load_update_intervals(self): - for data_point in self._config_manager.data_points: - endpoint = data_point.get("endpoint") - interval = data_point.get("interval", DEFAULT_INTERVAL) - - self._update_intervals[endpoint] = self._convert_to_seconds(interval) - def _get_devices_data(self): devices = [] @@ -514,15 +497,3 @@ def device_data_changed(self, device_key: str): device_data, device_config, ) - - @staticmethod - def _convert_to_seconds(duration: str | None) -> int: - if duration is None: - duration = DEFAULT_INTERVAL - - count = int(duration[:-1]) - unit = DURATION_UNITS[duration[-1]] - td = timedelta(**{unit: count}) - seconds = td.seconds + 60 * 60 * 24 * td.days - - return seconds