@@ -132,6 +132,7 @@ def run_prediction(self, now, charge_limit, load_minutes, pv_forecast_minute, sa
132132 import_kwh = 0
133133 import_kwh_house = 0
134134 import_kwh_battery = 0
135+ load_kwh = 0
135136 metric = 0
136137
137138 # For the SOC calculation we need to stop at the second charge window to avoid confusing multiple days out
@@ -152,9 +153,7 @@ def run_prediction(self, now, charge_limit, load_minutes, pv_forecast_minute, sa
152153 minute_yesterday = 24 * 60 - minute + six_days
153154 # Average previous load over 10 minutes due to sampling accuracy
154155 load_yesterday = self .get_from_incrementing (load_minutes , minute_yesterday )
155- if load_yesterday < 0 :
156- self .log ("WARN: Negative load %s at %s" % (load_yesterday , minute ))
157-
156+
158157 minute_absolute = minute + self .minutes_now
159158 minute_timestamp = self .midnight_utc + timedelta (seconds = 60 * minute_absolute )
160159
@@ -166,12 +165,15 @@ def run_prediction(self, now, charge_limit, load_minutes, pv_forecast_minute, sa
166165 car_energy = self .get_from_incrementing (self .car_charging_energy , minute_yesterday )
167166 if self .debug_enable and car_energy > 0.0 and (minute % 60 ) == 0 and (minute < 60 * 48 ):
168167 self .log ("Hour %s car charging hold with data %s load now %s metric %s" % (minute / 60 , car_energy , load_yesterday , metric ))
168+ load_yesterday = max (0 , load_yesterday - car_energy )
169169 elif self .car_charging_hold and (load_yesterday >= self .car_charging_threshold ):
170170 # Car charging hold - ignore car charging in computation based on threshold
171171 load_yesterday = 0
172172 if self .debug_enable and minute % 60 == 0 :
173173 self .log ("Hour %s car charging hold" % (minute / 60 ))
174174
175+ # Count load
176+ load_kwh += load_yesterday
175177
176178 # Are we within the charging time window?
177179 if self .charge_enable and soc < charge_limit and self .in_charge_window (minute_absolute ):
@@ -182,6 +184,9 @@ def run_prediction(self, now, charge_limit, load_minutes, pv_forecast_minute, sa
182184 # For now we ignore PV in this as it's probably not a major factor when mains charging is enabled
183185 if record :
184186 energy = max (0 , soc - old_soc - pv_now ) / self .battery_loss
187+
188+ # Must add in grid import for load
189+ energy += load_yesterday
185190 import_kwh += energy
186191 import_kwh_battery += energy
187192 if minute_absolute in self .octopus_import :
@@ -275,6 +280,7 @@ def run_prediction(self, now, charge_limit, load_minutes, pv_forecast_minute, sa
275280 self .set_state ("predbat.charge_limit_kw" , state = self .dp2 (charge_limit ), attributes = {'friendly_name' : 'Predicted charge limit kwh' , 'state_class' : 'measurement' , 'unit_of_measurement' : 'kwh' })
276281 self .set_state ("predbat.charge_limit" , state = charge_limit_percent , attributes = {'friendly_name' : 'Predicted charge limit' , 'state_class' : 'measurement' , 'unit_of_measurement' : '%' })
277282 self .set_state ("predbat.export_energy" , state = self .dp2 (export_kwh ), attributes = {'friendly_name' : 'Predicted exports' , 'state_class' : 'measurement' , 'unit_of_measurement' : 'kwh' })
283+ self .set_state ("predbat.load_energy" , state = self .dp2 (load_kwh ), attributes = {'friendly_name' : 'Predicted load' , 'state_class' : 'measurement' , 'unit_of_measurement' : 'kwh' })
278284 self .set_state ("predbat.import_energy" , state = self .dp2 (import_kwh ), attributes = {'friendly_name' : 'Predicted imports' , 'state_class' : 'measurement' , 'unit_of_measurement' : 'kwh' })
279285 self .set_state ("predbat.import_energy_battery" , state = self .dp2 (import_kwh_battery ), attributes = {'friendly_name' : 'Predicted import to battery' , 'state_class' : 'measurement' , 'unit_of_measurement' : 'kwh' })
280286 self .set_state ("predbat.import_energy_house" , state = self .dp2 (import_kwh_house ), attributes = {'friendly_name' : 'Predicted import to house' , 'state_class' : 'measurement' , 'unit_of_measurement' : 'kwh' })
@@ -287,6 +293,7 @@ def run_prediction(self, now, charge_limit, load_minutes, pv_forecast_minute, sa
287293 self .set_state ("predbat.soc_kw_best" , state = self .dp2 (final_soc ), attributes = {'results' : predict_soc_time , 'friendly_name' : 'Battery SOC kwh best' , 'state_class' : 'measurement' , 'unit_of_measurement' : 'kwh' , 'step' : 0.5 })
288294 self .set_state ("predbat.best_charge_limit_kw" , state = self .dp2 (charge_limit ), attributes = {'friendly_name' : 'Predicted charge limit kwh best' , 'state_class' : 'measurement' , 'unit_of_measurement' : 'kwh' })
289295 self .set_state ("predbat.best_charge_limit" , state = charge_limit_percent , attributes = {'friendly_name' : 'Predicted charge limit best' , 'state_class' : 'measurement' , 'unit_of_measurement' : '%' })
296+ self .set_state ("predbat.best_load_energy" , state = self .dp2 (load_kwh ), attributes = {'friendly_name' : 'Predicted load best' , 'state_class' : 'measurement' , 'unit_of_measurement' : 'kwh' })
290297 self .set_state ("predbat.best_export_energy" , state = self .dp2 (export_kwh ), attributes = {'friendly_name' : 'Predicted exports best' , 'state_class' : 'measurement' , 'unit_of_measurement' : 'kwh' })
291298 self .set_state ("predbat.best_import_energy" , state = self .dp2 (import_kwh ), attributes = {'friendly_name' : 'Predicted imports best' , 'state_class' : 'measurement' , 'unit_of_measurement' : 'kwh' })
292299 self .set_state ("predbat.best_import_energy_battery" , state = self .dp2 (import_kwh_battery ), attributes = {'friendly_name' : 'Predicted import to battery best' , 'state_class' : 'measurement' , 'unit_of_measurement' : 'kwh' })
0 commit comments