Compare commits

..

13 Commits

Author SHA1 Message Date
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
Hanzhang Ma
566ebca6cd make factory demand to csv file 2024-05-13 16:49:22 +02:00
Hanzhang Ma
c8c37b756c update pv yield code 2024-05-13 16:48:16 +02:00
Hanzhang Ma
4f1a47d505 update generate data code 2024-05-13 16:47:56 +02:00
Hanzhang Ma
ad9b5e6a19 update generate data code 2024-05-13 16:26:24 +02:00
Hanzhang Ma
33871fba77 done with convert data 2024-05-13 16:09:28 +02:00
Hanzhang Ma
9d143399ed get new intensity file 2024-05-13 15:24:44 +02:00
Hanzhang Ma
72d4ce811e data 2024-05-11 00:03:14 +02:00
Hanzhang Ma
060fa5bff1 v0.0.5 code 2024-05-10 23:57:58 +02:00
Hanzhang Ma
ebebd2d481 add read sell data 2024-05-10 17:40:54 +02:00
18 changed files with 316295 additions and 70386 deletions

View File

@@ -35,9 +35,12 @@ class EnergySystem:
# 如果ESS也不足以满足需求再从电网获取 - 当ESS中的存储电量也不足以补充时再从电网购买剩余所需电量。
def simulate(self, data, time_interval):
total_benefit = 0
total_netto_benefit = 0
total_gen = 0
for index, row in data.iterrows():
time = row['time']
sunlight_intensity = row['sunlight']
# sunlight_intensity = row['sunlight']
pv_yield = row['PV yield[kW/kWp]']
factory_demand = row['demand']
electricity_price = row['buy']
sell_price = row['sell']
@@ -53,7 +56,7 @@ class EnergySystem:
soc = self.ess.storage / self.ess.capacity
self.hour_stored_2.append(soc)
generated_pv_power = self.pv.capacity * sunlight_intensity # 生成的功率,单位 kW
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
# pv生成的能量如果比工厂的需求要大
@@ -109,9 +112,11 @@ class EnergySystem:
# 工厂需求量-总能量
# unmet_demand = max(0, factory_demand * time_interval - total_energy)
# benefit = (total_energy - unmet_demand) * electricity_price
total_gen += saved_energy
benefit = (saved_energy) * electricity_price
cost = net_grid * electricity_price
# print(f"time:{time} benefit: {benefit}, cost: {cost}")
total_netto_benefit += benefit
total_benefit += benefit - cost
# # spring
week_start = self.season_start
@@ -137,4 +142,4 @@ class EnergySystem:
# self.winter_week_gen.append(generated_pv_power)
# self.winter_week_soc.append(self.ess.storage / self.ess.capacity)
return total_benefit
return (total_benefit, total_netto_benefit, total_gen)

File diff suppressed because it is too large Load Diff

View File

@@ -17,12 +17,12 @@
"pv_capacities":{
"begin": 0,
"end": 50000,
"groups": 5
"groups": 11
},
"ess_capacities":{
"begin": 0,
"end": 100000,
"groups": 10
"groups": 11
},
"time_interval":{
"numerator": 15,
@@ -31,7 +31,8 @@
"annotated": {
"unmet_prob": false,
"benefit": false,
"cost": false
"cost": false,
"roi": false
},
"figure_size":{
"height": 9,
@@ -40,6 +41,7 @@
"plot_title":{
"unmet_prob": "Coverage Rate of Factory Electrical Demands",
"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"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -52,7 +52,7 @@
"source": [
"import json\n",
"\n",
"print(\"Version 0.0.4\")\n",
"print(\"Version 0.0.5\")\n",
"\n",
"with open('config.json', 'r') as f:\n",
" js_data = json.load(f)\n",
@@ -61,6 +61,7 @@
" \n",
"\n",
"time_interval = js_data[\"time_interval\"][\"numerator\"] / js_data[\"time_interval\"][\"denominator\"]\n",
"print(time_interval)\n",
"\n",
"pv_loss = js_data[\"pv\"][\"loss\"]\n",
"pv_cost_per_kW = js_data[\"pv\"][\"cost_per_kW\"]\n",
@@ -85,10 +86,13 @@
"annot_unmet = js_data[\"annotated\"][\"unmet_prob\"]\n",
"annot_benefit = js_data[\"annotated\"][\"benefit\"]\n",
"annot_cost = js_data[\"annotated\"][\"cost\"]\n",
"annot_roi = js_data[\"annotated\"][\"roi\"]\n",
"\n",
"title_unmet = js_data[\"plot_title\"][\"unmet_prob\"]\n",
"title_cost = js_data[\"plot_title\"][\"cost\"]\n",
"title_benefit = js_data[\"plot_title\"][\"benefit\"]\n",
"title_roi = js_data[\"plot_title\"][\"roi\"]\n",
"\n",
"\n",
"figure_size = (js_data[\"figure_size\"][\"length\"], js_data[\"figure_size\"][\"height\"])\n",
"\n",
@@ -181,6 +185,59 @@
" plt.savefig(filename)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def draw_roi(costs, results, filename, title_roi, days=365, annot_roi=False, figure_size=(10, 10)):\n",
" costs = costs.astype(float)\n",
" costs = costs / 365 \n",
" costs = costs * days\n",
"\n",
" df = results\n",
" df = costs / df\n",
" if 0 in df.index and 0 in df.columns:\n",
" df.loc[0,0] = 100\n",
" df[df > 80] = 100\n",
" print(df)\n",
"\n",
" df = df.astype(float)\n",
" df.index = df.index / 1000\n",
" df.index = df.index.map(int)\n",
" df.columns = df.columns / 1000\n",
" df.columns = df.columns.map(int)\n",
" min_value = df.min().min()\n",
" max_value = df.max().max()\n",
" print(max_value)\n",
" max_scale = max(abs(min_value), abs(max_value))\n",
"\n",
" df[df.columns[-1] + 1] = df.iloc[:, -1] \n",
" new_Data = pd.DataFrame(index=[df.index[-1] + 1], columns=df.columns)\n",
" for i in df.columns:\n",
" new_Data[i] = df[i].iloc[-1]\n",
" df = pd.concat([df, new_Data])\n",
"\n",
" X, Y = np.meshgrid(np.arange(df.shape[1]), np.arange(df.shape[0]))\n",
"\n",
" def fmt(x,pos):\n",
" return '{:.0f}'.format(x)\n",
"\n",
" cmap = sns.color_palette(\"Greys\", as_cmap=True)\n",
" plt.figure(figsize=figure_size)\n",
" ax = sns.heatmap(df, fmt=\".1f\", cmap=cmap, vmin=0, vmax=100, annot=annot_benefit)\n",
" CS = ax.contour(X, Y, df, colors='black', alpha=0.5)\n",
" ax.clabel(CS, inline=True, fontsize=10, fmt=FuncFormatter(fmt))\n",
" plt.title(title_roi)\n",
" plt.gca().invert_yaxis()\n",
" plt.xlim(0, df.shape[1] - 1)\n",
" plt.ylim(0, df.shape[0] - 1)\n",
" plt.xlabel('ESS Capacity (MWh)')\n",
" plt.ylabel('PV Capacity (MW)')\n",
" plt.savefig(filename)"
]
},
{
"cell_type": "code",
"execution_count": null,
@@ -253,8 +310,8 @@
" ax = sns.heatmap(df, fmt=\".00%\", cmap=cmap, vmin=0, vmax=1, annot=annot_unmet)\n",
"\n",
" cbar = ax.collections[0].colorbar\n",
" cbar.set_ticks([0, 0.25, 0.5, 0.75, 1])\n",
" cbar.set_ticklabels(['0%', '25%', '50%', '75%', '100%'])\n",
" cbar.set_ticks([0, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1])\n",
" cbar.set_ticklabels(['0%', '10%', '20%', '30%', '40%', '50%', '60%', '70%', '80%', '90%', '100%'])\n",
" cbar.ax.yaxis.set_major_formatter(ticker.FuncFormatter(lambda x, pos: f'{x:.0%}'))\n",
" X, Y = np.meshgrid(np.arange(df.shape[1]), np.arange(df.shape[0]))\n",
"\n",
@@ -289,7 +346,7 @@
"metadata": {},
"outputs": [],
"source": [
"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):\n",
"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):\n",
" pv = pv_config(capacity=pv_capacity, \n",
" cost_per_kW=pv_cost_per_kW,\n",
" lifetime=pv_lifetime, \n",
@@ -306,11 +363,11 @@
" energySystem = EnergySystem(pv_type=pv, \n",
" ess_type=ess, \n",
" grid_type= grid)\n",
" benefit = energySystem.simulate(data, time_interval)\n",
" (benefit, netto_benefit, gen_energy) = energySystem.simulate(data, time_interval)\n",
" results = cal_profit(energySystem, benefit, days)\n",
" overload_cnt = energySystem.overload_cnt\n",
" costs = energySystem.ess.capacity * energySystem.ess.cost_per_kW + energySystem.pv.capacity * energySystem.pv.cost_per_kW\n",
" return (results, overload_cnt, costs)\n"
" return (results, overload_cnt, costs, netto_benefit, gen_energy, energySystem.generated)\n"
]
},
{
@@ -322,26 +379,38 @@
"months_results = []\n",
"months_costs = []\n",
"months_overload = []\n",
"months_nettos = []\n",
"months_gen_energy = []\n",
"months_gen_energy2 = []\n",
"for index, month_data in enumerate(months_data):\n",
" results = pd.DataFrame(index=pv_capacities, columns= ess_capacities)\n",
" costs = pd.DataFrame(index=pv_capacities, columns= ess_capacities)\n",
" overload_cnt = pd.DataFrame(index=pv_capacities, columns= ess_capacities)\n",
" nettos = pd.DataFrame(index=pv_capacities, columns= ess_capacities)\n",
" gen_energies = pd.DataFrame(index=pv_capacities, columns= ess_capacities)\n",
" gen_energies2 = pd.DataFrame(index=pv_capacities, columns= ess_capacities)\n",
" for pv_capacity in pv_capacities:\n",
" for ess_capacity in ess_capacities:\n",
" (result, overload, cost) = 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])\n",
" (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])\n",
" results.loc[pv_capacity,ess_capacity] = result\n",
" overload_cnt.loc[pv_capacity,ess_capacity] = overload\n",
" costs.loc[pv_capacity,ess_capacity] = cost\n",
" nettos.loc[pv_capacity,ess_capacity] = netto\n",
" gen_energies.loc[pv_capacity, ess_capacity] = gen_energy\n",
" gen_energies2.loc[pv_capacity, ess_capacity] = gen_energy2\n",
" months_results.append(results)\n",
" months_costs.append(costs)\n",
" months_overload.append(overload_cnt)\n",
" months_nettos.append(nettos)\n",
" months_gen_energy.append(gen_energies)\n",
" months_gen_energy2.append(gen_energies2)\n",
" draw_results(results=results, \n",
" filename=f'plots/pv-{pv_capacity}-ess-{ess_capacity}-{index}-benefit.png',\n",
" filename=f'plots/pv-{pv_capacity}-ess-{ess_capacity}-month-{index+1}-benefit.png',\n",
" title_benefit=title_benefit,\n",
" annot_benefit=annot_benefit,\n",
" figure_size=figure_size)\n",
" draw_overload(overload_cnt=overload_cnt, \n",
" filename=f'plots/pv-{pv_capacity}-ess-{ess_capacity}-{index}-unmet.png',\n",
" filename=f'plots/pv-{pv_capacity}-ess-{ess_capacity}-month-{index+1}-unmet.png',\n",
" title_unmet=title_unmet,\n",
" annot_unmet=annot_unmet,\n",
" figure_size=figure_size,\n",
@@ -351,6 +420,11 @@
"annual_result = pd.DataFrame(index=pv_capacities, columns= ess_capacities)\n",
"annual_costs = pd.DataFrame(index=pv_capacities, columns= ess_capacities)\n",
"annual_overload = pd.DataFrame(index=pv_capacities, columns= ess_capacities)\n",
"annual_nettos = pd.DataFrame(index=pv_capacities, columns= ess_capacities)\n",
"annual_gen = pd.DataFrame(index=pv_capacities, columns= ess_capacities)\n",
"annual_gen2 = pd.DataFrame(index=pv_capacities, columns= ess_capacities)\n",
"\n",
"\n",
"\n",
"# get the yearly results\n",
"for pv_capacity in pv_capacities:\n",
@@ -358,13 +432,22 @@
" results = 0\n",
" costs = 0\n",
" overload_cnt = 0\n",
" nettos = 0\n",
" gen = 0\n",
" gen2 = 0\n",
" for index, month_data in enumerate(months_data):\n",
" results += months_results[index].loc[pv_capacity,ess_capacity]\n",
" costs += months_costs[index].loc[pv_capacity,ess_capacity]\n",
" overload_cnt += months_overload[index].loc[pv_capacity, ess_capacity]\n",
" nettos += months_nettos[index].loc[pv_capacity, ess_capacity]\n",
" gen += months_gen_energy[index].loc[pv_capacity, ess_capacity]\n",
" gen2 += months_gen_energy[index].loc[pv_capacity, ess_capacity]\n",
" annual_result.loc[pv_capacity, ess_capacity] = results\n",
" annual_costs.loc[pv_capacity, ess_capacity] = costs\n",
" annual_overload.loc[pv_capacity, ess_capacity] = overload_cnt\n",
" annual_nettos.loc[pv_capacity, ess_capacity] = nettos\n",
" annual_gen.loc[pv_capacity, ess_capacity] = gen\n",
" annual_gen2.loc[pv_capacity, ess_capacity] = gen2\n",
"\n",
"draw_cost(costs=annual_costs,\n",
" filename='plots/annual_cost.png',\n",
@@ -403,9 +486,27 @@
"if not os.path.isdir('data'):\n",
" os.makedirs('data')\n",
"\n",
"save_data(results, f'data/{pv_begin}-{pv_end}-{pv_groups}-{ess_begin}-{ess_end}-{ess_groups}-results')\n",
"save_data(costs, f'data/{pv_begin}-{pv_end}-{pv_groups}-{ess_begin}-{ess_end}-{ess_groups}-costs')\n",
"save_data(overload_cnt, f'data/{pv_begin}-{pv_end}-{pv_groups}-{ess_begin}-{ess_end}-{ess_groups}-overload_cnt')"
"save_data(annual_result, f'data/{pv_begin}-{pv_end}-{pv_groups}-{ess_begin}-{ess_end}-{ess_groups}-results')\n",
"save_data(annual_costs, f'data/{pv_begin}-{pv_end}-{pv_groups}-{ess_begin}-{ess_end}-{ess_groups}-costs')\n",
"save_data(annual_overload, f'data/{pv_begin}-{pv_end}-{pv_groups}-{ess_begin}-{ess_end}-{ess_groups}-overload_cnt')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"draw_results(annual_result, 'plots/test.png', 'test', False)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"draw_roi(annual_costs, annual_nettos, 'plots/annual_roi.png', title_roi, 365, annot_benefit, figure_size)\n"
]
}
],

550
main.py
View File

@@ -1,12 +1,17 @@
#!/usr/bin/env python
# coding: utf-8
# In[14]:
import os
import glob
import shutil
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
from matplotlib.ticker import FuncFormatter
import numpy as np
import pandas as pd
import os
import seaborn as sns
import json
from matplotlib.colors import LinearSegmentedColormap
def clear_folder_make_ess_pv(folder_path):
if os.path.isdir(folder_path):
@@ -19,9 +24,6 @@ folder_path = 'plots'
clear_folder_make_ess_pv(folder_path)
# In[15]:
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
@@ -29,19 +31,15 @@ import pandas as pd
from EnergySystem import EnergySystem
from config import pv_config, grid_config, ess_config
# In[16]:
import json
print("Version 0.0.2")
print("Version 0.0.5")
with open('config.json', 'r') as f:
js_data = json.load(f)
data = pd.read_csv('combined_data.csv')
time_interval = js_data["time_interval"]["numerator"] / js_data["time_interval"]["denominator"]
print(time_interval)
pv_loss = js_data["pv"]["loss"]
pv_cost_per_kW = js_data["pv"]["cost_per_kW"]
@@ -66,22 +64,45 @@ ess_groups = js_data["ess_capacities"]["groups"]
annot_unmet = js_data["annotated"]["unmet_prob"]
annot_benefit = js_data["annotated"]["benefit"]
annot_cost = js_data["annotated"]["cost"]
annot_roi = js_data["annotated"]["roi"]
title_unmet = js_data["plot_title"]["unmet_prob"]
title_cost = js_data["plot_title"]["cost"]
title_benefit = js_data["plot_title"]["benefit"]
title_roi = js_data["plot_title"]["roi"]
figure_size = (js_data["figure_size"]["length"], js_data["figure_size"]["height"])
data = pd.read_csv('combined_data.csv')
granularity = js_data["time_interval"]["numerator"]
months_days = [31,28,31,30,31,30,31,31,30,31,30,31]
def get_month_coe(num, granularity):
return 60 / granularity * 24 * months_days[num]
months_index = [get_month_coe(num, granularity) for num in range(12)]
months_data = []
for i in range(1,12):
months_index[i] += months_index[i-1]
for i in range(12):
start = 0 if i == 0 else months_index[i-1]
end = months_index[i]
months_data.append(data.iloc[int(start):int(end)])
pv_capacities = np.linspace(pv_begin, pv_end, pv_groups)
ess_capacities = np.linspace(ess_begin, ess_end, ess_groups)
results = pd.DataFrame(index=pv_capacities, columns= ess_capacities)
affords = 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)
# results = pd.DataFrame(index=pv_capacities, columns= ess_capacities)
# affords = 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)
# In[17]:
# In[ ]:
hour_demand = []
@@ -97,248 +118,301 @@ plt.savefig('plots/demand.png')
plt.close()
# In[18]:
def draw_results(results, filename, title_benefit, annot_benefit=False, figure_size=(10, 10)):
df=results
df = df.astype(float)
df.index = df.index / 1000
df.index = df.index.map(int)
df.columns = df.columns / 1000
df.columns = df.columns.map(int)
min_value = df.min().min()
max_value = df.max().max()
max_scale = max(abs(min_value/1000), abs(max_value/1000))
df[df.columns[-1] + 1] = df.iloc[:, -1]
new_Data = pd.DataFrame(index=[df.index[-1] + 1], columns=df.columns)
for i in df.columns:
new_Data[i] = df[i].iloc[-1]
df = pd.concat([df, new_Data])
X, Y = np.meshgrid(np.arange(df.shape[1]), np.arange(df.shape[0]))
def fmt(x,pos):
return '{:.0f}'.format(x/1000)
cmap = sns.color_palette("coolwarm", as_cmap=True)
plt.figure(figsize=figure_size)
ax = sns.heatmap(df/1000, fmt=".1f", cmap=cmap, vmin=-max_scale, vmax=max_scale, annot=annot_benefit)
CS = ax.contour(X, Y, df, colors='black', alpha=0.5)
ax.clabel(CS, inline=True, fontsize=10, fmt=FuncFormatter(fmt))
plt.title(title_benefit)
plt.gca().invert_yaxis()
plt.xlim(0, df.shape[1] - 1)
plt.ylim(0, df.shape[0] - 1)
plt.xlabel('ESS Capacity (MWh)')
plt.ylabel('PV Capacity (MW)')
plt.savefig(filename)
def cal_profit(es: EnergySystem, saved_money):
profit = saved_money - es.ess.get_cost_per_year() - es.pv.get_cost_per_year()
# In[ ]:
def draw_roi(costs, results, filename, title_roi, days=365, annot_roi=False, figure_size=(10, 10)):
costs = costs.astype(float)
costs = costs / 365
costs = costs * days
df = results
df = costs / df
if 0 in df.index and 0 in df.columns:
df.loc[0,0] = 100
df[df > 80] = 100
print(df)
df = df.astype(float)
df.index = df.index / 1000
df.index = df.index.map(int)
df.columns = df.columns / 1000
df.columns = df.columns.map(int)
min_value = df.min().min()
max_value = df.max().max()
print(max_value)
max_scale = max(abs(min_value), abs(max_value))
df[df.columns[-1] + 1] = df.iloc[:, -1]
new_Data = pd.DataFrame(index=[df.index[-1] + 1], columns=df.columns)
for i in df.columns:
new_Data[i] = df[i].iloc[-1]
df = pd.concat([df, new_Data])
X, Y = np.meshgrid(np.arange(df.shape[1]), np.arange(df.shape[0]))
def fmt(x,pos):
return '{:.0f}'.format(x)
cmap = sns.color_palette("Greys", as_cmap=True)
plt.figure(figsize=figure_size)
ax = sns.heatmap(df, fmt=".1f", cmap=cmap, vmin=0, vmax=100, annot=annot_benefit)
CS = ax.contour(X, Y, df, colors='black', alpha=0.5)
ax.clabel(CS, inline=True, fontsize=10, fmt=FuncFormatter(fmt))
plt.title(title_roi)
plt.gca().invert_yaxis()
plt.xlim(0, df.shape[1] - 1)
plt.ylim(0, df.shape[0] - 1)
plt.xlabel('ESS Capacity (MWh)')
plt.ylabel('PV Capacity (MW)')
plt.savefig(filename)
def draw_cost(costs, filename, title_cost, annot_cost=False, figure_size=(10, 10)):
df = costs
df = df.astype(int)
df.index = df.index / 1000
df.index = df.index.map(int)
df.columns = df.columns / 1000
df.columns = df.columns.map(int)
df[df.columns[-1] + 1] = df.iloc[:, -1]
new_Data = pd.DataFrame(index=[df.index[-1] + 1], columns=df.columns)
for i in df.columns:
new_Data[i] = df[i].iloc[-1]
df = pd.concat([df, new_Data])
X, Y = np.meshgrid(np.arange(df.shape[1]), np.arange(df.shape[0]))
def fmt(x, pos):
return '{:.0f}'.format(x / 1000000)
plt.figure(figsize=figure_size)
ax = sns.heatmap(df/1000000, fmt=".1f", cmap='viridis', annot=annot_cost)
CS = ax.contour(X, Y, df, colors='black', alpha=0.5)
ax.clabel(CS, inline=True, fontsize=10, fmt=FuncFormatter(fmt))
plt.title(title_cost)
plt.gca().invert_yaxis()
plt.xlim(0, df.shape[1] - 1)
plt.ylim(0, df.shape[0] - 1)
plt.xlabel('ESS Capacity (MWh)')
plt.ylabel('PV Capacity (MW)')
plt.savefig(filename)
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)
coef = 60 / granularity * days * 24
print(coef)
print(df)
df = ( coef - df) / coef
print(df)
df = df.astype(float)
df.index = df.index / 1000
df.index = df.index.map(int)
df.columns = df.columns / 1000
df.columns = df.columns.map(int)
df[df.columns[-1] + 1] = df.iloc[:, -1]
new_Data = pd.DataFrame(index=[df.index[-1] + 1], columns=df.columns)
for i in df.columns:
new_Data[i] = df[i].iloc[-1]
# print(new_Data)
df = pd.concat([df, new_Data])
plt.figure(figsize=figure_size)
cmap = LinearSegmentedColormap.from_list("", ["white", "blue"])
ax = sns.heatmap(df, fmt=".00%", cmap=cmap, vmin=0, vmax=1, annot=annot_unmet)
cbar = ax.collections[0].colorbar
cbar.set_ticks([0, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1])
cbar.set_ticklabels(['0%', '10%', '20%', '30%', '40%', '50%', '60%', '70%', '80%', '90%', '100%'])
cbar.ax.yaxis.set_major_formatter(ticker.FuncFormatter(lambda x, pos: f'{x:.0%}'))
X, Y = np.meshgrid(np.arange(df.shape[1]), np.arange(df.shape[0]))
def fmt(x, pos):
return '{:.0f}%'.format(x * 100)
CS = ax.contour(X, Y, df, colors='black', alpha=0.5)
ax.clabel(CS, inline=True, fontsize=10, fmt=FuncFormatter(fmt))
plt.xlim(0, df.shape[1] - 1)
plt.ylim(0, df.shape[0] - 1)
plt.title(title_unmet)
plt.xlabel('ESS Capacity (MWh)')
plt.ylabel('PV Capacity (MW)')
plt.savefig(filename)
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
# In[24]:
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):
pv = pv_config(capacity=pv_capacity,
cost_per_kW=pv_cost_per_kW,
lifetime=pv_lifetime,
loss=pv_loss)
ess = ess_config(capacity=ess_capacity,
cost_per_kW=ess_cost_per_kW,
lifetime=ess_lifetime,
loss=ess_loss,
charge_power=ess_capacity,
discharge_power=ess_capacity)
grid = grid_config(capacity=grid_capacity,
grid_loss=grid_loss,
sell_price= sell_price)
energySystem = EnergySystem(pv_type=pv,
ess_type=ess,
grid_type= grid)
(benefit, netto_benefit, gen_energy) = energySystem.simulate(data, time_interval)
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)
for ess_capacity in ess_capacities:
print(f"ess_capacity:{ess_capacity}")
months_results = []
months_costs = []
months_overload = []
months_nettos = []
months_gen_energy = []
months_gen_energy2 = []
for index, month_data in enumerate(months_data):
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:
print(f"pv_capacity:{pv_capacity}")
pv = pv_config(capacity=pv_capacity,
cost_per_kW=pv_cost_per_kW,
lifetime=pv_lifetime,
loss=pv_loss)
ess = ess_config(capacity=ess_capacity,
cost_per_kW=ess_cost_per_kW,
lifetime=ess_lifetime,
loss=ess_loss,
charge_power=ess_capacity,
discharge_power=ess_capacity)
grid = grid_config(capacity=grid_capacity,
grid_loss=grid_loss,
sell_price= sell_price)
energySystem = EnergySystem(pv_type=pv,
ess_type=ess,
grid_type= grid)
benefit = energySystem.simulate(data, time_interval)
results.loc[pv_capacity,ess_capacity] = cal_profit(energySystem, benefit)
affords.loc[pv_capacity,ess_capacity] = energySystem.afford
overload_cnt.loc[pv_capacity,ess_capacity] = energySystem.overload_cnt
costs.loc[pv_capacity,ess_capacity] = energySystem.ess.capacity * energySystem.ess.cost_per_kW + energySystem.pv.capacity * energySystem.pv.cost_per_kW
pv_generated = energySystem.day_generated
ess_generated = energySystem.hour_stored
ess_generated_2 = energySystem.hour_stored_2
plt.figure(figsize=(10,8));
plt.plot(ess_generated)
plt.xlabel('day #')
plt.ylabel('SoC %')
plt.title(f'14:00 ESS SoC \n PV cap:{pv_capacity}, ESS cap:{ess_capacity}')
plt.savefig(f'plots/ess/1400-{pv_capacity}-{ess_capacity}.png')
plt.close()
plt.figure(figsize=(10,8));
plt.plot(ess_generated_2)
plt.xlabel('day #')
plt.ylabel('SoC%')
plt.title(f'08:00 ESS SoC \n PV cap:{pv_capacity}, ESS cap:{ess_capacity}')
plt.savefig(f'plots/ess/0800-{pv_capacity}-{ess_capacity}.png')
plt.close()
# print(energySystem.unmet)
# spring_week_start = energySystem.season_start
# spring_week_end = spring_week_start + energySystem.week_length
# summer_week_start = energySystem.season_start + 1 * energySystem.season_step
# summer_week_end = summer_week_start + energySystem.week_length
# autumn_week_start = energySystem.season_start + 2 * energySystem.season_step
# autumn_week_end = autumn_week_start + energySystem.week_length
# winter_week_start = energySystem.season_start + 3 * energySystem.season_step
# winter_week_end = winter_week_start+ energySystem.week_length
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])
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_results.append(results)
months_costs.append(costs)
months_overload.append(overload_cnt)
months_nettos.append(nettos)
months_gen_energy.append(gen_energies)
months_gen_energy2.append(gen_energies2)
draw_results(results=results,
filename=f'plots/pv-{pv_capacity}-ess-{ess_capacity}-month-{index+1}-benefit.png',
title_benefit=title_benefit,
annot_benefit=annot_benefit,
figure_size=figure_size)
draw_overload(overload_cnt=overload_cnt,
filename=f'plots/pv-{pv_capacity}-ess-{ess_capacity}-month-{index+1}-unmet.png',
title_unmet=title_unmet,
annot_unmet=annot_unmet,
figure_size=figure_size,
days=months_days[index],
granularity=granularity)
# spring_consume_data = []
# summer_consume_data = []
# autumn_consume_data = []
# winter_consume_data = []
# for index, row in data.iterrows():
# if index in range(spring_week_start, spring_week_end):
# spring_consume_data.append(row['demand'])
# elif index in range(summer_week_start, summer_week_end):
# summer_consume_data.append(row['demand'])
# elif index in range(autumn_week_start, autumn_week_end):
# autumn_consume_data.append(row['demand'])
# elif index in range(winter_week_start, winter_week_end):
# winter_consume_data.append(row['demand'])
# spring_week_time = list(range(spring_week_start, spring_week_end))
# summer_week_time = list(range(summer_week_start, summer_week_end))
# autumn_week_time = list(range(autumn_week_start, autumn_week_end))
# winter_week_time = list(range(winter_week_start, winter_week_end))
# spring_pv_generated = energySystem.spring_week_gen
# summer_pv_generated = energySystem.summer_week_gen
# autumn_pv_generated = energySystem.autumn_week_gen
# winter_pv_generated = energySystem.winter_week_gen
# spring_soc = energySystem.spring_week_soc
# summer_soc = energySystem.summer_week_soc
# autumn_soc = energySystem.autumn_week_soc
# winter_soc = energySystem.winter_week_soc
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)
annual_nettos = pd.DataFrame(index=pv_capacities, columns= ess_capacities)
annual_gen = pd.DataFrame(index=pv_capacities, columns= ess_capacities)
annual_gen2 = pd.DataFrame(index=pv_capacities, columns= ess_capacities)
# fig, ax1 = plt.subplots()
# plt.plot(spring_week_time, spring_pv_generated, label = 'pv generation')
# plt.plot(spring_week_time, spring_consume_data, label = 'factory consume')
# plt.ylabel('Power / kW')
# plt.xlabel('15 min #')
# plt.title(f'ess: {energySystem.ess.capacity/1000 } MWh pv: {energySystem.pv.capacity/1000 } MW spring week generate condition')
# plt.legend()
# plt.savefig(f'plots/{energySystem.ess.capacity}-{energySystem.pv.capacity}-spring.png')
# plt.close()
# get the yearly results
for pv_capacity in pv_capacities:
for ess_capacity in ess_capacities:
results = 0
costs = 0
overload_cnt = 0
nettos = 0
gen = 0
gen2 = 0
for index, month_data in enumerate(months_data):
results += months_results[index].loc[pv_capacity,ess_capacity]
costs += months_costs[index].loc[pv_capacity,ess_capacity]
overload_cnt += months_overload[index].loc[pv_capacity, ess_capacity]
nettos += months_nettos[index].loc[pv_capacity, ess_capacity]
gen += months_gen_energy[index].loc[pv_capacity, ess_capacity]
gen2 += months_gen_energy[index].loc[pv_capacity, ess_capacity]
annual_result.loc[pv_capacity, ess_capacity] = results
annual_costs.loc[pv_capacity, ess_capacity] = costs
annual_overload.loc[pv_capacity, ess_capacity] = overload_cnt
annual_nettos.loc[pv_capacity, ess_capacity] = nettos
annual_gen.loc[pv_capacity, ess_capacity] = gen
annual_gen2.loc[pv_capacity, ess_capacity] = gen2
# plt.plot(summer_week_time, summer_pv_generated, label = 'pv generation')
# plt.plot(summer_week_time, summer_consume_data, label = 'factory consume')
# plt.ylabel('Power / kW')
# plt.xlabel('15 min #')
# plt.title(f'ess: {energySystem.ess.capacity/1000 } MWh pv: {energySystem.pv.capacity/1000 } MW summer week generate condition')
# plt.legend()
# plt.savefig(f'plots/{energySystem.ess.capacity}-{energySystem.pv.capacity}-summer.png')
# plt.close()
draw_cost(costs=annual_costs,
filename='plots/annual_cost.png',
title_cost=title_cost,
annot_cost=annot_cost,
figure_size=figure_size)
draw_results(results=annual_result,
filename='plots/annual_benefit.png',
title_benefit=title_benefit,
annot_benefit=annot_benefit,
figure_size=figure_size)
draw_overload(overload_cnt=annual_overload,
filename='plots/annual_unmet.png',
title_unmet=title_unmet,
annot_unmet=annot_unmet,
figure_size=figure_size)
# plt.plot(autumn_week_time, autumn_pv_generated, label = 'pv generation')
# plt.plot(autumn_week_time, autumn_consume_data, label = 'factory consume')
# plt.ylabel('Power / kW')
# plt.xlabel('15 min #')
# plt.title(f'ess: {energySystem.ess.capacity/1000 } MWh pv: {energySystem.pv.capacity/1000 } MW autumn week generate condition')
# plt.legend()
# plt.savefig(f'plots/{energySystem.ess.capacity}-{energySystem.pv.capacity}-autumn.png')
# plt.close()
# plt.plot(winter_week_time, winter_pv_generated, label = 'pv generation')
# plt.plot(winter_week_time, winter_consume_data, label = 'factory consume')
# plt.ylabel('Power / kW')
# plt.xlabel('15 min #')
# plt.title(f'ess: {energySystem.ess.capacity/1000 } MWh pv: {energySystem.pv.capacity/1000 } MW winter week generate condition')
# plt.legend()
# plt.savefig(f'plots/{energySystem.ess.capacity}-{energySystem.pv.capacity}-winter.png')
# plt.close()
# plt.figure();
# plt.plot(pv_generated)
# plt.xlabel('day #')
# plt.ylabel('Electricity kWh')
# plt.title(f'PV generated pv cap:{pv_capacity}, ess cap:{ess_capacity}')
# plt.savefig(f'plots/pv/{pv_capacity}-{ess_capacity}.png')
# plt.close()
# plt.show()
# results = results.astype(float)
# pv = pv_config(capacity=100000,cost_per_kW=200,lifetime=25,loss=0.95)
# ess = ess_config(capacity=100000,cost_per_kW=300,lifetime=25,loss=0.95,charge_power=100000,discharge_power=100000)
# grid = grid_config(price_schedule=price_schedule, capacity=5000, grid_loss=0.95, sell_price=0.4)
# grid = grid_config(capacity=50000, grid_loss=0.95, sell_price=0.4)
# print(benefit)
# In[20]:
def save_data(data, filename):
data.to_csv(filename+'.csv')
data.to_json(filename + '.json')
# In[21]:
import matplotlib.ticker as ticker
if not os.path.isdir('data'):
os.makedirs('data')
save_data(results, f'data/{pv_begin}-{pv_end}-{pv_groups}-{ess_begin}-{ess_end}-{ess_groups}-results')
save_data(costs, f'data/{pv_begin}-{pv_end}-{pv_groups}-{ess_begin}-{ess_end}-{ess_groups}-costs')
save_data(overload_cnt, f'data/{pv_begin}-{pv_end}-{pv_groups}-{ess_begin}-{ess_end}-{ess_groups}-overload_cnt')
df=results
df = df.astype(float)
df.index = df.index / 1000
df.columns = df.columns / 1000
min_value = df.min().min()
max_value = df.max().max()
max_scale = max(abs(min_value/1000), abs(max_value/1000))
plt.figure(figsize=figure_size)
cmap = sns.color_palette("coolwarm", as_cmap=True)
ax = sns.heatmap(df/1000, fmt=".1f", cmap=cmap, vmin=-max_scale, vmax=max_scale, annot=annot_benefit)
# ax.yaxis.set_major_formatter(ticker.FormatStrFormatter('%.1f'))
plt.title(title_benefit)
plt.gca().invert_yaxis()
plt.xlabel('ESS Capacity (MWh)')
plt.ylabel('PV Capacity (MW)')
plt.savefig('plots/benefit.png')
save_data(annual_result, f'data/{pv_begin}-{pv_end}-{pv_groups}-{ess_begin}-{ess_end}-{ess_groups}-results')
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')
draw_results(annual_result, 'plots/test.png', 'test', False)
# In[22]:
df = costs
df = df.astype(int)
df.index = df.index / 1000
df.columns = df.columns / 1000
plt.figure(figsize=figure_size)
sns.heatmap(df/1000000, fmt=".1f", cmap='viridis', annot=annot_cost)
plt.title(title_cost)
plt.gca().invert_yaxis()
plt.xlabel('ESS Capacity (MWh)')
plt.ylabel('PV Capacity (MW)')
plt.savefig('plots/costs.png')
# pv = pv_config(capacity=100000,cost_per_kW=200,lifetime=25,loss=0.95)
# ess = ess_config(capacity=100000,cost_per_kW=300,lifetime=25,loss=0.95,charge_power=100000,discharge_power=100000)
# grid = grid_config(price_schedule=price_schedule, capacity=5000, grid_loss=0.95, sell_price=0.4)
# grid = grid_config(capacity=50000, grid_loss=0.95, sell_price=0.4)
# print(benefit)
# In[23]:
from matplotlib.colors import LinearSegmentedColormap
df = overload_cnt
df = df.astype(int)
df.index = df.index / 1000
df.columns = df.columns / 1000
min_value = df.min().min()
max_value = df.max().max()
max_scale = max(abs(min_value/1000), abs(max_value/1000))
plt.figure(figsize=figure_size)
cmap = LinearSegmentedColormap.from_list("", ["white", "blue"])
ax = sns.heatmap(df/(4*24*365), fmt=".00%", cmap=cmap, vmin=0, vmax=1, annot=annot_unmet)
cbar = ax.collections[0].colorbar
cbar.set_ticks([0, 0.25, 0.5, 0.75, 1])
cbar.set_ticklabels(['0%', '25%', '50%', '75%', '100%'])
cbar.ax.yaxis.set_major_formatter(ticker.FuncFormatter(lambda x, pos: f'{x:.0%}'))
plt.title(title_unmet)
plt.gca().invert_yaxis()
plt.xlabel('ESS Capacity (MWh)')
plt.ylabel('PV Capacity (MW)')
plt.savefig('plots/unmet.png')
draw_roi(annual_costs, annual_nettos, 'plots/annual_roi.png', title_roi, 365, annot_benefit, figure_size)

View File

@@ -2,68 +2,38 @@ import pandas as pd
import numpy as np
import csv
sunlight_file_name = 'lightintensity.xlsx'
factory_demand_file_name = 'factory_power1.xlsx'
electricity_price_data = 'electricity_price_data.csv'
pv_yield_file_name = 'read_data/Serbia.csv'
# factory_demand_file_name = 'factory_power1.xlsx'
factory_demand_file_name = 'read_data/factory_power1.csv'
electricity_price_data = 'read_data/electricity_price_data.csv'
electricity_price_data_sell = 'read_data/electricity_price_data_sell.csv'
df_sunlight = pd.read_excel(sunlight_file_name, header=None, names=['SunlightIntensity'])
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)
start_date = '2023-01-01 00:00:00' # 根据数据的实际开始日期调整
hours = pd.date_range(start=start_date, periods=len(df_sunlight), freq='h')
df_sunlight['Time'] = hours
df_sunlight.set_index('Time', inplace=True)
df_power = pd.read_csv('factory_power1.csv', index_col='Time', usecols=['Time', 'FactoryPower'])
df_power.index = pd.to_datetime(df_power.index)
df_combined = pv_df.join(df_power)
df_sunlight_resampled = df_sunlight.resample('15min').interpolate()
df_power = pd.read_excel(factory_demand_file_name,
header=None,
names=['FactoryPower'],
dtype={'FactoryPower': float})
times = pd.date_range(start=start_date, periods=len(df_power), freq='15min')
df_power['Time'] = times
df_power.set_index('Time',inplace=True)
print(df_power.head())
df_combined = df_sunlight_resampled.join(df_power)
df_combined.to_csv('combined_data.csv', index=True, index_label='Time')
def read_csv(file_path):
return pd.read_csv(file_path, index_col='Time', usecols=['Time', 'ElectricityPrice'])
# price_data = np.random.uniform(0.3, 0.3, len(times))
# 创建DataFrame
price_df = read_csv(electricity_price_data)
price_df = pd.read_csv(electricity_price_data, index_col='Time', usecols=['Time', 'ElectricityBuy'])
price_df.index = pd.to_datetime(price_df.index)
price_df = price_df.reindex(df_combined.index)
# price_df.set_index('Time', inplace=True)
# 保存到CSV文件
# price_df.to_csv('electricity_price_data.csv', index=True)
print("price____")
print(price_df.index)
print("df_combined____")
print(df_combined.index)
print("Electricity price data generated and saved.")
df_combined2 = df_combined.join(price_df)
print(df_combined2.head())
# 保存结果
sell_df = pd.read_csv(electricity_price_data_sell, index_col='Time', usecols=['Time', 'ElectricitySell'])
sell_df.index = pd.to_datetime(sell_df.index)
sell_df = sell_df.reindex(df_combined.index)
df_combined3 = df_combined2.join(sell_df)
with open('combined_data.csv', 'w', newline='') as file:
writer = csv.writer(file)
writer.writerow(['time', 'sunlight', 'demand','price'])
writer.writerow(['time', 'PV yield[kW/kWp]', 'demand','buy', 'sell'])
cnt = 0
for index, row in df_combined2.iterrows():
for index, row in df_combined3.iterrows():
time_formatted = index.strftime('%H:%M')
writer.writerow([time_formatted, row['SunlightIntensity'], row['FactoryPower'],row['ElectricityPrice']])
writer.writerow([time_formatted, row['PV yield[kW/kWp]'], row['FactoryPower'],row['ElectricityBuy'], row['ElectricitySell']])
print('The file is written to combined_data.csv')
# combined_data.to_csv('updated_simulation_with_prices.csv', index=False)
print("Simulation data with electricity prices has been updated and saved.")

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

@@ -0,0 +1,372 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 85,
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"import pandas as pd\n",
"import numpy as np\n",
"import os\n",
"import csv"
]
},
{
"cell_type": "code",
"execution_count": 86,
"metadata": {},
"outputs": [],
"source": [
"def read_csv(filename):\n",
" skip_rows = list(range(1, 17))\n",
" data = pd.read_csv(filename, sep=';', skiprows=skip_rows)\n",
" return data"
]
},
{
"cell_type": "code",
"execution_count": 87,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/tmp/ipykernel_3075037/3659192646.py:3: DtypeWarning: Columns (32,33,35) have mixed types. Specify dtype option on import or set low_memory=False.\n",
" data = pd.read_csv(filename, sep=';', skiprows=skip_rows)\n"
]
},
{
"data": {
"text/plain": [
"Index(['Time', 'Irradiance onto horizontal plane ',\n",
" 'Diffuse Irradiation onto Horizontal Plane ', 'Outside Temperature ',\n",
" 'Module Area 1: Height of Sun ',\n",
" 'Module Area 1: Irradiance onto tilted surface ',\n",
" 'Module Area 1: Module Temperature ', 'Grid Export ',\n",
" 'Energy from Grid ', 'Global radiation - horizontal ',\n",
" 'Deviation from standard spectrum ', 'Ground Reflection (Albedo) ',\n",
" 'Orientation and inclination of the module surface ', 'Shading ',\n",
" 'Reflection on the Module Surface ',\n",
" 'Irradiance on the rear side of the module ',\n",
" 'Global Radiation at the Module ',\n",
" 'Module Area 1: Reflection on the Module Surface ',\n",
" 'Module Area 1: Global Radiation at the Module ',\n",
" 'Global PV Radiation ', 'Bifaciality ', 'Soiling ',\n",
" 'STC Conversion (Rated Efficiency of Module) ', 'Rated PV Energy ',\n",
" 'Low-light performance ', 'Module-specific Partial Shading ',\n",
" 'Deviation from the nominal module temperature ', 'Diodes ',\n",
" 'Mismatch (Manufacturer Information) ',\n",
" 'Mismatch (Configuration/Shading) ',\n",
" 'Power optimizer (DC conversion/clipping) ',\n",
" 'PV Energy (DC) without inverter clipping ',\n",
" 'Failing to reach the DC start output ',\n",
" 'Clipping on account of the MPP Voltage Range ',\n",
" 'Clipping on account of the max. DC Current ',\n",
" 'Clipping on account of the max. DC Power ',\n",
" 'Clipping on account of the max. AC Power/cos phi ', 'MPP Matching ',\n",
" 'PV energy (DC) ',\n",
" 'Inverter 1 - MPP 1 - to Module Area 1: PV energy (DC) ',\n",
" 'Inverter 1 - MPP 2 - to Module Area 1: PV energy (DC) ',\n",
" 'Inverter 1 - MPP 3 - to Module Area 1: PV energy (DC) ',\n",
" 'Inverter 1 - MPP 4 - to Module Area 1: PV energy (DC) ',\n",
" 'Inverter 1 - MPP 5 - to Module Area 1: PV energy (DC) ',\n",
" 'Inverter 1 - MPP 6 - to Module Area 1: PV energy (DC) ',\n",
" 'Inverter 2 - MPP 1 - to Module Area 1: PV energy (DC) ',\n",
" 'Inverter 2 - MPP 2 - to Module Area 1: PV energy (DC) ',\n",
" 'Energy at the Inverter Input ',\n",
" 'Input voltage deviates from rated voltage ', 'DC/AC Conversion ',\n",
" 'Own Consumption (Standby or Night) ', 'Total Cable Losses ',\n",
" 'PV energy (AC) minus standby use ', 'Feed-in energy ',\n",
" 'Inverter 1 to Module Area 1: Own Consumption (Standby or Night) ',\n",
" 'Inverter 1 to Module Area 1: PV energy (AC) minus standby use ',\n",
" 'Inverter 2 to Module Area 1: Own Consumption (Standby or Night) ',\n",
" 'Inverter 2 to Module Area 1: PV energy (AC) minus standby use ',\n",
" 'Unnamed: 58'],\n",
" dtype='object')"
]
},
"execution_count": 87,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"\n",
"file_name = 'Riyahd_raw.csv'\n",
"df = read_csv(file_name)\n",
"df.columns"
]
},
{
"cell_type": "code",
"execution_count": 88,
"metadata": {},
"outputs": [],
"source": [
"remain_column = ['Time','PV energy (AC) minus standby use ']\n",
"energy_row_name = remain_column[1]\n",
"\n",
"df = df[remain_column]\n",
"df[energy_row_name] = df[energy_row_name].str.replace(',','.').astype(float)\n"
]
},
{
"cell_type": "code",
"execution_count": 89,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"770594.226863267"
]
},
"execution_count": 89,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sum_energy = df[energy_row_name].sum()\n",
"sum_energy"
]
},
{
"cell_type": "code",
"execution_count": 90,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1975.882632982736"
]
},
"execution_count": 90,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sum_energy / 390"
]
},
{
"cell_type": "code",
"execution_count": 91,
"metadata": {},
"outputs": [],
"source": [
"group_size = 15\n",
"df['group_id'] = df.index // group_size\n",
"\n",
"sums = df.groupby('group_id')[energy_row_name].sum()\n",
"sums_df = sums.reset_index(drop=True).to_frame(name = 'Energy')"
]
},
{
"cell_type": "code",
"execution_count": 92,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<bound method NDFrame.head of Energy\n",
"0 0.0\n",
"1 0.0\n",
"2 0.0\n",
"3 0.0\n",
"4 0.0\n",
"... ...\n",
"35035 0.0\n",
"35036 0.0\n",
"35037 0.0\n",
"35038 0.0\n",
"35039 0.0\n",
"\n",
"[35040 rows x 1 columns]>"
]
},
"execution_count": 92,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sums_df.head"
]
},
{
"cell_type": "code",
"execution_count": 93,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" Time\n",
"0 2023-01-01 00:00:00\n",
"1 2023-01-01 00:15:00\n",
"2 2023-01-01 00:30:00\n",
"3 2023-01-01 00:45:00\n",
"4 2023-01-01 01:00:00\n",
" Time\n",
"35035 2023-12-31 22:45:00\n",
"35036 2023-12-31 23:00:00\n",
"35037 2023-12-31 23:15:00\n",
"35038 2023-12-31 23:30:00\n",
"35039 2023-12-31 23:45:00\n"
]
}
],
"source": [
"\n",
"start_date = '2023-01-01'\n",
"end_date = '2023-12-31'\n",
"\n",
"# 生成每天的15分钟间隔时间\n",
"all_dates = pd.date_range(start=start_date, end=end_date, freq='D')\n",
"all_times = pd.timedelta_range(start='0 min', end='1435 min', freq='15 min')\n",
"\n",
"# 生成完整的时间标签\n",
"date_times = [pd.Timestamp(date) + time for date in all_dates for time in all_times]\n",
"\n",
"# 创建DataFrame\n",
"time_frame = pd.DataFrame({\n",
" 'Time': date_times\n",
"})\n",
"\n",
"# 查看生成的DataFrame\n",
"print(time_frame.head())\n",
"print(time_frame.tail())\n"
]
},
{
"cell_type": "code",
"execution_count": 94,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(35040, 1)\n",
"(35040, 1)\n"
]
}
],
"source": [
"print(sums_df.shape)\n",
"print(time_frame.shape)"
]
},
{
"cell_type": "code",
"execution_count": 95,
"metadata": {},
"outputs": [],
"source": [
"# sums_df['Time'] = time_frame['Time']\n",
"sums_df = pd.concat([time_frame, sums_df], axis=1)"
]
},
{
"cell_type": "code",
"execution_count": 96,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" Energy\n",
"Time \n",
"2023-01-01 00:00:00 0.0\n",
"2023-01-01 00:15:00 0.0\n",
"2023-01-01 00:30:00 0.0\n",
"2023-01-01 00:45:00 0.0\n",
"2023-01-01 01:00:00 0.0\n"
]
}
],
"source": [
"sums_df.set_index('Time', inplace=True)\n",
"print(sums_df.head())"
]
},
{
"cell_type": "code",
"execution_count": 97,
"metadata": {},
"outputs": [],
"source": [
"max_value = sums_df['Energy'].max()\n",
"sums_df['Energy'] = sums_df['Energy'] / max_value\n"
]
},
{
"cell_type": "code",
"execution_count": 98,
"metadata": {},
"outputs": [],
"source": [
"def save_csv(df, filename, columns):\n",
" tmp_df = df.copy()\n",
" tmp_df[columns[1]] = tmp_df[columns[1]].round(4)\n",
" with open(filename, 'w', newline='') as file:\n",
" writer = csv.writer(file)\n",
" writer.writerow(columns)\n",
" for index, row in tmp_df.iterrows():\n",
" time_formatted = index.strftime('%H:%M')\n",
" writer.writerow([time_formatted, row[columns[1]]])\n",
" \n",
" print(f'The file is written to {filename}')\n",
" \n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 99,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The file is written to Riyahd.csv\n"
]
}
],
"source": [
"save_csv(sums_df, 'Riyahd.csv', ['Time', 'Energy'])"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "pv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.9"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

79
read_data/convert_data.py Normal file
View File

@@ -0,0 +1,79 @@
#!/usr/bin/env python
# coding: utf-8
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import os
import csv
def generate_min_df(mins = 15):
end = 60/mins * 24
start_date = '2023-01-01'
end_date = '2023-12-31'
all_dates = pd.date_range(start=start_date, end=end_date, freq='D')
all_times = pd.timedelta_range(start='0 min', end=f'1435 min', freq=f'{mins} min')
date_times = [pd.Timestamp(date) + time for date in all_dates for time in all_times]
time_frame = pd.DataFrame({
'Time': date_times
})
return time_frame
def save_csv(df, filename, columns):
with open(filename, 'w', newline='') as file:
writer = csv.writer(file)
writer.writerow(['Time', 'PV yield[kW/kWp]'])
for index, row in df.iterrows():
time_formatted = index.strftime('%H:%M')
writer.writerow([time_formatted, row[columns[1]]])
print(f'The file is written to {filename}')
def read_csv(filename):
skip_rows = list(range(1, 17))
data = pd.read_csv(filename, sep=';', skiprows=skip_rows)
return data
def process(file_name):
df = read_csv(file_name)
city = file_name.split('_')[0]
remain_column = ['Time','PV energy (AC) minus standby use ']
energy_row_name = remain_column[1]
df = df[remain_column]
df[energy_row_name] = df[energy_row_name].str.replace(',','.').astype(float)
sum_energy = df[energy_row_name].sum()
group_size = 15
df['group_id'] = df.index // group_size
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[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)
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']
for city in city_list:
print(f'Processing {city}')
file_name = f'{city}_raw.csv'
process(file_name)
print(f'Processing {city} is done\n')

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

35041
read_data/factory_power1.csv Normal file

File diff suppressed because it is too large Load Diff

16
xlsx2csv.py Normal file
View File

@@ -0,0 +1,16 @@
import pandas as pd
excel_file = 'factory_power1.xlsx'
sheet_name = 'Sheet1'
df = pd.read_excel(excel_file, sheet_name=sheet_name)
start_date = '2023-01-01'
df_power = pd.read_excel(excel_file,
header=None,
names=['FactoryPower'],
dtype={'FactoryPower': float})
times = pd.date_range(start=start_date, periods=len(df_power), freq='15min')
df_power['Time'] = times
df_power = df_power[['Time', 'FactoryPower']]
df_power.to_csv('factory_power1.csv', index=True)