Compare commits

...

7 Commits

Author SHA1 Message Date
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
Hanzhang Ma
9f472b4bf4 add city data 2024-05-13 17:00:59 +02:00
Hanzhang Ma
127f005dcd add city data 2024-05-13 16:59:12 +02:00
Hanzhang Ma
c5edf456c5 move some data to the folder 2024-05-13 16:54:20 +02:00
Hanzhang Ma
d8ece46e14 add city data 2024-05-13 16:52:43 +02:00
16 changed files with 175741 additions and 68 deletions

View File

@@ -21,6 +21,13 @@ class EnergySystem:
self.summer_week_soc = []
self.autumn_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.season_step = self.granularity * 24 * 7 * 12
self.season_start= self.granularity * 24 * 7 * 2
@@ -37,8 +44,10 @@ class EnergySystem:
total_benefit = 0
total_netto_benefit = 0
total_gen = 0
net_grid = 0.
for index, row in data.iterrows():
time = row['time']
self.time.append(time)
# sunlight_intensity = row['sunlight']
pv_yield = row['PV yield[kW/kWp]']
factory_demand = row['demand']
@@ -58,6 +67,11 @@ class EnergySystem:
generated_pv_power = self.pv.capacity * pv_yield# 生成的功率,单位 kW
generated_pv_energy = generated_pv_power * time_interval * self.pv.loss # 生成的能量,单位 kWh
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)
self.generated += generated_pv_energy
# pv生成的能量如果比工厂的需求要大
if generated_pv_energy >= factory_demand * time_interval:
@@ -75,6 +89,7 @@ class EnergySystem:
# 节省的能量 = 工厂需求的能量 * 时间段
# total_energy = factory_demand * time_interval
saved_energy = factory_demand * time_interval
self.grid_need_power_kW.append(0)
# pv比工厂的需求小
else:
# 从ess中需要的电量 = 工厂需要的电量 - pv中的电量
@@ -90,6 +105,7 @@ class EnergySystem:
self.ess.storage -= discharging_power
# 节省下来的能量 = pv的能量 + 放出来的能量
saved_energy = generated_pv_energy + discharging_power * self.ess.loss
self.grid_need_power_kW.append(0)
else:
# 如果存的电量不够
# 需要把ess中的所有电量释放出来
@@ -106,6 +122,7 @@ class EnergySystem:
self.ess.storage = 0
needed_from_grid = factory_demand * time_interval - saved_energy
net_grid = min(self.grid.capacity * time_interval, needed_from_grid) * self.grid.loss
self.grid_need_power_kW.append(needed_from_grid * 4)
# grid_energy += net_grid
# total_energy += net_grid
# print(total_energy)
@@ -124,6 +141,7 @@ class EnergySystem:
if index in range(week_start, week_end):
self.spring_week_gen.append(generated_pv_power)
self.spring_week_soc.append(self.ess.storage / self.ess.capacity)
self.ess_rest = self.ess.storage
# summer
# week_start += self.season_step
# week_end += self.season_step

View File

@@ -17,12 +17,12 @@
"pv_capacities":{
"begin": 0,
"end": 50000,
"groups": 11
"groups": 3
},
"ess_capacities":{
"begin": 0,
"end": 100000,
"groups": 11
"groups": 3
},
"time_interval":{
"numerator": 15,
@@ -43,5 +43,11 @@
"cost": "Costs of Microgrid system [m-EUR]",
"benefit": "Financial Profit Based on Py & Ess Configuration (k-EUR / year)",
"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):
return self.capacity * self.cost_per_kW / self.lifetime
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.cost_per_kW = cost_per_kW
self.lifetime = lifetime
self.loss = loss
self.storage = 0
self.storage = storage
self.charge_power = charge_power
self.discharge_power = discharge_power
def get_cost(self):

BIN
main.exe

Binary file not shown.

File diff suppressed because one or more lines are too long

187
main.py
View File

@@ -1,5 +1,9 @@
#!/usr/bin/env python
# coding: utf-8
# In[83]:
import os
import glob
import shutil
@@ -24,6 +28,9 @@ folder_path = 'plots'
clear_folder_make_ess_pv(folder_path)
# In[84]:
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
@@ -31,6 +38,10 @@ import pandas as pd
from EnergySystem import EnergySystem
from config import pv_config, grid_config, ess_config
# In[85]:
import json
print("Version 0.0.5")
@@ -38,8 +49,11 @@ print("Version 0.0.5")
with open('config.json', 'r') as f:
js_data = json.load(f)
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_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)
# In[ ]:
# In[86]:
hour_demand = []
@@ -118,6 +132,9 @@ plt.savefig('plots/demand.png')
plt.close()
# In[87]:
def draw_results(results, filename, title_benefit, annot_benefit=False, figure_size=(10, 10)):
df=results
df = df.astype(float)
@@ -154,7 +171,7 @@ def draw_results(results, filename, title_benefit, annot_benefit=False, figure_s
plt.savefig(filename)
# In[ ]:
# In[88]:
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:
df.loc[0,0] = 100
df[df > 80] = 100
print(df)
# print(df)
df = df.astype(float)
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)
min_value = df.min().min()
max_value = df.max().max()
print(max_value)
# print(max_value)
max_scale = max(abs(min_value), abs(max_value))
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.ylabel('PV Capacity (MW)')
plt.savefig(filename)
plt.close()
# In[89]:
def draw_cost(costs, filename, title_cost, annot_cost=False, figure_size=(10, 10)):
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.ylabel('PV Capacity (MW)')
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):
df = overload_cnt
print(days, granularity)
# print(days, granularity)
coef = 60 / granularity * days * 24
print(coef)
print(df)
# print(coef)
# print(df)
df = ( coef - df) / coef
print(df)
# print(df)
df = df.astype(float)
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.ylabel('PV Capacity (MW)')
plt.savefig(filename)
plt.close()
# In[91]:
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
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,
cost_per_kW=pv_cost_per_kW,
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,
loss=ess_loss,
charge_power=ess_capacity,
discharge_power=ess_capacity)
discharge_power=ess_capacity,
storage=storage)
grid = grid_config(capacity=grid_capacity,
grid_loss=grid_loss,
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)
overload_cnt = energySystem.overload_cnt
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_costs = []
months_overload = []
months_nettos = []
months_gen_energy = []
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)
costs = 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)
gen_energies = 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:
(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
overload_cnt.loc[pv_capacity,ess_capacity] = overload
costs.loc[pv_capacity,ess_capacity] = cost
nettos.loc[pv_capacity,ess_capacity] = netto
gen_energies.loc[pv_capacity, ess_capacity] = gen_energy
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_costs.append(costs)
months_overload.append(overload_cnt)
@@ -349,7 +450,6 @@ for index, month_data in enumerate(months_data):
figure_size=figure_size,
days=months_days[index],
granularity=granularity)
annual_result = 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)
@@ -358,7 +458,6 @@ annual_gen = pd.DataFrame(index=pv_capacities, columns= ess_capacities)
annual_gen2 = pd.DataFrame(index=pv_capacities, columns= ess_capacities)
# get the yearly results
for pv_capacity in pv_capacities:
for ess_capacity in ess_capacities:
@@ -399,11 +498,58 @@ draw_overload(overload_cnt=annual_overload,
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):
data.to_csv(filename+'.csv')
data.to_json(filename + '.json')
# In[97]:
if not os.path.isdir('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_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)
# In[99]:
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 numpy as np
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.csv'
electricity_price_data = 'electricity_price_data.csv'
electricity_price_data_sell = 'electricity_price_data_sell.csv'
factory_demand_file_name = js_data["data_path"]["demand"]
print(factory_demand_file_name)
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.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_combined = pv_df.join(df_power)

35041
read_data/Berlin.csv Normal file

File diff suppressed because it is too large Load Diff

35041
read_data/Cambodge.csv Normal file

File diff suppressed because it is too large Load Diff

35041
read_data/Marcedonia.csv Normal file

File diff suppressed because it is too large Load Diff

35041
read_data/Riyahd.csv Normal file

File diff suppressed because it is too large Load Diff

35041
read_data/Serbia.csv Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -55,15 +55,19 @@ def process(file_name):
sums = df.groupby('group_id')[energy_row_name].sum()
sums_df = sums.reset_index(drop=True).to_frame(name = 'Energy')
pv_energy_column_name = 'PV yield[kW/kWp]'
sums_df = sums_df.rename(columns={'Energy': pv_energy_column_name})
time_frame = generate_min_df(15)
sums_df = pd.concat([time_frame, sums_df], axis=1)
sums_df.set_index('Time', inplace=True)
max_value = sums_df['Energy'].max()
sums_df['Energy'] = sums_df['Energy'] / 390.
sums_df['Energy'] = sums_df['Energy'].round(4)
sums_df['Energy'].replace(0.0, -0.0)
# sums_df.set_index('Time', inplace=True)
# max_value = sums_df[pv_energy_column_name].max()
sums_df[pv_energy_column_name] = sums_df[pv_energy_column_name] / 390.
sums_df[pv_energy_column_name] = sums_df[pv_energy_column_name].round(4)
sums_df[pv_energy_column_name].replace(0.0, -0.0)
save_csv(sums_df, f'{city}.csv', ['Time', 'Energy'])
sums_df.to_csv(f'{city}.csv')
# save_csv(sums_df, f'{city}.csv', ['Time', 'Energy'])
if __name__ == '__main__':
city_list = ['Riyahd', 'Cambodge', 'Berlin', 'Serbia']

View File

Can't render this file because it is too large.

View File

Can't render this file because it is too large.

View File

Can't render this file because it is too large.