From 95eb78605e8f91eb212eb6983724bcbff7e75aad Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Tue, 16 Dec 2025 09:58:18 +0100 Subject: [PATCH 1/8] draft --- .../flexible_tariffs/rabot/config.py | 20 +---- .../flexible_tariffs/rabot/tariff.py | 75 ++----------------- 2 files changed, 11 insertions(+), 84 deletions(-) diff --git a/packages/modules/electricity_pricing/flexible_tariffs/rabot/config.py b/packages/modules/electricity_pricing/flexible_tariffs/rabot/config.py index b3a29b8e01..2e48c43e2f 100644 --- a/packages/modules/electricity_pricing/flexible_tariffs/rabot/config.py +++ b/packages/modules/electricity_pricing/flexible_tariffs/rabot/config.py @@ -1,24 +1,12 @@ from typing import Optional -class RabotToken(): - def __init__(self, - access_token: Optional[str] = None, - expires_in: Optional[str] = None, - created_at: Optional[str] = None) -> None: - self.access_token = access_token # don't show in UI - self.expires_in = expires_in # don't show in UI - self.created_at = created_at # don't show in UI - - class RabotTariffConfiguration: def __init__(self, - client_id: Optional[str] = None, - client_secret: Optional[str] = None, - token: RabotToken = None): - self.client_id = client_id - self.client_secret = client_secret - self.token = token or RabotToken() + consumer_number: Optional[str] = None, + contract_number: Optional[str] = None): + self.consumer_number = consumer_number + self.contract_number = contract_number class RabotTariff: diff --git a/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py b/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py index 0d64234468..f5104b0462 100644 --- a/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py +++ b/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py @@ -2,90 +2,29 @@ import datetime import logging from typing import Dict -from requests.exceptions import HTTPError -from helpermodules.utils.error_handling import ImportErrorContext -with ImportErrorContext(): - import pytz - -from dataclass_utils import asdict -from helpermodules import timecheck -from helpermodules.pub import Pub from modules.common import req from modules.common.abstract_device import DeviceDescriptor from modules.common.component_state import TariffState -from modules.electricity_pricing.flexible_tariffs.rabot.config import RabotTariff, RabotToken +from modules.electricity_pricing.flexible_tariffs.rabot.config import RabotTariff log = logging.getLogger(__name__) -def validate_token(config: RabotTariff) -> None: - if config.configuration.token.expires_in: - expiration = config.configuration.token.created_at + config.configuration.token.expires_in - log.debug("No need to authenticate. Valid token already present.") - if timecheck.create_timestamp() > expiration: - log.debug("Access token expired. Refreshing token.") - _refresh_token(config) - else: - _refresh_token(config) - - -def _refresh_token(config: RabotTariff): - data = { - 'client_id': {config.configuration.client_id}, - 'client_secret': {config.configuration.client_secret}, - 'grant_type': 'client_credentials', - 'scope': 'openid offline_access api:hems', - } - response = req.get_http_session().post( - 'https://auth.rabot-charge.de/connect/token?client_id=&client_secret=&username=&password=&scope=*&' - + 'grant_type=client_credentials', data=data).json() - config.configuration.token = RabotToken(access_token=response["access_token"], - expires_in=response["expires_in"], - created_at=timecheck.create_timestamp()) - Pub().pub("openWB/set/optional/ep/flexible_tariff/provider", asdict(config)) - - def fetch(config: RabotTariff) -> None: - def get_raw_prices(): - return req.get_http_session().get( - "https://api.rabot-charge.de/hems/v1/day-ahead-prices/limited", - headers={"Content-Type": "application/json", - "Authorization": f'Bearer {config.configuration.token.access_token}'}, - params={"from": start_date, "tz": timezone} - ).json()["records"] - - validate_token(config) - # ToDo: get rid of hard coded timezone! - # start_date von voller Stunde sonst liefert die API die nächste Stunde - start_date = datetime.datetime.fromtimestamp( - timecheck.create_unix_timestamp_current_full_hour()).astimezone( - pytz.timezone("Europe/Berlin")).isoformat(sep="T", timespec="seconds") - if datetime.datetime.today().astimezone(pytz.timezone("Europe/Berlin")).dst().total_seconds()/3600: - # Sommerzeit - timezone = "UTC+2:00" - else: - timezone = "UTC+1:00" - try: - raw_prices = get_raw_prices() - except HTTPError as error: - if error.response.status_code == 401: - _refresh_token(config) - raw_prices = get_raw_prices() - else: - raise error + raw_prices = req.get_http_session().get( + f"https://rabot.openwb.de/rabot-proxy.php/customers/{config.configuration.consumer_number}" + f"/contracts/{config.configuration.contract_number}/metrics" + ).json()["data"]["records"] prices: Dict[int, float] = {} for data in raw_prices: - formatted_price = data["priceInCentPerKwh"]/100000 # Cent/kWh -> €/Wh - timestamp = datetime.datetime.fromisoformat(data["timestamp"]).astimezone( - pytz.timezone("Europe/Berlin")).timestamp() + formatted_price = data["value"]/1000 # €/kWh -> €/Wh + timestamp = datetime.datetime.strptime(data["moment"], "%Y-%m-%d %H:%M").timestamp() prices.update({str(int(timestamp)): formatted_price}) return prices def create_electricity_tariff(config: RabotTariff): - validate_token(config) - def updater(): return TariffState(prices=fetch(config)) return updater From 23edfa00a021f3ee5b454584ad2252a0ae1fd0c6 Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Wed, 17 Dec 2025 14:09:02 +0100 Subject: [PATCH 2/8] fix --- .../electricity_pricing/flexible_tariffs/rabot/config.py | 4 ++-- .../electricity_pricing/flexible_tariffs/rabot/tariff.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/modules/electricity_pricing/flexible_tariffs/rabot/config.py b/packages/modules/electricity_pricing/flexible_tariffs/rabot/config.py index 2e48c43e2f..c18293f965 100644 --- a/packages/modules/electricity_pricing/flexible_tariffs/rabot/config.py +++ b/packages/modules/electricity_pricing/flexible_tariffs/rabot/config.py @@ -3,9 +3,9 @@ class RabotTariffConfiguration: def __init__(self, - consumer_number: Optional[str] = None, + costumer_number: Optional[str] = None, contract_number: Optional[str] = None): - self.consumer_number = consumer_number + self.costumer_number = costumer_number self.contract_number = contract_number diff --git a/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py b/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py index f5104b0462..51c7aff847 100644 --- a/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py +++ b/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py @@ -13,7 +13,7 @@ def fetch(config: RabotTariff) -> None: raw_prices = req.get_http_session().get( - f"https://rabot.openwb.de/rabot-proxy.php/customers/{config.configuration.consumer_number}" + f"https://rabot.openwb.de/rabot-proxy.php/customers/{config.configuration.costumer_number}" f"/contracts/{config.configuration.contract_number}/metrics" ).json()["data"]["records"] prices: Dict[int, float] = {} From fa5cc964ae5f4fa98a858dc23aac8efac16c2edb Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Wed, 17 Dec 2025 14:23:29 +0100 Subject: [PATCH 3/8] fix --- .../electricity_pricing/flexible_tariffs/rabot/tariff.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py b/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py index 51c7aff847..e75bd0c8d4 100644 --- a/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py +++ b/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py @@ -14,7 +14,8 @@ def fetch(config: RabotTariff) -> None: raw_prices = req.get_http_session().get( f"https://rabot.openwb.de/rabot-proxy.php/customers/{config.configuration.costumer_number}" - f"/contracts/{config.configuration.contract_number}/metrics" + f"/contracts/{config.configuration.contract_number}/metrics", + timeout=10 ).json()["data"]["records"] prices: Dict[int, float] = {} for data in raw_prices: From f06d605f1aa6717277ff662867d67f001dd51464 Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Wed, 17 Dec 2025 14:27:17 +0100 Subject: [PATCH 4/8] typo --- .../electricity_pricing/flexible_tariffs/rabot/tariff.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py b/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py index e75bd0c8d4..527b057c33 100644 --- a/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py +++ b/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py @@ -13,7 +13,7 @@ def fetch(config: RabotTariff) -> None: raw_prices = req.get_http_session().get( - f"https://rabot.openwb.de/rabot-proxy.php/customers/{config.configuration.costumer_number}" + f"https://rabot.openwb.de/rabot-proxy.php/customers/{config.configuration.customer_number}" f"/contracts/{config.configuration.contract_number}/metrics", timeout=10 ).json()["data"]["records"] From f60a3c6fee498bdd64abd4dd49761f9607ad7368 Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Wed, 17 Dec 2025 14:40:20 +0100 Subject: [PATCH 5/8] fix --- .../electricity_pricing/flexible_tariffs/rabot/config.py | 4 ++-- .../electricity_pricing/flexible_tariffs/rabot/tariff.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/modules/electricity_pricing/flexible_tariffs/rabot/config.py b/packages/modules/electricity_pricing/flexible_tariffs/rabot/config.py index c18293f965..bdda950bed 100644 --- a/packages/modules/electricity_pricing/flexible_tariffs/rabot/config.py +++ b/packages/modules/electricity_pricing/flexible_tariffs/rabot/config.py @@ -3,9 +3,9 @@ class RabotTariffConfiguration: def __init__(self, - costumer_number: Optional[str] = None, + customer_number: Optional[str] = None, contract_number: Optional[str] = None): - self.costumer_number = costumer_number + self.customer_number = customer_number self.contract_number = contract_number diff --git a/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py b/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py index 527b057c33..4fec17a812 100644 --- a/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py +++ b/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py @@ -15,7 +15,7 @@ def fetch(config: RabotTariff) -> None: raw_prices = req.get_http_session().get( f"https://rabot.openwb.de/rabot-proxy.php/customers/{config.configuration.customer_number}" f"/contracts/{config.configuration.contract_number}/metrics", - timeout=10 + timeout=15 ).json()["data"]["records"] prices: Dict[int, float] = {} for data in raw_prices: From 056d01c3f181f1f685c926a58bc066adf14a219b Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Thu, 18 Dec 2025 10:28:12 +0100 Subject: [PATCH 6/8] fixes --- packages/control/optional.py | 9 ++++----- packages/modules/loadvars.py | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/control/optional.py b/packages/control/optional.py index e3286d9603..044dd32a70 100644 --- a/packages/control/optional.py +++ b/packages/control/optional.py @@ -154,11 +154,10 @@ def remove(price_data: Dict) -> Dict: try: if self.data.electricity_pricing.configured: - if len(self.data.electricity_pricing.get.prices) == 0: - return - ep = self.data.electricity_pricing - ep.get.prices = remove(ep.get.prices) - Pub().pub("openWB/set/optional/ep/get/prices", ep.get.prices) + if len(self.data.electricity_pricing.get.prices) >= 0: + ep = self.data.electricity_pricing + ep.get.prices = remove(ep.get.prices) + Pub().pub("openWB/set/optional/ep/get/prices", ep.get.prices) if self._flexible_tariff_module: ep.flexible_tariff.get.prices = remove(ep.flexible_tariff.get.prices) Pub().pub("openWB/set/optional/ep/flexible_tariff/get/prices", ep.flexible_tariff.get.prices) diff --git a/packages/modules/loadvars.py b/packages/modules/loadvars.py index 76009ec8f2..a7b35aca8a 100644 --- a/packages/modules/loadvars.py +++ b/packages/modules/loadvars.py @@ -155,7 +155,7 @@ def append_thread_set_values(module_name: str) -> None: joined_thread_handler(threads_set_values, None) wait_for_module_update_completed(self.event_module_update_completed, "openWB/set/optional/ep/module_update_completed") - data.data.copy_module_data() + data.data.copy_data() self.price_value_store.update() except Exception as e: log.exception("Fehler im Optional-Modul: %s", e) From 607d776d4614d3b85d31c7feb49dc1683eae8327 Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Thu, 18 Dec 2025 10:53:46 +0100 Subject: [PATCH 7/8] unit --- .../electricity_pricing/flexible_tariffs/rabot/tariff.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py b/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py index 4fec17a812..b4c19a2f89 100644 --- a/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py +++ b/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py @@ -19,7 +19,7 @@ def fetch(config: RabotTariff) -> None: ).json()["data"]["records"] prices: Dict[int, float] = {} for data in raw_prices: - formatted_price = data["value"]/1000 # €/kWh -> €/Wh + formatted_price = data["value"] / 100.000 # ct/kWh -> €/Wh timestamp = datetime.datetime.strptime(data["moment"], "%Y-%m-%d %H:%M").timestamp() prices.update({str(int(timestamp)): formatted_price}) return prices From 0a2a09461b8cb0147f542186021bdc156d9adb7f Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Thu, 18 Dec 2025 11:57:31 +0100 Subject: [PATCH 8/8] fix unit --- .../electricity_pricing/flexible_tariffs/rabot/tariff.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py b/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py index b4c19a2f89..605c8fbe8c 100644 --- a/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py +++ b/packages/modules/electricity_pricing/flexible_tariffs/rabot/tariff.py @@ -19,7 +19,7 @@ def fetch(config: RabotTariff) -> None: ).json()["data"]["records"] prices: Dict[int, float] = {} for data in raw_prices: - formatted_price = data["value"] / 100.000 # ct/kWh -> €/Wh + formatted_price = data["value"] / 100000 # ct/kWh -> €/Wh timestamp = datetime.datetime.strptime(data["moment"], "%Y-%m-%d %H:%M").timestamp() prices.update({str(int(timestamp)): formatted_price}) return prices