Spaces:
Sleeping
Sleeping
Daniel Varga commited on
Commit ·
eb9eaaf
1
Parent(s): 4da0b0d
tuned params, vis
Browse files- v2/architecture.py +27 -11
- v2/supplier.py +1 -1
v2/architecture.py
CHANGED
|
@@ -3,12 +3,15 @@ import pandas as pd
|
|
| 3 |
import copy
|
| 4 |
import time
|
| 5 |
from enum import IntEnum
|
|
|
|
| 6 |
|
| 7 |
# it's really just a network pricing model
|
| 8 |
from supplier import Supplier
|
| 9 |
from data_processing import read_datasets, add_production_field, interpolate_and_join, SolarParameters
|
| 10 |
|
| 11 |
|
|
|
|
|
|
|
| 12 |
STEPS_PER_HOUR = 12
|
| 13 |
|
| 14 |
|
|
@@ -95,9 +98,10 @@ class Decision(IntEnum):
|
|
| 95 |
# mock class as usual
|
| 96 |
# output_window_size is not yet used, always decides one timestep.
|
| 97 |
class Decider:
|
| 98 |
-
def __init__(self):
|
| 99 |
self.input_window_size = STEPS_PER_HOUR * 24 # day long window.
|
| 100 |
self.random_seed = 0
|
|
|
|
| 101 |
|
| 102 |
# prod_cons_pred is a dataframe starting at now, containing
|
| 103 |
# fields Production and Consumption.
|
|
@@ -105,6 +109,17 @@ class Decider:
|
|
| 105 |
# battery_model is just queried for capacity and current soc.
|
| 106 |
# the method returns a pd.Series of Decisions as integers.
|
| 107 |
def decide(self, prod_pred, cons_pred, battery_model):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
# assert len(prod_pred) == len(cons_pred) == self.input_window_size
|
| 109 |
self.random_seed += 1
|
| 110 |
self.random_seed %= 3 # dummy rotates between Decisions
|
|
@@ -232,11 +247,11 @@ def simulator(battery_model, supplier, prod_cons, decider):
|
|
| 232 |
consumption_from_network_pandas_series,
|
| 233 |
provide_detail=True)
|
| 234 |
print(f"All in all we have paid {total_charge} to network.")
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
|
| 238 |
-
|
| 239 |
-
|
| 240 |
|
| 241 |
results = pd.DataFrame({'soc_series': soc_series, 'consumption_from_solar': consumption_from_solar_series,
|
| 242 |
'consumption_from_network': consumption_from_network_series,
|
|
@@ -256,7 +271,7 @@ def main():
|
|
| 256 |
supplier.set_price_for_interval(9, 17, 150) # nine-to-five increased price.
|
| 257 |
# peak_demand dimension is kWh, but it's interpreted as the full consumption
|
| 258 |
# during a 15 minute timestep.
|
| 259 |
-
supplier.set_demand_charge(peak_demand=25, surcharge_per_kwh=
|
| 260 |
|
| 261 |
parameters = SolarParameters()
|
| 262 |
|
|
@@ -270,15 +285,16 @@ def main():
|
|
| 270 |
time_interval_h = time_interval_min / 60
|
| 271 |
battery_model = BatteryModel(capacity_Ah=600, time_interval_h=time_interval_h)
|
| 272 |
|
| 273 |
-
decider = Decider()
|
| 274 |
|
| 275 |
t = time.perf_counter()
|
| 276 |
results = simulator(battery_model, supplier, all_data_with_predictions, decider)
|
| 277 |
print("Simulation runtime", time.perf_counter() - t, "seconds.")
|
| 278 |
|
| 279 |
-
|
| 280 |
-
|
| 281 |
-
|
|
|
|
| 282 |
|
| 283 |
|
| 284 |
if __name__ == '__main__':
|
|
|
|
| 3 |
import copy
|
| 4 |
import time
|
| 5 |
from enum import IntEnum
|
| 6 |
+
import matplotlib.pyplot as plt
|
| 7 |
|
| 8 |
# it's really just a network pricing model
|
| 9 |
from supplier import Supplier
|
| 10 |
from data_processing import read_datasets, add_production_field, interpolate_and_join, SolarParameters
|
| 11 |
|
| 12 |
|
| 13 |
+
DO_VIS = False
|
| 14 |
+
|
| 15 |
STEPS_PER_HOUR = 12
|
| 16 |
|
| 17 |
|
|
|
|
| 98 |
# mock class as usual
|
| 99 |
# output_window_size is not yet used, always decides one timestep.
|
| 100 |
class Decider:
|
| 101 |
+
def __init__(self, supplier):
|
| 102 |
self.input_window_size = STEPS_PER_HOUR * 24 # day long window.
|
| 103 |
self.random_seed = 0
|
| 104 |
+
self.supplier = supplier
|
| 105 |
|
| 106 |
# prod_cons_pred is a dataframe starting at now, containing
|
| 107 |
# fields Production and Consumption.
|
|
|
|
| 109 |
# battery_model is just queried for capacity and current soc.
|
| 110 |
# the method returns a pd.Series of Decisions as integers.
|
| 111 |
def decide(self, prod_pred, cons_pred, battery_model):
|
| 112 |
+
return Decision.DISCHARGE
|
| 113 |
+
next_prod = prod_pred[0]
|
| 114 |
+
next_cons = cons_pred[0]
|
| 115 |
+
deficit = next_cons - next_prod
|
| 116 |
+
soc = battery_model.soc
|
| 117 |
+
if soc > 0.9:
|
| 118 |
+
return Decision.DISCHARGE
|
| 119 |
+
elif soc < 0.1 and OLCSO:
|
| 120 |
+
return Decision.PASSIVE
|
| 121 |
+
return
|
| 122 |
+
|
| 123 |
# assert len(prod_pred) == len(cons_pred) == self.input_window_size
|
| 124 |
self.random_seed += 1
|
| 125 |
self.random_seed %= 3 # dummy rotates between Decisions
|
|
|
|
| 247 |
consumption_from_network_pandas_series,
|
| 248 |
provide_detail=True)
|
| 249 |
print(f"All in all we have paid {total_charge} to network.")
|
| 250 |
+
|
| 251 |
+
if DO_VIS:
|
| 252 |
+
demand_charges.plot()
|
| 253 |
+
plt.title("demand_charges")
|
| 254 |
+
plt.show()
|
| 255 |
|
| 256 |
results = pd.DataFrame({'soc_series': soc_series, 'consumption_from_solar': consumption_from_solar_series,
|
| 257 |
'consumption_from_network': consumption_from_network_series,
|
|
|
|
| 271 |
supplier.set_price_for_interval(9, 17, 150) # nine-to-five increased price.
|
| 272 |
# peak_demand dimension is kWh, but it's interpreted as the full consumption
|
| 273 |
# during a 15 minute timestep.
|
| 274 |
+
supplier.set_demand_charge(peak_demand=25, surcharge_per_kwh=500) # kWh in a 15 minutes interval, Ft/kWh
|
| 275 |
|
| 276 |
parameters = SolarParameters()
|
| 277 |
|
|
|
|
| 285 |
time_interval_h = time_interval_min / 60
|
| 286 |
battery_model = BatteryModel(capacity_Ah=600, time_interval_h=time_interval_h)
|
| 287 |
|
| 288 |
+
decider = Decider(supplier)
|
| 289 |
|
| 290 |
t = time.perf_counter()
|
| 291 |
results = simulator(battery_model, supplier, all_data_with_predictions, decider)
|
| 292 |
print("Simulation runtime", time.perf_counter() - t, "seconds.")
|
| 293 |
|
| 294 |
+
if DO_VIS:
|
| 295 |
+
results['soc_series'].plot()
|
| 296 |
+
plt.title('soc_series')
|
| 297 |
+
plt.show()
|
| 298 |
|
| 299 |
|
| 300 |
if __name__ == '__main__':
|
v2/supplier.py
CHANGED
|
@@ -71,7 +71,7 @@ class Supplier:
|
|
| 71 |
time_steps_per_demand_charge_evaluation = 15 // demand_series.index.freq.n
|
| 72 |
# fifteen_minute_peaks [kW] tells the maximum demand in a 15 minutes timeframe:
|
| 73 |
fifteen_minute_demands_in_kwh = demand_series.resample('15T').sum() * step_in_hour
|
| 74 |
-
demand_charges = [self.demand_charge(demand_in_kwh) for demand_in_kwh in fifteen_minute_demands_in_kwh]
|
| 75 |
total_demand_charge = sum(demand_charges)
|
| 76 |
total_charge = consumption_charge + total_demand_charge
|
| 77 |
if provide_detail:
|
|
|
|
| 71 |
time_steps_per_demand_charge_evaluation = 15 // demand_series.index.freq.n
|
| 72 |
# fifteen_minute_peaks [kW] tells the maximum demand in a 15 minutes timeframe:
|
| 73 |
fifteen_minute_demands_in_kwh = demand_series.resample('15T').sum() * step_in_hour
|
| 74 |
+
demand_charges = pd.Series([self.demand_charge(demand_in_kwh) for demand_in_kwh in fifteen_minute_demands_in_kwh], index=fifteen_minute_demands_in_kwh.index)
|
| 75 |
total_demand_charge = sum(demand_charges)
|
| 76 |
total_charge = consumption_charge + total_demand_charge
|
| 77 |
if provide_detail:
|