Compare commits

..

4 Commits
0.0.6 ... main

Author SHA1 Message Date
Hanzhang ma
f1b2959143 add English comments 2024-05-17 10:48:07 +02:00
Hanzhang Ma
df2f953678 update the csv file output code and add a progress bar in the code 2024-05-16 21:12:13 +02:00
Hanzhang Ma
3740136d7c update the format 2024-05-15 15:06:43 +02:00
Hanzhang ma
e04e01e943 edit read_data.py to accept changeable data 2024-05-13 22:22:03 +02:00
7 changed files with 618 additions and 126 deletions

View File

@ -21,6 +21,13 @@ class EnergySystem:
self.summer_week_soc = [] self.summer_week_soc = []
self.autumn_week_soc = [] self.autumn_week_soc = []
self.winter_week_soc = [] self.winter_week_soc = []
self.factory_demand = []
self.buy_price_kWh = []
self.sell_price_kWh = []
self.pv_generated_kWh = []
self.grid_need_power_kW = []
self.time = []
self.ess_rest = 0
self.granularity = 4 self.granularity = 4
self.season_step = self.granularity * 24 * 7 * 12 self.season_step = self.granularity * 24 * 7 * 12
self.season_start= self.granularity * 24 * 7 * 2 self.season_start= self.granularity * 24 * 7 * 2
@ -30,15 +37,32 @@ class EnergySystem:
def get_cost(self): def get_cost(self):
return self.ess.get_cost()+self.pv.get_cost() return self.ess.get_cost()+self.pv.get_cost()
# 优先使用PV供电给工厂 - 如果PV输出能满足工厂的需求则直接供电多余的电能用来给ESS充电。
# PV不足时使用ESS补充 - 如果PV输出不足以满足工厂需求首先从ESS获取所需电量。
# 如果ESS也不足以满足需求再从电网获取 - 当ESS中的存储电量也不足以补充时再从电网购买剩余所需电量。
def simulate(self, data, time_interval): def simulate(self, data, time_interval):
"""
The program will use the PV to supply the factory first. If the PV output can meet the factory's demand, it will be directly powered, and the excess electrical energy will be used to charge the ESS. Program will use the PV to supply the Ess.
When the PV is insufficient, the ESS is used to supplement. If the PV output is not enough to meet the factory's demand, the required power is first obtained from the ESS.
If the ESS is also insufficient to meet the demand, it will be obtained from the grid. When the stored power in the ESS is also insufficient to supplement, the remaining required power will be purchased from the grid.
Args:
data: pandas.DataFrame
The data that contains the factory's demand, PV output, and electricity price.
time_interval: float
The time interval of the data in hours.
Returns:
tuple
The total benefit, total netto benefit, and total generated energy.
"""
total_benefit = 0 total_benefit = 0
total_netto_benefit = 0 total_netto_benefit = 0
total_gen = 0 total_gen = 0
net_grid = 0.
for index, row in data.iterrows(): for index, row in data.iterrows():
time = row['time'] time = row['time']
self.time.append(time)
# sunlight_intensity = row['sunlight'] # sunlight_intensity = row['sunlight']
pv_yield = row['PV yield[kW/kWp]'] pv_yield = row['PV yield[kW/kWp]']
factory_demand = row['demand'] factory_demand = row['demand']
@ -46,100 +70,122 @@ class EnergySystem:
sell_price = row['sell'] sell_price = row['sell']
# electricity_price = self.grid.get_price_for_time(time) # electricity_price = self.grid.get_price_for_time(time)
if time == '00:00': # if time == '00:00':
self.day_generated.append(self.generated) # self.day_generated.append(self.generated)
self.generated = 0 # self.generated = 0
if time.endswith('14:00'): # if time.endswith('14:00'):
soc = self.ess.storage / self.ess.capacity # soc = self.ess.storage / self.ess.capacity
self.hour_stored.append(soc) # self.hour_stored.append(soc)
if time.endswith('08:00'): # if time.endswith('08:00'):
soc = self.ess.storage / self.ess.capacity # soc = self.ess.storage / self.ess.capacity
self.hour_stored_2.append(soc) # self.hour_stored_2.append(soc)
# `generated_pv_power`: the power generated by the PV in kW
# `generated_pv_energy`: the energy generated by the PV in kWh
generated_pv_power = self.pv.capacity * pv_yield
generated_pv_energy = generated_pv_power * time_interval * self.pv.loss
self.pv_generated_kWh.append(generated_pv_energy)
self.factory_demand.append(factory_demand)
self.buy_price_kWh.append(electricity_price)
self.sell_price_kWh.append(sell_price)
generated_pv_power = self.pv.capacity * pv_yield# 生成的功率,单位 kW
generated_pv_energy = generated_pv_power * time_interval * self.pv.loss # 生成的能量,单位 kWh
self.generated += generated_pv_energy self.generated += generated_pv_energy
# pv生成的能量如果比工厂的需求要大 # generated_pv_energy is larger than factory_demand energy
if generated_pv_energy >= factory_demand * time_interval: if generated_pv_energy >= factory_demand * time_interval:
# 剩余的能量(kwh) = pv生成的能量 - 工厂需求的功率 * 时间间隔 """
That means the generated energy is enough to power the factory.
The surplus energy will be used to charge the ESS.
surplus_energy: The energy that is left after powering the factory.
formula: generated_pv_energy - factory_demand * time_interval
charge_to_ess: The energy that will be charged to the ESS.
formula: min(surplus_energy, ess.charge_power * time_interval, ess.capacity - ess.storage)
surplus_after_ess: The energy that is left after charging the ESS.
"""
surplus_energy = generated_pv_energy - factory_demand * time_interval surplus_energy = generated_pv_energy - factory_demand * time_interval
# 要充到ess中的能量 = min(剩余的能量,ess的充电功率*时间间隔(ess在时间间隔内能充进的电量),ess的容量-ess储存的能量(ess中能冲进去的电量))
charge_to_ess = min(surplus_energy, self.ess.charge_power * time_interval, self.ess.capacity - self.ess.storage) charge_to_ess = min(surplus_energy, self.ess.charge_power * time_interval, self.ess.capacity - self.ess.storage)
self.ess.storage += charge_to_ess self.ess.storage += charge_to_ess
surplus_after_ess = surplus_energy - charge_to_ess surplus_after_ess = surplus_energy - charge_to_ess
# 如果还有电量盈余,且pv功率大于ess的充电功率+工厂的需求功率则准备卖电 """
If there is still surplus energy after charging the ESS, and the generated PV power is greater than the sum of the ESS's charge power and the factory's demand power, the surplus energy will be sold to the grid.
"""
if surplus_after_ess > 0 and generated_pv_power > self.ess.charge_power + factory_demand: if surplus_after_ess > 0 and generated_pv_power > self.ess.charge_power + factory_demand:
sold_to_grid = surplus_after_ess sold_to_grid = surplus_after_ess
sell_income = sold_to_grid * sell_price sell_income = sold_to_grid * sell_price
total_benefit += sell_income total_benefit += sell_income
# 节省的能量 = 工厂需求的能量 * 时间段 """
# total_energy = factory_demand * time_interval Saved energy is the energy that is saved by using the PV to power the factory.
"""
saved_energy = factory_demand * time_interval saved_energy = factory_demand * time_interval
# pv比工厂的需求小 self.grid_need_power_kW.append(0)
else: else:
# 从ess中需要的电量 = 工厂需要的电量 - pv中的电量 """
If the generated energy is not enough to power the factory, the ESS will be used to supplement the energy.
needed_from_ess: The energy that is needed from the ESS to power the factory.
formula: factory_demand * time_interval - generated_pv_energy
"""
needed_from_ess = factory_demand * time_interval - generated_pv_energy needed_from_ess = factory_demand * time_interval - generated_pv_energy
# 如果ess中存的电量比需要的多 """
If the ESS has enough stored energy to power the factory, the energy will be taken from the ESS.
"""
if self.ess.storage * self.ess.loss >= needed_from_ess: if self.ess.storage * self.ess.loss >= needed_from_ess:
# 取出电量
if self.ess.discharge_power * time_interval * self.ess.loss < needed_from_ess: if self.ess.discharge_power * time_interval * self.ess.loss < needed_from_ess:
discharging_power = self.ess.discharge_power * time_interval discharging_power = self.ess.discharge_power * time_interval
else: else:
discharging_power = needed_from_ess / self.ess.loss discharging_power = needed_from_ess / self.ess.loss
self.ess.storage -= discharging_power self.ess.storage -= discharging_power
# 节省下来的能量 = pv的能量 + 放出来的能量 """
In this case, the energy that is needed from the grid is 0.
"""
saved_energy = generated_pv_energy + discharging_power * self.ess.loss saved_energy = generated_pv_energy + discharging_power * self.ess.loss
self.grid_need_power_kW.append(0)
else: else:
# 如果存的电量不够 """
# 需要把ess中的所有电量释放出来 If the ESS does not have enough stored energy to power the factory, the energy will be taken from the grid.
"""
if self.grid.capacity * time_interval + generated_pv_energy + self.ess.storage * self.ess.loss < factory_demand * time_interval: if self.grid.capacity * time_interval + generated_pv_energy + self.ess.storage * self.ess.loss < factory_demand * time_interval:
self.afford = False self.afford = False
self.overload_cnt+=1 self.overload_cnt+=1
log = f"index: {index}, time: {time}, SoC:{self.ess.storage / self.ess.capacity}%, storage: {self.ess.storage}, pv_gen:{generated_pv_power}, power_demand: {factory_demand}, overload_cnt:{self.overload_cnt}, day:{int(index/96) + 1}"
self.unmet.append((index,time,factory_demand,generated_pv_power)) self.unmet.append((index,time,factory_demand,generated_pv_power))
# with open(f'plots/summary/ess-{self.ess.capacity}-pv-{self.pv.capacity}', 'a') as f:
# f.write(log)
# print(log)
# self.unmet.append(log)
saved_energy = generated_pv_energy + self.ess.storage * self.ess.loss saved_energy = generated_pv_energy + self.ess.storage * self.ess.loss
self.ess.storage = 0 self.ess.storage = 0
needed_from_grid = factory_demand * time_interval - saved_energy needed_from_grid = factory_demand * time_interval - saved_energy
net_grid = min(self.grid.capacity * time_interval, needed_from_grid) * self.grid.loss net_grid = min(self.grid.capacity * time_interval, needed_from_grid) * self.grid.loss
# grid_energy += net_grid self.grid_need_power_kW.append(needed_from_grid * 4)
# total_energy += net_grid
# print(total_energy)
# 工厂需求量-总能量
# unmet_demand = max(0, factory_demand * time_interval - total_energy)
# benefit = (total_energy - unmet_demand) * electricity_price
total_gen += saved_energy total_gen += saved_energy
benefit = (saved_energy) * electricity_price benefit = (saved_energy) * electricity_price
cost = net_grid * electricity_price cost = net_grid * electricity_price
# print(f"time:{time} benefit: {benefit}, cost: {cost}")
total_netto_benefit += benefit total_netto_benefit += benefit
total_benefit += benefit - cost total_benefit += benefit - cost
# # spring print_season_flag = False
week_start = self.season_start if print_season_flag == True:
week_end = self.week_length + week_start week_start = self.season_start
if index in range(week_start, week_end): week_end = self.week_length + week_start
self.spring_week_gen.append(generated_pv_power) if index in range(week_start, week_end):
self.spring_week_soc.append(self.ess.storage / self.ess.capacity) self.spring_week_gen.append(generated_pv_power)
# summer self.spring_week_soc.append(self.ess.storage / self.ess.capacity)
# week_start += self.season_step self.ess_rest = self.ess.storage
# week_end += self.season_step # summer
# if index in range(week_start, week_end): week_start += self.season_step
# self.summer_week_gen.append(generated_pv_power) week_end += self.season_step
# self.summer_week_soc.append(self.ess.storage / self.ess.capacity) if index in range(week_start, week_end):
# # autumn self.summer_week_gen.append(generated_pv_power)
# week_start += self.season_step self.summer_week_soc.append(self.ess.storage / self.ess.capacity)
# week_end += self.season_step # # autumn
# if index in range(week_start, week_end): week_start += self.season_step
# self.autumn_week_gen.append(generated_pv_power) week_end += self.season_step
# self.autumn_week_soc.append(self.ess.storage / self.ess.capacity) if index in range(week_start, week_end):
# week_start += self.season_step self.autumn_week_gen.append(generated_pv_power)
# week_end += self.season_step self.autumn_week_soc.append(self.ess.storage / self.ess.capacity)
# if index in range(week_start, week_end): week_start += self.season_step
# self.winter_week_gen.append(generated_pv_power) week_end += self.season_step
# self.winter_week_soc.append(self.ess.storage / self.ess.capacity) if index in range(week_start, week_end):
self.winter_week_gen.append(generated_pv_power)
self.winter_week_soc.append(self.ess.storage / self.ess.capacity)
return (total_benefit, total_netto_benefit, total_gen) return (total_benefit, total_netto_benefit, total_gen)

View File

@ -17,12 +17,12 @@
"pv_capacities":{ "pv_capacities":{
"begin": 0, "begin": 0,
"end": 50000, "end": 50000,
"groups": 11 "groups": 3
}, },
"ess_capacities":{ "ess_capacities":{
"begin": 0, "begin": 0,
"end": 100000, "end": 100000,
"groups": 11 "groups": 3
}, },
"time_interval":{ "time_interval":{
"numerator": 15, "numerator": 15,
@ -43,5 +43,11 @@
"cost": "Costs of Microgrid system [m-EUR]", "cost": "Costs of Microgrid system [m-EUR]",
"benefit": "Financial Profit Based on Py & Ess Configuration (k-EUR / year)", "benefit": "Financial Profit Based on Py & Ess Configuration (k-EUR / year)",
"roi": "ROI" "roi": "ROI"
},
"data_path": {
"pv_yield": "read_data/Serbia.csv",
"demand": "read_data/factory_power1.csv",
"sell": "read_data/electricity_price_data_sell.csv",
"buy": "read_data/electricity_price_data.csv"
} }
} }

View File

@ -10,12 +10,12 @@ class pv_config:
def get_cost_per_year(self): def get_cost_per_year(self):
return self.capacity * self.cost_per_kW / self.lifetime return self.capacity * self.cost_per_kW / self.lifetime
class ess_config: class ess_config:
def __init__(self, capacity, cost_per_kW, lifetime, loss, charge_power, discharge_power): def __init__(self, capacity, cost_per_kW, lifetime, loss, charge_power, discharge_power, storage=0):
self.capacity = capacity self.capacity = capacity
self.cost_per_kW = cost_per_kW self.cost_per_kW = cost_per_kW
self.lifetime = lifetime self.lifetime = lifetime
self.loss = loss self.loss = loss
self.storage = 0 self.storage = storage
self.charge_power = charge_power self.charge_power = charge_power
self.discharge_power = discharge_power self.discharge_power = discharge_power
def get_cost(self): def get_cost(self):

BIN
main.exe

Binary file not shown.

File diff suppressed because one or more lines are too long

189
main.py
View File

@ -1,5 +1,9 @@
#!/usr/bin/env python #!/usr/bin/env python
# coding: utf-8 # coding: utf-8
# In[83]:
import os import os
import glob import glob
import shutil import shutil
@ -24,6 +28,9 @@ folder_path = 'plots'
clear_folder_make_ess_pv(folder_path) clear_folder_make_ess_pv(folder_path)
# In[84]:
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import seaborn as sns import seaborn as sns
import numpy as np import numpy as np
@ -31,15 +38,22 @@ import pandas as pd
from EnergySystem import EnergySystem from EnergySystem import EnergySystem
from config import pv_config, grid_config, ess_config from config import pv_config, grid_config, ess_config
# In[85]:
import json import json
print("Version 0.0.5") print("Version 0.0.7\n")
with open('config.json', 'r') as f: with open('config.json', 'r') as f:
js_data = json.load(f) js_data = json.load(f)
time_interval = js_data["time_interval"]["numerator"] / js_data["time_interval"]["denominator"] time_interval = js_data["time_interval"]["numerator"] / js_data["time_interval"]["denominator"]
print(time_interval) # print(time_interval)
pv_loss = js_data["pv"]["loss"] pv_loss = js_data["pv"]["loss"]
pv_cost_per_kW = js_data["pv"]["cost_per_kW"] pv_cost_per_kW = js_data["pv"]["cost_per_kW"]
@ -102,7 +116,7 @@ ess_capacities = np.linspace(ess_begin, ess_end, ess_groups)
# overload_cnt = pd.DataFrame(index=pv_capacities, columns= ess_capacities) # overload_cnt = pd.DataFrame(index=pv_capacities, columns= ess_capacities)
# In[ ]: # In[86]:
hour_demand = [] hour_demand = []
@ -118,6 +132,9 @@ plt.savefig('plots/demand.png')
plt.close() plt.close()
# In[87]:
def draw_results(results, filename, title_benefit, annot_benefit=False, figure_size=(10, 10)): def draw_results(results, filename, title_benefit, annot_benefit=False, figure_size=(10, 10)):
df=results df=results
df = df.astype(float) df = df.astype(float)
@ -154,7 +171,7 @@ def draw_results(results, filename, title_benefit, annot_benefit=False, figure_s
plt.savefig(filename) plt.savefig(filename)
# In[ ]: # In[88]:
def draw_roi(costs, results, filename, title_roi, days=365, annot_roi=False, figure_size=(10, 10)): def draw_roi(costs, results, filename, title_roi, days=365, annot_roi=False, figure_size=(10, 10)):
@ -167,7 +184,7 @@ def draw_roi(costs, results, filename, title_roi, days=365, annot_roi=False, fig
if 0 in df.index and 0 in df.columns: if 0 in df.index and 0 in df.columns:
df.loc[0,0] = 100 df.loc[0,0] = 100
df[df > 80] = 100 df[df > 80] = 100
print(df) # print(df)
df = df.astype(float) df = df.astype(float)
df.index = df.index / 1000 df.index = df.index / 1000
@ -176,7 +193,7 @@ def draw_roi(costs, results, filename, title_roi, days=365, annot_roi=False, fig
df.columns = df.columns.map(int) df.columns = df.columns.map(int)
min_value = df.min().min() min_value = df.min().min()
max_value = df.max().max() max_value = df.max().max()
print(max_value) # print(max_value)
max_scale = max(abs(min_value), abs(max_value)) max_scale = max(abs(min_value), abs(max_value))
df[df.columns[-1] + 1] = df.iloc[:, -1] df[df.columns[-1] + 1] = df.iloc[:, -1]
@ -202,6 +219,11 @@ def draw_roi(costs, results, filename, title_roi, days=365, annot_roi=False, fig
plt.xlabel('ESS Capacity (MWh)') plt.xlabel('ESS Capacity (MWh)')
plt.ylabel('PV Capacity (MW)') plt.ylabel('PV Capacity (MW)')
plt.savefig(filename) plt.savefig(filename)
plt.close()
# In[89]:
def draw_cost(costs, filename, title_cost, annot_cost=False, figure_size=(10, 10)): def draw_cost(costs, filename, title_cost, annot_cost=False, figure_size=(10, 10)):
df = costs df = costs
@ -232,16 +254,20 @@ def draw_cost(costs, filename, title_cost, annot_cost=False, figure_size=(10, 10
plt.xlabel('ESS Capacity (MWh)') plt.xlabel('ESS Capacity (MWh)')
plt.ylabel('PV Capacity (MW)') plt.ylabel('PV Capacity (MW)')
plt.savefig(filename) plt.savefig(filename)
plt.close()
# In[90]:
def draw_overload(overload_cnt, filename, title_unmet, annot_unmet=False, figure_size=(10, 10), days=365, granularity=15): def draw_overload(overload_cnt, filename, title_unmet, annot_unmet=False, figure_size=(10, 10), days=365, granularity=15):
df = overload_cnt df = overload_cnt
print(days, granularity) # print(days, granularity)
coef = 60 / granularity * days * 24 coef = 60 / granularity * days * 24
print(coef) # print(coef)
print(df) # print(df)
df = ( coef - df) / coef df = ( coef - df) / coef
print(df) # print(df)
df = df.astype(float) df = df.astype(float)
df.index = df.index / 1000 df.index = df.index / 1000
@ -280,12 +306,21 @@ def draw_overload(overload_cnt, filename, title_unmet, annot_unmet=False, figure
plt.xlabel('ESS Capacity (MWh)') plt.xlabel('ESS Capacity (MWh)')
plt.ylabel('PV Capacity (MW)') plt.ylabel('PV Capacity (MW)')
plt.savefig(filename) plt.savefig(filename)
plt.close()
# In[91]:
def cal_profit(es: EnergySystem, saved_money, days): def cal_profit(es: EnergySystem, saved_money, days):
profit = saved_money - es.ess.get_cost_per_year() / 365 * days - es.pv.get_cost_per_year() / 365 * days profit = saved_money - es.ess.get_cost_per_year() / 365 * days - es.pv.get_cost_per_year() / 365 * days
return profit return profit
def generate_data(pv_capacity, pv_cost_per_kW, pv_lifetime, pv_loss, ess_capacity, ess_cost_per_kW, ess_lifetime, ess_loss, grid_capacity, grid_loss, sell_price, time_interval, data, days):
# In[92]:
def generate_data(pv_capacity, pv_cost_per_kW, pv_lifetime, pv_loss, ess_capacity, ess_cost_per_kW, ess_lifetime, ess_loss, grid_capacity, grid_loss, sell_price, time_interval, data, days, storage=0):
pv = pv_config(capacity=pv_capacity, pv = pv_config(capacity=pv_capacity,
cost_per_kW=pv_cost_per_kW, cost_per_kW=pv_cost_per_kW,
lifetime=pv_lifetime, lifetime=pv_lifetime,
@ -295,7 +330,8 @@ def generate_data(pv_capacity, pv_cost_per_kW, pv_lifetime, pv_loss, ess_capacit
lifetime=ess_lifetime, lifetime=ess_lifetime,
loss=ess_loss, loss=ess_loss,
charge_power=ess_capacity, charge_power=ess_capacity,
discharge_power=ess_capacity) discharge_power=ess_capacity,
storage=storage)
grid = grid_config(capacity=grid_capacity, grid = grid_config(capacity=grid_capacity,
grid_loss=grid_loss, grid_loss=grid_loss,
sell_price= sell_price) sell_price= sell_price)
@ -306,31 +342,96 @@ def generate_data(pv_capacity, pv_cost_per_kW, pv_lifetime, pv_loss, ess_capacit
results = cal_profit(energySystem, benefit, days) results = cal_profit(energySystem, benefit, days)
overload_cnt = energySystem.overload_cnt overload_cnt = energySystem.overload_cnt
costs = energySystem.ess.capacity * energySystem.ess.cost_per_kW + energySystem.pv.capacity * energySystem.pv.cost_per_kW costs = energySystem.ess.capacity * energySystem.ess.cost_per_kW + energySystem.pv.capacity * energySystem.pv.cost_per_kW
return (results, overload_cnt, costs, netto_benefit, gen_energy, energySystem.generated) return (results,
overload_cnt,
costs,
netto_benefit,
gen_energy,
energySystem.generated,
energySystem.ess_rest,
energySystem.factory_demand,
energySystem.buy_price_kWh,
energySystem.sell_price_kWh,
energySystem.pv_generated_kWh,
energySystem.grid_need_power_kW,
energySystem.time)
# In[93]:
from tqdm import tqdm
months_results = [] months_results = []
months_costs = [] months_costs = []
months_overload = [] months_overload = []
months_nettos = [] months_nettos = []
months_gen_energy = [] months_gen_energy = []
months_gen_energy2 = [] months_gen_energy2 = []
for index, month_data in enumerate(months_data): months_ess_rest = pd.DataFrame(30, index=pv_capacities, columns= ess_capacities)
months_csv_data = {}
for index, month_data in tqdm(enumerate(months_data), total=len(months_data), position=0, leave= True):
results = pd.DataFrame(index=pv_capacities, columns= ess_capacities) results = pd.DataFrame(index=pv_capacities, columns= ess_capacities)
costs = pd.DataFrame(index=pv_capacities, columns= ess_capacities) costs = pd.DataFrame(index=pv_capacities, columns= ess_capacities)
overload_cnt = pd.DataFrame(index=pv_capacities, columns= ess_capacities) overload_cnt = pd.DataFrame(index=pv_capacities, columns= ess_capacities)
nettos = pd.DataFrame(index=pv_capacities, columns= ess_capacities) nettos = pd.DataFrame(index=pv_capacities, columns= ess_capacities)
gen_energies = pd.DataFrame(index=pv_capacities, columns= ess_capacities) gen_energies = pd.DataFrame(index=pv_capacities, columns= ess_capacities)
gen_energies2 = pd.DataFrame(index=pv_capacities, columns= ess_capacities) gen_energies2 = pd.DataFrame(index=pv_capacities, columns= ess_capacities)
for pv_capacity in pv_capacities: factory_demands = {}
buy_prices= {}
sell_prices = {}
pv_generates = {}
grid_need_powers = {}
times = {}
for pv_capacity in tqdm(pv_capacities, total=len(pv_capacities), desc=f'generating pv for month {index + 1}',position=1, leave=False):
factory_demands[pv_capacity] = {}
buy_prices[pv_capacity] = {}
sell_prices[pv_capacity] = {}
pv_generates[pv_capacity] = {}
grid_need_powers[pv_capacity] = {}
times[pv_capacity] = {}
for ess_capacity in ess_capacities: for ess_capacity in ess_capacities:
(result, overload, cost, netto, gen_energy, gen_energy2) = generate_data(pv_capacity=pv_capacity,pv_cost_per_kW=pv_cost_per_kW, pv_lifetime=pv_lifetime, pv_loss=pv_loss, ess_capacity=ess_capacity, ess_cost_per_kW=ess_cost_per_kW, ess_lifetime=ess_lifetime, ess_loss=ess_loss, grid_capacity=grid_capacity, grid_loss=grid_loss, sell_price=sell_price, time_interval=time_interval, data=month_data, days=months_days[index]) (result,
overload,
cost,
netto,
gen_energy,
gen_energy2,
ess_rest,
factory_demand,
buy_price,
sell_price,
pv_generate,
grid_need_power,
time) = generate_data(pv_capacity=pv_capacity,
pv_cost_per_kW=pv_cost_per_kW,
pv_lifetime=pv_lifetime,
pv_loss=pv_loss,
ess_capacity=ess_capacity,
ess_cost_per_kW=ess_cost_per_kW,
ess_lifetime=ess_lifetime,
ess_loss=ess_loss,
grid_capacity=grid_capacity,
grid_loss=grid_loss,
sell_price=sell_price,
time_interval=time_interval,
data=month_data,
days=months_days[index],
storage=months_ess_rest.loc[pv_capacity, ess_capacity])
results.loc[pv_capacity,ess_capacity] = result results.loc[pv_capacity,ess_capacity] = result
overload_cnt.loc[pv_capacity,ess_capacity] = overload overload_cnt.loc[pv_capacity,ess_capacity] = overload
costs.loc[pv_capacity,ess_capacity] = cost costs.loc[pv_capacity,ess_capacity] = cost
nettos.loc[pv_capacity,ess_capacity] = netto nettos.loc[pv_capacity,ess_capacity] = netto
gen_energies.loc[pv_capacity, ess_capacity] = gen_energy gen_energies.loc[pv_capacity, ess_capacity] = gen_energy
gen_energies2.loc[pv_capacity, ess_capacity] = gen_energy2 gen_energies2.loc[pv_capacity, ess_capacity] = gen_energy2
months_ess_rest.loc[pv_capacity, ess_capacity] = ess_rest
factory_demands[pv_capacity][ess_capacity] = factory_demand
buy_prices[pv_capacity][ess_capacity] = buy_price
sell_prices[pv_capacity][ess_capacity] = sell_price
pv_generates[pv_capacity][ess_capacity] = pv_generate
grid_need_powers[pv_capacity][ess_capacity] = grid_need_power
times[pv_capacity][ess_capacity] = time
months_csv_data[index] = {"factory_demand": factory_demands, "buy_price": buy_prices, "sell_price": sell_prices, "pv_generate": pv_generates, "grid_need_power": grid_need_powers, "time": times}
months_results.append(results) months_results.append(results)
months_costs.append(costs) months_costs.append(costs)
months_overload.append(overload_cnt) months_overload.append(overload_cnt)
@ -349,7 +450,6 @@ for index, month_data in enumerate(months_data):
figure_size=figure_size, figure_size=figure_size,
days=months_days[index], days=months_days[index],
granularity=granularity) granularity=granularity)
annual_result = pd.DataFrame(index=pv_capacities, columns= ess_capacities) annual_result = pd.DataFrame(index=pv_capacities, columns= ess_capacities)
annual_costs = pd.DataFrame(index=pv_capacities, columns= ess_capacities) annual_costs = pd.DataFrame(index=pv_capacities, columns= ess_capacities)
annual_overload = pd.DataFrame(index=pv_capacities, columns= ess_capacities) annual_overload = pd.DataFrame(index=pv_capacities, columns= ess_capacities)
@ -358,7 +458,6 @@ annual_gen = pd.DataFrame(index=pv_capacities, columns= ess_capacities)
annual_gen2 = pd.DataFrame(index=pv_capacities, columns= ess_capacities) annual_gen2 = pd.DataFrame(index=pv_capacities, columns= ess_capacities)
# get the yearly results # get the yearly results
for pv_capacity in pv_capacities: for pv_capacity in pv_capacities:
for ess_capacity in ess_capacities: for ess_capacity in ess_capacities:
@ -399,11 +498,58 @@ draw_overload(overload_cnt=annual_overload,
figure_size=figure_size) figure_size=figure_size)
# In[94]:
def collapse_months_csv_data(months_csv_data, column_name,pv_capacies, ess_capacities):
data = {}
for pv_capacity in pv_capacities:
data[pv_capacity] = {}
for ess_capacity in ess_capacities:
annual_data = []
for index, month_data in enumerate(months_data):
annual_data.extend(months_csv_data[index][column_name][pv_capacity][ess_capacity])
# months_csv_data[index][column_name][pv_capacity][ess_capacity] = months_csv_data[index][column_name][pv_capacity][ess_capacity].tolist()
data[pv_capacity][ess_capacity] = annual_data
return data
# In[102]:
annual_pv_gen = collapse_months_csv_data(months_csv_data, "pv_generate", pv_capacities, ess_capacities)
annual_time = collapse_months_csv_data(months_csv_data, "time", pv_capacities, ess_capacities)
annual_buy_price = collapse_months_csv_data(months_csv_data, "buy_price",pv_capacities, ess_capacities)
annual_sell_price = collapse_months_csv_data(months_csv_data, "sell_price", pv_capacities, ess_capacities)
annual_factory_demand = collapse_months_csv_data(months_csv_data, "factory_demand", pv_capacities, ess_capacities)
annual_grid_need_power = collapse_months_csv_data(months_csv_data, "grid_need_power", pv_capacities, ess_capacities)
from datetime import datetime, timedelta
for pv_capacity in pv_capacities:
for ess_capacity in ess_capacities:
with open(f'data/annual_data-pv-{pv_capacity}-ess-{ess_capacity}.csv', 'w') as f:
f.write("date, time,pv_generate (kW),factory_demand (kW),buy_price (USD/MWh),sell_price (USD/MWh),grid_need_power (kW)\n")
start_date = datetime(2023, 1, 1, 0, 0, 0)
for i in range(len(annual_time[pv_capacity][ess_capacity])):
current_date = start_date + timedelta(hours=i)
formate_date = current_date.strftime("%Y-%m-%d")
f.write(f"{formate_date},{annual_time[pv_capacity][ess_capacity][i]},{int(annual_pv_gen[pv_capacity][ess_capacity][i])},{int(annual_factory_demand[pv_capacity][ess_capacity][i])},{int(annual_buy_price[pv_capacity][ess_capacity][i]*1000)},{int(annual_sell_price[pv_capacity][ess_capacity][i]*1000)},{int(annual_grid_need_power[pv_capacity][ess_capacity][i])} \n")
# In[96]:
def save_data(data, filename): def save_data(data, filename):
data.to_csv(filename+'.csv') data.to_csv(filename+'.csv')
data.to_json(filename + '.json') data.to_json(filename + '.json')
# In[97]:
if not os.path.isdir('data'): if not os.path.isdir('data'):
os.makedirs('data') os.makedirs('data')
@ -411,8 +557,15 @@ save_data(annual_result, f'data/{pv_begin}-{pv_end}-{pv_groups}-{ess_begin}-{ess
save_data(annual_costs, f'data/{pv_begin}-{pv_end}-{pv_groups}-{ess_begin}-{ess_end}-{ess_groups}-costs') save_data(annual_costs, f'data/{pv_begin}-{pv_end}-{pv_groups}-{ess_begin}-{ess_end}-{ess_groups}-costs')
save_data(annual_overload, f'data/{pv_begin}-{pv_end}-{pv_groups}-{ess_begin}-{ess_end}-{ess_groups}-overload_cnt') save_data(annual_overload, f'data/{pv_begin}-{pv_end}-{pv_groups}-{ess_begin}-{ess_end}-{ess_groups}-overload_cnt')
# In[98]:
draw_results(annual_result, 'plots/test.png', 'test', False) draw_results(annual_result, 'plots/test.png', 'test', False)
# In[99]:
draw_roi(annual_costs, annual_nettos, 'plots/annual_roi.png', title_roi, 365, annot_benefit, figure_size) draw_roi(annual_costs, annual_nettos, 'plots/annual_roi.png', title_roi, 365, annot_benefit, figure_size)

View File

@ -1,17 +1,25 @@
import pandas as pd import pandas as pd
import numpy as np import numpy as np
import csv import csv
import json
pv_yield_file_name = 'read_data/Serbia.csv' with open('config.json', 'r') as f:
js_data = json.load(f)
pv_yield_file_name = js_data["data_path"]["pv_yield"]
print(pv_yield_file_name)
# factory_demand_file_name = 'factory_power1.xlsx' # factory_demand_file_name = 'factory_power1.xlsx'
factory_demand_file_name = 'read_data/factory_power1.csv' factory_demand_file_name = js_data["data_path"]["demand"]
electricity_price_data = 'read_data/electricity_price_data.csv' print(factory_demand_file_name)
electricity_price_data_sell = 'read_data/electricity_price_data_sell.csv' electricity_price_data = js_data["data_path"]["buy"]
print(electricity_price_data)
electricity_price_data_sell = js_data["data_path"]["sell"]
print(electricity_price_data_sell)
pv_df = pd.read_csv(pv_yield_file_name, index_col='Time', usecols=['Time', 'PV yield[kW/kWp]']) pv_df = pd.read_csv(pv_yield_file_name, index_col='Time', usecols=['Time', 'PV yield[kW/kWp]'])
pv_df.index = pd.to_datetime(pv_df.index) pv_df.index = pd.to_datetime(pv_df.index)
df_power = pd.read_csv('factory_power1.csv', index_col='Time', usecols=['Time', 'FactoryPower']) df_power = pd.read_csv(factory_demand_file_name, index_col='Time', usecols=['Time', 'FactoryPower'])
df_power.index = pd.to_datetime(df_power.index) df_power.index = pd.to_datetime(df_power.index)
df_combined = pv_df.join(df_power) df_combined = pv_df.join(df_power)