From 38796ce56201fa9b7f70086a58e23c495812c2d8 Mon Sep 17 00:00:00 2001 From: MartinRinas Date: Thu, 23 Jan 2025 21:51:30 +0000 Subject: [PATCH 1/4] fix midnight --- packages/modules/electricity_tariffs/fixed_hours/tariff.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/modules/electricity_tariffs/fixed_hours/tariff.py b/packages/modules/electricity_tariffs/fixed_hours/tariff.py index f4edb9f3d7..08d16e698d 100644 --- a/packages/modules/electricity_tariffs/fixed_hours/tariff.py +++ b/packages/modules/electricity_tariffs/fixed_hours/tariff.py @@ -12,6 +12,8 @@ def to_time(time_str): + if time_str == "24:00": + return datetime.time(23, 59, 59) return datetime.datetime.strptime(time_str, "%H:%M").time() From f6655c8bc6d1537f6e8fe7b9cbd9957ef4290ca5 Mon Sep 17 00:00:00 2001 From: MartinRinas Date: Thu, 23 Jan 2025 22:00:09 +0000 Subject: [PATCH 2/4] consider quater when checking overlapping tariff windows --- packages/modules/electricity_tariffs/fixed_hours/tariff.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/modules/electricity_tariffs/fixed_hours/tariff.py b/packages/modules/electricity_tariffs/fixed_hours/tariff.py index 08d16e698d..e27b1ab595 100644 --- a/packages/modules/electricity_tariffs/fixed_hours/tariff.py +++ b/packages/modules/electricity_tariffs/fixed_hours/tariff.py @@ -23,10 +23,11 @@ def validate_tariff_times(config): for start, end in tariff["active_times"]["times"]: start_time = to_time(start) end_time = to_time(end) - for existing_start, existing_end in time_slots: - if (start_time < existing_end and end_time > existing_start): + for existing_start, existing_end, existing_quarters in time_slots: + if (start_time < existing_end and end_time > existing_start and + any(quarter in tariff["active_times"]["quarters"] for quarter in existing_quarters)): raise ValueError(f"Overlapping time window detected: {start} - {end} in tariff '{tariff['name']}'") - time_slots.append((start_time, end_time)) + time_slots.append((start_time, end_time, tariff["active_times"]["quarters"])) def fetch(config: FixedHoursTariffConfiguration) -> None: From a9ef896f26149c8b5c03cfa7d199723646f89559 Mon Sep 17 00:00:00 2001 From: MartinRinas Date: Tue, 28 Jan 2025 20:42:52 +0000 Subject: [PATCH 3/4] replace fixed quarters with date range --- .../electricity_tariffs/fixed_hours/config.py | 4 +-- .../electricity_tariffs/fixed_hours/tariff.py | 34 ++++++++++++------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/packages/modules/electricity_tariffs/fixed_hours/config.py b/packages/modules/electricity_tariffs/fixed_hours/config.py index 37587bf12b..e9c15419b6 100644 --- a/packages/modules/electricity_tariffs/fixed_hours/config.py +++ b/packages/modules/electricity_tariffs/fixed_hours/config.py @@ -12,7 +12,7 @@ def __init__(self, default_price: Optional[float] = None, tariffs: List[Dict[str "name": "high_tariff", "price": 0.20, "active_times": { - "quarters": [1, 2, 3, 4], # applicable quarters + "dates": [("01-01", "31-03"), ("01-07", "30-09")], # applicable date ranges (day-month) "times": [("08:00", "12:00"), ("18:00", "22:00")] # active times during the day } }, @@ -20,7 +20,7 @@ def __init__(self, default_price: Optional[float] = None, tariffs: List[Dict[str "name": "low_tariff", "price": 0.05, "active_times": { - "quarters": [1, 2, 3, 4], # applicable quarters + "dates": [("01-04", "30-06"), ("01-10", "31-12")], # applicable date ranges (day-month) "times": [("00:00", "06:00"), ("22:00", "23:59")] # active times during the day } } diff --git a/packages/modules/electricity_tariffs/fixed_hours/tariff.py b/packages/modules/electricity_tariffs/fixed_hours/tariff.py index e27b1ab595..7a5daa03dd 100644 --- a/packages/modules/electricity_tariffs/fixed_hours/tariff.py +++ b/packages/modules/electricity_tariffs/fixed_hours/tariff.py @@ -2,6 +2,7 @@ import logging import datetime import time +from typing import List, Tuple, Dict from modules.electricity_tariffs.fixed_hours.config import FixedHoursTariff, FixedHoursTariffConfiguration from modules.common.abstract_device import DeviceDescriptor @@ -11,42 +12,49 @@ log = logging.getLogger(__name__) -def to_time(time_str): +def to_time(time_str: str) -> datetime.time: if time_str == "24:00": return datetime.time(23, 59, 59) return datetime.datetime.strptime(time_str, "%H:%M").time() -def validate_tariff_times(config): - time_slots = [] +def to_date(date_str: str, time_slot: datetime.datetime) -> datetime.date: + date = datetime.datetime.strptime(date_str, "%d-%m").date().replace(year=datetime.datetime.now().year) + if date.year < time_slot.year: # Beim Jahreswechsel das korrekte Jahr setzen + date = date.replace(year=time_slot.year) + return date + + +def validate_tariff_times(config: FixedHoursTariffConfiguration) -> None: + time_slots: List[Tuple[datetime.time, datetime.time, List[Tuple[str, str]]]] = [] for tariff in config.tariffs: for start, end in tariff["active_times"]["times"]: start_time = to_time(start) end_time = to_time(end) - for existing_start, existing_end, existing_quarters in time_slots: + for existing_start, existing_end, existing_dates in time_slots: if (start_time < existing_end and end_time > existing_start and - any(quarter in tariff["active_times"]["quarters"] for quarter in existing_quarters)): + any(start <= existing_end and end >= existing_start for start, end in existing_dates)): raise ValueError(f"Overlapping time window detected: {start} - {end} in tariff '{tariff['name']}'") - time_slots.append((start_time, end_time, tariff["active_times"]["quarters"])) + time_slots.append((start_time, end_time, tariff["active_times"]["dates"])) -def fetch(config: FixedHoursTariffConfiguration) -> None: +def fetch(config: FixedHoursTariffConfiguration) -> TariffState: validate_tariff_times(config) current_time = datetime.datetime.now().replace(minute=0, second=0, microsecond=0) - prices = {} + prices: Dict[str, float] = {} for i in range(24): # get prices for the next 24 hours time_slot = current_time + datetime.timedelta(hours=i) epoch_time = int(time.mktime(time_slot.timetuple())) - quarter = (current_time.month - 1) // 3 + 1 - price = config.default_price/1000 + price = config.default_price / 1000 for tariff in config.tariffs: active_times = [(to_time(start), to_time(end)) for start, end in tariff["active_times"]["times"]] + active_dates = [(to_date(start, time_slot), to_date(end, time_slot)) for start, end in tariff["active_times"]["dates"]] if (any(start <= time_slot.time() < end for start, end in active_times) and - quarter in tariff["active_times"]["quarters"]): - price = tariff["price"]/1000 + any(start <= time_slot.date() <= end for start, end in active_dates)): + price = tariff["price"] / 1000 break # Break since we found a matching tariff prices[str(epoch_time)] = price @@ -55,7 +63,7 @@ def fetch(config: FixedHoursTariffConfiguration) -> None: def create_electricity_tariff(config: FixedHoursTariff): - def updater(): + def updater() -> TariffState: return fetch(config.configuration) return updater From fa986540af38a7106cf916182ef441bf371794f8 Mon Sep 17 00:00:00 2001 From: MartinRinas Date: Tue, 28 Jan 2025 20:43:41 +0000 Subject: [PATCH 4/4] fix formatting --- packages/modules/electricity_tariffs/fixed_hours/tariff.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/modules/electricity_tariffs/fixed_hours/tariff.py b/packages/modules/electricity_tariffs/fixed_hours/tariff.py index 7a5daa03dd..0a73ccb125 100644 --- a/packages/modules/electricity_tariffs/fixed_hours/tariff.py +++ b/packages/modules/electricity_tariffs/fixed_hours/tariff.py @@ -51,7 +51,10 @@ def fetch(config: FixedHoursTariffConfiguration) -> TariffState: for tariff in config.tariffs: active_times = [(to_time(start), to_time(end)) for start, end in tariff["active_times"]["times"]] - active_dates = [(to_date(start, time_slot), to_date(end, time_slot)) for start, end in tariff["active_times"]["dates"]] + active_dates = [ + (to_date(start, time_slot), to_date(end, time_slot)) + for start, end in tariff["active_times"]["dates"] + ] if (any(start <= time_slot.time() < end for start, end in active_times) and any(start <= time_slot.date() <= end for start, end in active_dates)): price = tariff["price"] / 1000