22import logging
33import datetime
44import time
5+ from typing import List , Tuple , Dict
56
67from modules .electricity_tariffs .fixed_hours .config import FixedHoursTariff , FixedHoursTariffConfiguration
78from modules .common .abstract_device import DeviceDescriptor
1112log = 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
5468def create_electricity_tariff (config : FixedHoursTariff ):
55- def updater ():
69+ def updater () -> TariffState :
5670 return fetch (config .configuration )
5771 return updater
5872
0 commit comments