Compare commits

...

11 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
15 changed files with 245769 additions and 35118 deletions

View File

@@ -39,7 +39,8 @@ class EnergySystem:
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']
@@ -55,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生成的能量如果比工厂的需求要大

File diff suppressed because it is too large Load Diff

48
main.py
View File

@@ -1,9 +1,5 @@
#!/usr/bin/env python
# coding: utf-8
# In[ ]:
import os
import glob
import shutil
@@ -28,9 +24,6 @@ folder_path = 'plots'
clear_folder_make_ess_pv(folder_path)
# In[ ]:
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
@@ -38,10 +31,6 @@ import pandas as pd
from EnergySystem import EnergySystem
from config import pv_config, grid_config, ess_config
# In[ ]:
import json
print("Version 0.0.5")
@@ -49,9 +38,6 @@ 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)
@@ -132,9 +118,6 @@ plt.savefig('plots/demand.png')
plt.close()
# In[ ]:
def draw_results(results, filename, title_benefit, annot_benefit=False, figure_size=(10, 10)):
df=results
df = df.astype(float)
@@ -220,10 +203,6 @@ def draw_roi(costs, results, filename, title_roi, days=365, annot_roi=False, fig
plt.ylabel('PV Capacity (MW)')
plt.savefig(filename)
# In[ ]:
def draw_cost(costs, filename, title_cost, annot_cost=False, figure_size=(10, 10)):
df = costs
df = df.astype(int)
@@ -255,9 +234,6 @@ def draw_cost(costs, filename, title_cost, annot_cost=False, figure_size=(10, 10
plt.savefig(filename)
# In[ ]:
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)
@@ -305,18 +281,10 @@ def draw_overload(overload_cnt, filename, title_unmet, annot_unmet=False, figure
plt.ylabel('PV Capacity (MW)')
plt.savefig(filename)
# In[ ]:
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[ ]:
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,
@@ -341,9 +309,6 @@ def generate_data(pv_capacity, pv_cost_per_kW, pv_lifetime, pv_loss, ess_capacit
return (results, overload_cnt, costs, netto_benefit, gen_energy, energySystem.generated)
# In[ ]:
months_results = []
months_costs = []
months_overload = []
@@ -434,17 +399,11 @@ draw_overload(overload_cnt=annual_overload,
figure_size=figure_size)
# In[ ]:
def save_data(data, filename):
data.to_csv(filename+'.csv')
data.to_json(filename + '.json')
# In[ ]:
if not os.path.isdir('data'):
os.makedirs('data')
@@ -452,15 +411,8 @@ 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[ ]:
draw_results(annual_result, 'plots/test.png', 'test', False)
# In[ ]:
draw_roi(annual_costs, annual_nettos, 'plots/annual_roi.png', title_roi, 365, annot_benefit, figure_size)

View File

@@ -2,56 +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'
electricity_price_data_sell = 'electricity_price_data_sell.csv'
df_sunlight = pd.read_excel(sunlight_file_name, header=None, names=['SunlightIntensity'])
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_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)
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'
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.index = pd.to_datetime(df_power.index)
df_combined = pv_df.join(df_power)
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)
print("Electricity price data generated and saved.")
df_combined2 = df_combined.join(price_df)
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','buy', 'sell'])
writer.writerow(['time', 'PV yield[kW/kWp]', 'demand','buy', 'sell'])
cnt = 0
for index, row in df_combined3.iterrows():
time_formatted = index.strftime('%H:%M')
writer.writerow([time_formatted, row['SunlightIntensity'], row['FactoryPower'],row['ElectricityBuy'], row['ElectricitySell']])
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')

View File

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

View File

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

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)