@@ -47,14 +47,22 @@ def start(self) -> None:
47
47
while True :
48
48
try :
49
49
if first_iteration :
50
- next_price_minimum = self .tibber_api_handler .get_timestamp_of_next_price_minimum (first_iteration )
50
+ next_price_minimum , minimum_has_to_be_rechecked = (
51
+ self .tibber_api_handler .get_timestamp_of_next_price_minimum (first_iteration )
52
+ )
51
53
first_iteration = False
52
54
else :
53
- next_price_minimum = self ._do_iteration ()
55
+ next_price_minimum , minimum_has_to_be_rechecked = self ._do_iteration ()
56
+
57
+ time_to_sleep_to = next_price_minimum
58
+ if minimum_has_to_be_rechecked :
59
+ time_to_sleep_to = time_to_sleep_to .replace (hour = 14 , minute = 0 , second = 0 , microsecond = 0 )
60
+ self .log .info (f"The price minimum has to re-checked at { time_to_sleep_to } . Waiting until then..." )
61
+ else :
62
+ self .log .info (f"The next price minimum is at { next_price_minimum } . Waiting until then..." )
54
63
55
- self .log .info (f"The next price minimum is at { next_price_minimum } . Waiting until then..." )
56
64
self ._write_newlines_to_log_file ()
57
- pause .until (next_price_minimum )
65
+ pause .until (time_to_sleep_to )
58
66
59
67
except (ClientError , RequestException ) as e :
60
68
self .log .exception (f"An exception occurred while trying to fetch data from a different system: { e } " )
@@ -66,7 +74,7 @@ def start(self) -> None:
66
74
self .log .critical ("Exiting now..." )
67
75
exit (1 )
68
76
69
- def _do_iteration (self ) -> datetime : # FIXME: Find better name
77
+ def _do_iteration (self ) -> tuple [ datetime , bool ] : # FIXME: Find better name
70
78
"""
71
79
Computes the optimal charging strategy for an inverter until the next price minimum.
72
80
@@ -80,16 +88,23 @@ def _do_iteration(self) -> datetime: # FIXME: Find better name
80
88
81
89
Returns:
82
90
datetime: The timestamp of the next price minimum.
91
+ minimum_has_to_be_rechecked: Whether the price minimum has to be re-checked since not all the prices were
92
+ available yet.
83
93
"""
84
94
self .log .info (
85
95
"Waiting is over, now is the a price minimum. Checking what has to be done to reach the next minimum..."
86
96
)
87
97
88
98
timestamp_now = datetime .now (tz = self .timezone )
89
99
90
- next_price_minimum = self .tibber_api_handler .get_timestamp_of_next_price_minimum ()
100
+ next_price_minimum , minimum_has_to_be_rechecked = self .tibber_api_handler .get_timestamp_of_next_price_minimum ()
91
101
self .log .info (f"The next price minimum is at { next_price_minimum } " )
92
102
103
+ if minimum_has_to_be_rechecked :
104
+ self .log .info (
105
+ "The price minimum has to be re-checked since it is at the end of a day and the price rates for tomorrow are unavailable"
106
+ )
107
+
93
108
expected_power_harvested_till_next_minimum = self .sun_forecast_handler .get_solar_output_in_timeframe (
94
109
timestamp_now , next_price_minimum
95
110
)
@@ -111,6 +126,15 @@ def _do_iteration(self) -> datetime: # FIXME: Find better name
111
126
expected_energy_usage_till_next_minimum = self .sems_portal_api_handler .estimate_energy_usage_in_timeframe (
112
127
timestamp_now , next_price_minimum
113
128
)
129
+
130
+ if minimum_has_to_be_rechecked :
131
+ power_usage_factor = 1.15
132
+ self .log .info (
133
+ "Since the real price minimum is unknown at the moment the expected power usage "
134
+ + f"({ expected_energy_usage_till_next_minimum } ) is increased by { (power_usage_factor - 1 ) * 100 } %"
135
+ )
136
+ expected_energy_usage_till_next_minimum = expected_energy_usage_till_next_minimum * power_usage_factor
137
+
114
138
self .log .info (
115
139
f"The total expected energy usage till the next price minimum is { expected_energy_usage_till_next_minimum } "
116
140
)
@@ -140,6 +164,7 @@ def _do_iteration(self) -> datetime: # FIXME: Find better name
140
164
"current energy in battery" : current_energy_in_battery ,
141
165
"target min state of charge" : target_min_state_of_charge ,
142
166
"energy to be in battery when reaching next minimum" : energy_to_be_in_battery_when_reaching_next_minimum ,
167
+ "minimum_has_to_be_rechecked" : minimum_has_to_be_rechecked ,
143
168
}
144
169
self .log .debug (f"Summary of energy values: { summary_of_energy_vales } " )
145
170
@@ -151,7 +176,7 @@ def _do_iteration(self) -> datetime: # FIXME: Find better name
151
176
)
152
177
if excess_energy .watt_hours > 0 :
153
178
self .log .info (f"There is { excess_energy } of excess energy, thus there is no need to charge" )
154
- return next_price_minimum
179
+ return next_price_minimum , minimum_has_to_be_rechecked
155
180
156
181
missing_energy = excess_energy * - 1
157
182
self .log .info (f"There is a need to charge { missing_energy } " )
@@ -181,7 +206,7 @@ def _do_iteration(self) -> datetime: # FIXME: Find better name
181
206
timestamp_starting_to_charge , timestamp_ending_to_charge , energy_bought
182
207
)
183
208
184
- return next_price_minimum
209
+ return next_price_minimum , minimum_has_to_be_rechecked
185
210
186
211
def _charge_inverter (self , target_state_of_charge : int ) -> None :
187
212
"""
0 commit comments