Skip to content

Commit c91b3e6

Browse files
authored
Merge pull request #2172 from MartinRinas/feature-fixed-hour-tariff
Fix handling of midnight time input
2 parents be987c7 + fa98654 commit c91b3e6

2 files changed

Lines changed: 29 additions & 15 deletions

File tree

packages/modules/electricity_tariffs/fixed_hours/config.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ def __init__(self, default_price: Optional[float] = None, tariffs: List[Dict[str
1212
"name": "high_tariff",
1313
"price": 0.20,
1414
"active_times": {
15-
"quarters": [1, 2, 3, 4], # applicable quarters
15+
"dates": [("01-01", "31-03"), ("01-07", "30-09")], # applicable date ranges (day-month)
1616
"times": [("08:00", "12:00"), ("18:00", "22:00")] # active times during the day
1717
}
1818
},
1919
{
2020
"name": "low_tariff",
2121
"price": 0.05,
2222
"active_times": {
23-
"quarters": [1, 2, 3, 4], # applicable quarters
23+
"dates": [("01-04", "30-06"), ("01-10", "31-12")], # applicable date ranges (day-month)
2424
"times": [("00:00", "06:00"), ("22:00", "23:59")] # active times during the day
2525
}
2626
}

packages/modules/electricity_tariffs/fixed_hours/tariff.py

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import logging
33
import datetime
44
import time
5+
from typing import List, Tuple, Dict
56

67
from modules.electricity_tariffs.fixed_hours.config import FixedHoursTariff, FixedHoursTariffConfiguration
78
from modules.common.abstract_device import DeviceDescriptor
@@ -11,39 +12,52 @@
1112
log = logging.getLogger(__name__)
1213

1314

14-
def to_time(time_str):
15+
def to_time(time_str: str) -> datetime.time:
16+
if time_str == "24:00":
17+
return datetime.time(23, 59, 59)
1518
return datetime.datetime.strptime(time_str, "%H:%M").time()
1619

1720

18-
def validate_tariff_times(config):
19-
time_slots = []
21+
def to_date(date_str: str, time_slot: datetime.datetime) -> datetime.date:
22+
date = datetime.datetime.strptime(date_str, "%d-%m").date().replace(year=datetime.datetime.now().year)
23+
if date.year < time_slot.year: # Beim Jahreswechsel das korrekte Jahr setzen
24+
date = date.replace(year=time_slot.year)
25+
return date
26+
27+
28+
def validate_tariff_times(config: FixedHoursTariffConfiguration) -> None:
29+
time_slots: List[Tuple[datetime.time, datetime.time, List[Tuple[str, str]]]] = []
2030
for tariff in config.tariffs:
2131
for start, end in tariff["active_times"]["times"]:
2232
start_time = to_time(start)
2333
end_time = to_time(end)
24-
for existing_start, existing_end in time_slots:
25-
if (start_time < existing_end and end_time > existing_start):
34+
for existing_start, existing_end, existing_dates in time_slots:
35+
if (start_time < existing_end and end_time > existing_start and
36+
any(start <= existing_end and end >= existing_start for start, end in existing_dates)):
2637
raise ValueError(f"Overlapping time window detected: {start} - {end} in tariff '{tariff['name']}'")
27-
time_slots.append((start_time, end_time))
38+
time_slots.append((start_time, end_time, tariff["active_times"]["dates"]))
2839

2940

30-
def fetch(config: FixedHoursTariffConfiguration) -> None:
41+
def fetch(config: FixedHoursTariffConfiguration) -> TariffState:
3142
validate_tariff_times(config)
3243

3344
current_time = datetime.datetime.now().replace(minute=0, second=0, microsecond=0)
34-
prices = {}
45+
prices: Dict[str, float] = {}
3546

3647
for i in range(24): # get prices for the next 24 hours
3748
time_slot = current_time + datetime.timedelta(hours=i)
3849
epoch_time = int(time.mktime(time_slot.timetuple()))
39-
quarter = (current_time.month - 1) // 3 + 1
40-
price = config.default_price/1000
50+
price = config.default_price / 1000
4151

4252
for tariff in config.tariffs:
4353
active_times = [(to_time(start), to_time(end)) for start, end in tariff["active_times"]["times"]]
54+
active_dates = [
55+
(to_date(start, time_slot), to_date(end, time_slot))
56+
for start, end in tariff["active_times"]["dates"]
57+
]
4458
if (any(start <= time_slot.time() < end for start, end in active_times) and
45-
quarter in tariff["active_times"]["quarters"]):
46-
price = tariff["price"]/1000
59+
any(start <= time_slot.date() <= end for start, end in active_dates)):
60+
price = tariff["price"] / 1000
4761
break # Break since we found a matching tariff
4862

4963
prices[str(epoch_time)] = price
@@ -52,7 +66,7 @@ def fetch(config: FixedHoursTariffConfiguration) -> None:
5266

5367

5468
def create_electricity_tariff(config: FixedHoursTariff):
55-
def updater():
69+
def updater() -> TariffState:
5670
return fetch(config.configuration)
5771
return updater
5872

0 commit comments

Comments
 (0)