From cfccf3adc093a58d289aedc877870b3c346be089 Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Mon, 30 Mar 2026 16:10:34 +0200 Subject: [PATCH 1/4] electricity pricing: fix update required, energycharts --- packages/control/optional.py | 12 ++++++------ packages/modules/common/store/_tariff.py | 10 ++++++---- .../flexible_tariffs/energycharts/tariff.py | 16 +++------------- 3 files changed, 15 insertions(+), 23 deletions(-) diff --git a/packages/control/optional.py b/packages/control/optional.py index b65b161751..0a331267df 100644 --- a/packages/control/optional.py +++ b/packages/control/optional.py @@ -76,8 +76,8 @@ def _reset_state(self, module: Union[FlexibleTariff, GridFee]): module.get.fault_str = NO_ERROR Pub().pub(f"openWB/set/optional/ep/{module.name}/get/fault_state", 0) Pub().pub(f"openWB/set/optional/ep/{module.name}/get/fault_str", NO_ERROR) - Pub().pub(f"openWB/set/optional/ep/{module.name}/get/prices", {}) - Pub().pub(f"openWB/set/optional/ep/{module.name}/get/next_query_time", None) + Pub().pub(f"openWB/set/optional/ep/{module.name}/get/prices", {}) + Pub().pub(f"openWB/set/optional/ep/{module.name}/get/next_query_time", None) Pub().pub("openWB/set/optional/ep/get/prices", {}) def monitoring_start(self): @@ -242,8 +242,6 @@ def ep_get_loading_hours(self, duration: float, remaining_time: float) -> List[i return [] def _is_et_price_update_required_for_module(self, module: Union[FlexibleTariff, GridFee]) -> bool: - if module is None: - return False if module.get.next_query_time is None: return True now = timecheck.create_timestamp() @@ -261,8 +259,10 @@ def et_price_update_required(self) -> bool: return False if len(self.data.electricity_pricing.get.prices) == 0: return True - return (self._is_et_price_update_required_for_module(self.data.electricity_pricing.flexible_tariff) or - self._is_et_price_update_required_for_module(self.data.electricity_pricing.grid_fee)) + return ((self._flexible_tariff_module and + self._is_et_price_update_required_for_module(self.data.electricity_pricing.flexible_tariff)) or + (self._grid_fee_module and + self._is_et_price_update_required_for_module(self.data.electricity_pricing.grid_fee))) def ocpp_transfer_meter_values(self): try: diff --git a/packages/modules/common/store/_tariff.py b/packages/modules/common/store/_tariff.py index 401f7965c5..4ec04a915d 100644 --- a/packages/modules/common/store/_tariff.py +++ b/packages/modules/common/store/_tariff.py @@ -71,7 +71,8 @@ def __reduce_prices(prices: Dict[str, float]) -> Dict[int, float]: return {int(float(k)): v for k, v in prices.items() if int(float(k)) >= first_timestamp} def __get_default_grid_fee_price(prices: Dict[str, float]) -> float: - if (hasattr(data.data.optional_data.grid_fee_module.config, "default_price") and + if (data.data.optional_data.grid_fee_module is not None and + hasattr(data.data.optional_data.grid_fee_module.config, "default_price") and data.data.optional_data.grid_fee_module.config.default_price is not None): log.debug("Using default grid fee price from configuration: " + f"{data.data.optional_data.grid_fee_module.config.default_price}") @@ -93,8 +94,9 @@ def __normalize_grid_fee_prices(grid_fee_prices: Dict[int, float], max_timestamp grid_fee_prices = __reduce_prices(grid_fee_prices) grid_fee_prices = {int(float(k)): v for k, v in grid_fee_prices.items() if int(float(k)) <= max_timestamp} - if (hasattr(data.data.optional_data.flexible_tariff_module.config, "includes_grid_fee") - and data.data.optional_data.flexible_tariff_module.config.includes_grid_fee is False): + if (data.data.optional_data.flexible_tariff_module is not None and + hasattr(data.data.optional_data.flexible_tariff_module.config, "includes_grid_fee") and + data.data.optional_data.flexible_tariff_module.config.includes_grid_fee is False): return grid_fee_prices else: # Bei flexiblen Tarifen, die das Netzentgelt _nicht_ enthalten, @@ -105,7 +107,7 @@ def __normalize_grid_fee_prices(grid_fee_prices: Dict[int, float], max_timestamp def __sum_of_tariff_and_grid_fee( flexible_tariff_prices: Dict[int, float], grid_fee_prices: Dict[int, float] - ) -> Dict[int, float]: + ) -> Dict[int, float]: grid_fee_prices = __normalize_grid_fee_prices(grid_fee_prices, max(flexible_tariff_prices.keys())) timestamps = sorted(list(set(flexible_tariff_prices.keys()) | set(grid_fee_prices.keys()))) return {ts: (__get_value_at_or_before(flexible_tariff_prices, ts) + diff --git a/packages/modules/electricity_pricing/flexible_tariffs/energycharts/tariff.py b/packages/modules/electricity_pricing/flexible_tariffs/energycharts/tariff.py index cdd6a56827..49d205a7c5 100644 --- a/packages/modules/electricity_pricing/flexible_tariffs/energycharts/tariff.py +++ b/packages/modules/electricity_pricing/flexible_tariffs/energycharts/tariff.py @@ -39,19 +39,9 @@ def parse_response(config: EnergyChartsTariffConfiguration, raw_prices: dict) -> def fetch_prices(config: EnergyChartsTariffConfiguration) -> Dict[str, float]: url = create_request_url(config) - for attempt in range(MAX_RETRIES): - attempt += 1 # one-based indexing - try: - response = req.get_http_session().get(url, timeout=(10, 20)) - response.raise_for_status() - return parse_response(config, response.json()) - except requests.exceptions.Timeout as e: - if MAX_RETRIES > attempt: - delay = (attempt) * random.uniform(attempt, MAX_DELAY) - log.warning(f"Timeout beim Abrufen der Preise (Versuch {attempt}/{MAX_RETRIES}) : {str(e)}" - f", neuer Versuch in {delay:.1f} Sekunden...") - time.sleep(delay) - raise Exception("Timeout beim Abrufen der Preise nach {MAX_RETRIES} Versuchen") + response = req.get_http_session().get(url, timeout=(10, 20)) + response.raise_for_status() + return parse_response(config, response.json()) def create_electricity_tariff(config: EnergyChartsTariff): From 0657d4652841d88dbb50844f5f2b813ff7b74f84 Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Mon, 30 Mar 2026 16:18:21 +0200 Subject: [PATCH 2/4] handle no price data --- packages/modules/common/store/_tariff.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/modules/common/store/_tariff.py b/packages/modules/common/store/_tariff.py index 4ec04a915d..4b9a30f24d 100644 --- a/packages/modules/common/store/_tariff.py +++ b/packages/modules/common/store/_tariff.py @@ -122,6 +122,9 @@ def __sum_of_tariff_and_grid_fee( in electricity_pricing.grid_fee.get.prices.items()} flexible_tariff_prices = __reduce_prices(flexible_tariff_prices) + if len(flexible_tariff_prices) == 0 and len(grid_fee_prices) == 0: + return {} + if len(grid_fee_prices) == 0 and len(flexible_tariff_prices) > 0: return flexible_tariff_prices From a12c47d8e55f40bc1ee578de3a1520ebc9b94b0f Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Mon, 30 Mar 2026 16:22:13 +0200 Subject: [PATCH 3/4] falke8 --- .../flexible_tariffs/energycharts/tariff.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/modules/electricity_pricing/flexible_tariffs/energycharts/tariff.py b/packages/modules/electricity_pricing/flexible_tariffs/energycharts/tariff.py index 49d205a7c5..f20893bbe7 100644 --- a/packages/modules/electricity_pricing/flexible_tariffs/energycharts/tariff.py +++ b/packages/modules/electricity_pricing/flexible_tariffs/energycharts/tariff.py @@ -1,7 +1,4 @@ import logging -import random -import requests -import time from typing import Dict from datetime import datetime, timedelta from helpermodules import timecheck From a380812314f2962a1669fc4d0a1a3c237df7eac6 Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Mon, 30 Mar 2026 16:30:35 +0200 Subject: [PATCH 4/4] review --- packages/control/optional.py | 4 ++-- packages/control/optional_test.py | 2 +- .../flexible_tariffs/energycharts/tariff.py | 2 -- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/control/optional.py b/packages/control/optional.py index 0a331267df..7bb6400a33 100644 --- a/packages/control/optional.py +++ b/packages/control/optional.py @@ -259,9 +259,9 @@ def et_price_update_required(self) -> bool: return False if len(self.data.electricity_pricing.get.prices) == 0: return True - return ((self._flexible_tariff_module and + return ((self._flexible_tariff_module is not None and self._is_et_price_update_required_for_module(self.data.electricity_pricing.flexible_tariff)) or - (self._grid_fee_module and + (self._grid_fee_module is not None and self._is_et_price_update_required_for_module(self.data.electricity_pricing.grid_fee))) def ocpp_transfer_meter_values(self): diff --git a/packages/control/optional_test.py b/packages/control/optional_test.py index 32994f640c..f729577bca 100644 --- a/packages/control/optional_test.py +++ b/packages/control/optional_test.py @@ -473,7 +473,7 @@ def test_et_price_update_required(monkeypatch, flexible_tariff, grid_fee, curren # setup opt = Optional() opt._flexible_tariff_module = Mock() - opt._grid_fee_module = Mock() + opt._grid_fee_module = None opt.data.electricity_pricing.get.prices = flexible_tariff["prices"] opt.data.electricity_pricing.flexible_tariff.get.prices = flexible_tariff["prices"] opt.data.electricity_pricing.flexible_tariff.get.next_query_time = flexible_tariff["next_query_time"] diff --git a/packages/modules/electricity_pricing/flexible_tariffs/energycharts/tariff.py b/packages/modules/electricity_pricing/flexible_tariffs/energycharts/tariff.py index f20893bbe7..8ebce91750 100644 --- a/packages/modules/electricity_pricing/flexible_tariffs/energycharts/tariff.py +++ b/packages/modules/electricity_pricing/flexible_tariffs/energycharts/tariff.py @@ -8,8 +8,6 @@ from modules.electricity_pricing.flexible_tariffs.energycharts.config import EnergyChartsTariffConfiguration from modules.electricity_pricing.flexible_tariffs.energycharts.config import EnergyChartsTariff -MAX_RETRIES = 10 -MAX_DELAY = 10 log = logging.getLogger(__name__)