Compare commits
	
		
			52 Commits
		
	
	
		
			ca10254c52
			...
			0.0.6
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 9f472b4bf4 | ||
|  | 127f005dcd | ||
|  | c5edf456c5 | ||
|  | d8ece46e14 | ||
|  | 566ebca6cd | ||
|  | c8c37b756c | ||
|  | 4f1a47d505 | ||
|  | ad9b5e6a19 | ||
|  | 33871fba77 | ||
|  | 9d143399ed | ||
|  | 72d4ce811e | ||
|  | 060fa5bff1 | ||
|  | ebebd2d481 | ||
|  | a330946f71 | ||
|  | 32e8e59c82 | ||
|  | c4ec4590c2 | ||
|  | cb0bd2c3e0 | ||
|  | 4364411485 | ||
|  | 54dc8b744c | ||
|  | d4fde202d0 | ||
|  | 58a7662a8b | ||
|  | d791ac481a | ||
|  | 4b72bc6fa3 | ||
|  | eb24361ea3 | ||
|  | fd3bbbf212 | ||
|  | 760cdc9c1f | ||
|  | 23826aed75 | ||
|  | 8cf3d6472c | ||
|  | c217b6309c | ||
|  | f85fcd58f2 | ||
|  | cf7a66276f | ||
|  | bf74e87ba0 | ||
|  | 2788aafbf3 | ||
|  | 30e8d968f2 | ||
|  | 8d040e64a0 | ||
|  | 202d313684 | ||
|  | da69e7e24a | ||
|  | 0f49dba47e | ||
|  | f9b7af6feb | ||
|  | f51921dd06 | ||
|  | 06808d55a1 | ||
| 1679831dbd | |||
| 651833b521 | |||
| 3bc2478cd9 | |||
| b79ffb2416 | |||
| c0a7b5beff | |||
| ed58e34e7e | |||
| 88240280ca | |||
| 09ef44fc21 | |||
| f7afee2a64 | |||
| 90c96a512a | |||
| 3cc208035a | 
							
								
								
									
										145
									
								
								EnergySystem.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								EnergySystem.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,145 @@ | |||||||
|  | from config import pv_config, ess_config, grid_config | ||||||
|  | import pandas as pd | ||||||
|  | class EnergySystem: | ||||||
|  |     def __init__(self, pv_type: pv_config, ess_type: ess_config, grid_type: grid_config): | ||||||
|  |         self.pv = pv_type | ||||||
|  |         self.ess = ess_type | ||||||
|  |         self.grid = grid_type | ||||||
|  |         self.day_generated = [] | ||||||
|  |         self.generated = 0 | ||||||
|  |         self.stored = 0 | ||||||
|  |         self.hour_stored = [] | ||||||
|  |         self.hour_stored_2 = [] | ||||||
|  |         self.afford = True | ||||||
|  |         self.cost = self.ess.get_cost() + self.pv.get_cost() | ||||||
|  |         self.overload_cnt = 0 | ||||||
|  |         self.spring_week_gen = [] | ||||||
|  |         self.summer_week_gen = [] | ||||||
|  |         self.autumn_week_gen = [] | ||||||
|  |         self.winter_week_gen = [] | ||||||
|  |         self.spring_week_soc = [] | ||||||
|  |         self.summer_week_soc = [] | ||||||
|  |         self.autumn_week_soc = [] | ||||||
|  |         self.winter_week_soc = [] | ||||||
|  |         self.granularity = 4 | ||||||
|  |         self.season_step = self.granularity * 24 * 7 * 12 | ||||||
|  |         self.season_start= self.granularity * 24 * 7 * 2 | ||||||
|  |         self.week_length = self.granularity * 24 * 7 | ||||||
|  |         self.unmet = [] | ||||||
|  |          | ||||||
|  |     def get_cost(self): | ||||||
|  |         return self.ess.get_cost()+self.pv.get_cost() | ||||||
|  |  | ||||||
|  |     # 优先使用PV供电给工厂 - 如果PV输出能满足工厂的需求,则直接供电,多余的电能用来给ESS充电。 | ||||||
|  |     # PV不足时使用ESS补充 - 如果PV输出不足以满足工厂需求,首先从ESS获取所需电量。 | ||||||
|  |     # 如果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'] | ||||||
|  |             pv_yield = row['PV yield[kW/kWp]'] | ||||||
|  |             factory_demand = row['demand'] | ||||||
|  |             electricity_price = row['buy'] | ||||||
|  |             sell_price = row['sell'] | ||||||
|  |             # electricity_price = self.grid.get_price_for_time(time) | ||||||
|  |  | ||||||
|  |             if time == '00:00': | ||||||
|  |                 self.day_generated.append(self.generated) | ||||||
|  |                 self.generated = 0 | ||||||
|  |             if time.endswith('14:00'): | ||||||
|  |                 soc = self.ess.storage / self.ess.capacity | ||||||
|  |                 self.hour_stored.append(soc) | ||||||
|  |             if time.endswith('08:00'): | ||||||
|  |                 soc = self.ess.storage / self.ess.capacity | ||||||
|  |                 self.hour_stored_2.append(soc) | ||||||
|  |  | ||||||
|  |             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生成的能量如果比工厂的需求要大 | ||||||
|  |             if generated_pv_energy >= factory_demand * time_interval: | ||||||
|  |                 # 剩余的能量(kwh) = pv生成的能量 - 工厂需求的功率 * 时间间隔  | ||||||
|  |                 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) | ||||||
|  |                 self.ess.storage += charge_to_ess | ||||||
|  |                 surplus_after_ess = surplus_energy - charge_to_ess | ||||||
|  |                 # 如果还有电量盈余,且pv功率大于ess的充电功率+工厂的需求功率则准备卖电 | ||||||
|  |                 if surplus_after_ess > 0 and generated_pv_power > self.ess.charge_power + factory_demand: | ||||||
|  |                     sold_to_grid = surplus_after_ess | ||||||
|  |                     sell_income = sold_to_grid * sell_price | ||||||
|  |                     total_benefit += sell_income | ||||||
|  |                 # 节省的能量 = 工厂需求的能量 * 时间段 | ||||||
|  |                 # total_energy = factory_demand * time_interval | ||||||
|  |                 saved_energy = factory_demand * time_interval | ||||||
|  |             # pv比工厂的需求小 | ||||||
|  |             else: | ||||||
|  |                 # 从ess中需要的电量 = 工厂需要的电量 - pv中的电量 | ||||||
|  |                 needed_from_ess = factory_demand * time_interval - generated_pv_energy | ||||||
|  |                 # 如果ess中存的电量比需要的多 | ||||||
|  |                 if self.ess.storage * 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  | ||||||
|  |                     else: | ||||||
|  |                         discharging_power = needed_from_ess / self.ess.loss | ||||||
|  |  | ||||||
|  |                     self.ess.storage -= discharging_power | ||||||
|  |                     # 节省下来的能量 = pv的能量 + 放出来的能量 | ||||||
|  |                     saved_energy = generated_pv_energy + discharging_power * self.ess.loss | ||||||
|  |                 else: | ||||||
|  |                     # 如果存的电量不够 | ||||||
|  |                     # 需要把ess中的所有电量释放出来 | ||||||
|  |                     if self.grid.capacity * time_interval + generated_pv_energy + self.ess.storage * self.ess.loss < factory_demand * time_interval: | ||||||
|  |                         self.afford = False | ||||||
|  |                         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)) | ||||||
|  |                         # 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 | ||||||
|  |                     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 | ||||||
|  |                     # grid_energy += net_grid | ||||||
|  |                     # 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 | ||||||
|  |             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 | ||||||
|  |             week_end = self.week_length + week_start | ||||||
|  |             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) | ||||||
|  |             # summer | ||||||
|  |             # week_start += self.season_step | ||||||
|  |             # week_end += self.season_step | ||||||
|  |             # if index in range(week_start, week_end): | ||||||
|  |             #     self.summer_week_gen.append(generated_pv_power) | ||||||
|  |             #     self.summer_week_soc.append(self.ess.storage / self.ess.capacity) | ||||||
|  |             # # autumn | ||||||
|  |             # week_start += self.season_step | ||||||
|  |             # week_end += self.season_step | ||||||
|  |             # if index in range(week_start, week_end): | ||||||
|  |             #     self.autumn_week_gen.append(generated_pv_power) | ||||||
|  |             #     self.autumn_week_soc.append(self.ess.storage / self.ess.capacity) | ||||||
|  |             # week_start += self.season_step | ||||||
|  |             # week_end += self.season_step | ||||||
|  |             # 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) | ||||||
							
								
								
									
										
											BIN
										
									
								
								PV&PowerConsumptionData.xlsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								PV&PowerConsumptionData.xlsx
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										19
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | # Simple PV Simulator | ||||||
|  |  | ||||||
|  | Feature list: | ||||||
|  |  | ||||||
|  | - [] Draw the entire year's electricity consumption figure. | ||||||
|  | - [] Draw the entire year's energy generation figure. | ||||||
|  | - [] Draw a heatmap of the system profit in different configurations. | ||||||
|  | ~~- []Calculate the probability of a successful run.~~ | ||||||
|  | - [] Determine whether the system can run successfully | ||||||
|  | - [] Calculate the ROI. | ||||||
|  | - [] Read the configs from the file, including `time granularity`,  | ||||||
|  |   - ess: `capacity`, `cost per kW`, `charge power`, `discharge power`, `loss` | ||||||
|  |   - pv: `capacity`, `cost per kW`, `loss` | ||||||
|  |   - grid: `capacity`, `sell price` | ||||||
|  |   - file: | ||||||
|  |     - `lightintensity.xlsx`: record the light intensity. Value in the file should be between 0 and 1 | ||||||
|  |     - `factory_power.xlsx`: record the power consumption in the factory. Default time granularity is `15min` | ||||||
|  |     - `combined_data.csv`: This file is generated by the Python script, including the `light` `intensity`, `factory_power`, `time`.  | ||||||
|  | - [] GUI. | ||||||
							
								
								
									
										
											BIN
										
									
								
								__pycache__/EnergySystem.cpython-311.pyc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								__pycache__/EnergySystem.cpython-311.pyc
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								__pycache__/config.cpython-311.pyc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								__pycache__/config.cpython-311.pyc
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										35041
									
								
								combined_data.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35041
									
								
								combined_data.csv
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										47
									
								
								config.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								config.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | |||||||
|  | { | ||||||
|  |     "pv":{  | ||||||
|  |         "loss": 0.98,  | ||||||
|  |         "cost_per_kW": 200, | ||||||
|  |         "lifetime": 15 | ||||||
|  |     }, | ||||||
|  |     "ess":{ | ||||||
|  |         "loss": 0.98, | ||||||
|  |         "cost_per_kW": 300, | ||||||
|  |         "lifetime": 8 | ||||||
|  |     }, | ||||||
|  |     "grid":{ | ||||||
|  |         "loss": 0.98, | ||||||
|  |         "sell_price": 0.2 , | ||||||
|  |         "capacity": 5000 | ||||||
|  |     }, | ||||||
|  |     "pv_capacities":{ | ||||||
|  |         "begin": 0, | ||||||
|  |         "end": 50000, | ||||||
|  |         "groups": 11  | ||||||
|  |     }, | ||||||
|  |     "ess_capacities":{ | ||||||
|  |         "begin": 0, | ||||||
|  |         "end": 100000, | ||||||
|  |         "groups":  11 | ||||||
|  |     }, | ||||||
|  |     "time_interval":{ | ||||||
|  |         "numerator": 15, | ||||||
|  |         "denominator": 60 | ||||||
|  |     }, | ||||||
|  |     "annotated": { | ||||||
|  |         "unmet_prob": false, | ||||||
|  |         "benefit": false, | ||||||
|  |         "cost": false, | ||||||
|  |         "roi": false  | ||||||
|  |     }, | ||||||
|  |     "figure_size":{ | ||||||
|  |         "height": 9, | ||||||
|  |         "length": 10 | ||||||
|  |     }, | ||||||
|  |     "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)", | ||||||
|  |         "roi": "ROI" | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										29
									
								
								config.py
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								config.py
									
									
									
									
									
								
							| @@ -1,23 +1,34 @@ | |||||||
| import pandas as pd | import pandas as pd | ||||||
| class pv_config: | class pv_config: | ||||||
|     def __init__(self, capacity, cost_per_kW, pv_lifetime, pv_loss): |     def __init__(self, capacity, cost_per_kW, lifetime, loss): | ||||||
|         self.capacity = capacity |         self.capacity = capacity | ||||||
|         self.cost_per_kW = cost_per_kW |         self.cost_per_kW = cost_per_kW | ||||||
|         self.pv_lifetime = pv_lifetime |         self.lifetime = lifetime | ||||||
|         self.pv_loss = pv_loss |         self.loss = loss | ||||||
|  |     def get_cost(self): | ||||||
|  |         return self.capacity * self.cost_per_kW | ||||||
|  |     def get_cost_per_year(self): | ||||||
|  |         return self.capacity * self.cost_per_kW / self.lifetime | ||||||
| class ess_config: | class ess_config: | ||||||
|     def __init__(self, capacity, cost_per_kW, ess_lifetime, ess_loss, charge_power, discharge_power): |     def __init__(self, capacity, cost_per_kW, lifetime, loss, charge_power, discharge_power): | ||||||
|         self.capacity = capacity |         self.capacity = capacity | ||||||
|         self.cost_per_kW = cost_per_kW |         self.cost_per_kW = cost_per_kW | ||||||
|         self.ess_lifetime = ess_lifetime |         self.lifetime = lifetime | ||||||
|         self.ess_loss = ess_loss |         self.loss = loss | ||||||
|         self.ess_storage = 0 |         self.storage = 0 | ||||||
|         self.charge_power = charge_power |         self.charge_power = charge_power | ||||||
|         self.discharge_power = discharge_power |         self.discharge_power = discharge_power | ||||||
|  |     def get_cost(self): | ||||||
|  |         return self.capacity * self.cost_per_kW | ||||||
|  |     def get_cost_per_year(self): | ||||||
|  |         return self.capacity * self.cost_per_kW / self.lifetime | ||||||
|  |  | ||||||
| class grid_config: | class grid_config: | ||||||
|     def __init__(self, price_schedule, grid_loss): |     def __init__(self, capacity, grid_loss, sell_price): | ||||||
|         self.price_schedule = price_schedule |         # self.price_schedule = price_schedule | ||||||
|  |         self.loss = grid_loss | ||||||
|  |         self.sell_price = sell_price | ||||||
|  |         self.capacity = capacity | ||||||
|      |      | ||||||
|     def get_price_for_time(self, time): |     def get_price_for_time(self, time): | ||||||
|         hour, minute = map(int, time.split(':')) |         hour, minute = map(int, time.split(':')) | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								convert.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								convert.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | import nbformat | ||||||
|  | from nbconvert import PythonExporter | ||||||
|  |  | ||||||
|  | with open('main.ipynb', "r", encoding="utf-8") as f: | ||||||
|  |     notebook = nbformat.read(f, as_version = 4) | ||||||
|  |  | ||||||
|  | exporter = PythonExporter() | ||||||
|  | python_code, _ = exporter.from_notebook_node(notebook) | ||||||
|  |  | ||||||
|  | with open('main.py', "w", encoding="utf-8") as f: | ||||||
|  |     f.write(python_code) | ||||||
							
								
								
									
										209
									
								
								draw.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										209
									
								
								draw.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,209 @@ | |||||||
|  | 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 read_data(file_name: str): | ||||||
|  |     with open(file_name, 'r') as f: | ||||||
|  |         data = json.load(f) | ||||||
|  |     for key, value in data.items(): | ||||||
|  |         for subkey, subvalue in value.items(): | ||||||
|  |             data[key][subkey] = float(subvalue) | ||||||
|  |     df = pd.DataFrame.from_dict(data, orient='index') | ||||||
|  |     df = df.T | ||||||
|  |     df.index = pd.to_numeric(df.index) | ||||||
|  |     df.columns = pd.to_numeric(df.columns) | ||||||
|  |     return df | ||||||
|  |  | ||||||
|  | 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 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)): | ||||||
|  |     df = overload_cnt | ||||||
|  |     df = (4 * 24 * 365 - df) / (4 * 24 * 365) | ||||||
|  |     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() | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     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.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%}')) | ||||||
|  |     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) | ||||||
|  |  | ||||||
|  | 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"] | ||||||
|  |  | ||||||
|  | pv_loss = js_data["pv"]["loss"] | ||||||
|  | pv_cost_per_kW = js_data["pv"]["cost_per_kW"] | ||||||
|  | pv_lifetime = js_data["pv"]["lifetime"] | ||||||
|  |  | ||||||
|  | ess_loss = js_data["ess"]["loss"] | ||||||
|  | ess_cost_per_kW = js_data["ess"]["cost_per_kW"] | ||||||
|  | ess_lifetime = js_data["ess"]["lifetime"] | ||||||
|  |  | ||||||
|  | grid_loss = js_data["grid"]["loss"] | ||||||
|  | sell_price = js_data["grid"]["sell_price"] | ||||||
|  | grid_capacity = js_data["grid"]["capacity"] | ||||||
|  |  | ||||||
|  | pv_begin = js_data["pv_capacities"]["begin"] | ||||||
|  | pv_end = js_data["pv_capacities"]["end"] | ||||||
|  | pv_groups = js_data["pv_capacities"]["groups"] | ||||||
|  |  | ||||||
|  | ess_begin = js_data["ess_capacities"]["begin"] | ||||||
|  | ess_end = js_data["ess_capacities"]["end"] | ||||||
|  | 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"] | ||||||
|  |  | ||||||
|  | title_unmet = js_data["plot_title"]["unmet_prob"] | ||||||
|  | title_cost = js_data["plot_title"]["cost"] | ||||||
|  | title_benefit = js_data["plot_title"]["benefit"] | ||||||
|  |  | ||||||
|  | figure_size = (js_data["figure_size"]["length"], js_data["figure_size"]["height"]) | ||||||
|  |  | ||||||
|  | directory = 'data/' | ||||||
|  |  | ||||||
|  | file_list = [f for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f))] | ||||||
|  |  | ||||||
|  |  | ||||||
|  | split_files = [f.split('-') for f in file_list] | ||||||
|  |  | ||||||
|  | costs_files = [f for f in split_files if f[-1].endswith('costs.json')] | ||||||
|  | print(f'find costs files: {costs_files}') | ||||||
|  | overload_files = [f for f in split_files if f[-1].endswith('overload_cnt.json')] | ||||||
|  | print(f'find coverage/unmet files: {overload_files}') | ||||||
|  | results_files = [f for f in split_files if f[-1].endswith('results.json')] | ||||||
|  | print(f'find profit/benefit files: {results_files}') | ||||||
|  |  | ||||||
|  | costs_dfs = [read_data(directory + '-'.join(f)) for f in costs_files] | ||||||
|  | overload_dfs = [read_data(directory + '-'.join(f)) for f in overload_files] | ||||||
|  | results_dfs = [read_data(directory + '-'.join(f)) for f in results_files] | ||||||
|  |  | ||||||
|  | for costs_df, overload_df, results_df in zip(costs_dfs, overload_dfs, results_dfs): | ||||||
|  |  | ||||||
|  |     draw_cost(costs_df,  | ||||||
|  |               f'plots/costs-ess-{int(costs_df.columns[0])}-{int(costs_df.columns[-1])}-pv-{int(costs_df.index[0])}-{int(costs_df.index[-1])}.png',  | ||||||
|  |               title_cost=title_cost,  | ||||||
|  |               annot_cost=annot_cost) | ||||||
|  |  | ||||||
|  |     draw_overload(overload_df,  | ||||||
|  |                   f'plots/overload-ess-{overload_df.columns[0]}-{overload_df.columns[-1]}-pv-{overload_df.index[0]}-{overload_df.index[-1]}.png',  | ||||||
|  |                   title_unmet=title_unmet,  | ||||||
|  |                   annot_unmet=False) | ||||||
|  |  | ||||||
|  |     draw_results(results_df,  | ||||||
|  |                  f'plots/results-ess-{results_df.columns[0]}-{results_df.columns[-1]}-pv-{results_df.index[0]}-{results_df.index[-1]}.png',  | ||||||
|  |                  title_benefit=title_benefit, | ||||||
|  |                  annot_benefit=False) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										
											BIN
										
									
								
								factory_power.xlsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								factory_power.xlsx
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								factory_power1.xlsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								factory_power1.xlsx
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								lightintensity.xlsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								lightintensity.xlsx
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										534
									
								
								main.ipynb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										534
									
								
								main.ipynb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,534 @@ | |||||||
|  | { | ||||||
|  |  "cells": [ | ||||||
|  |   { | ||||||
|  |    "cell_type": "code", | ||||||
|  |    "execution_count": null, | ||||||
|  |    "metadata": {}, | ||||||
|  |    "outputs": [], | ||||||
|  |    "source": [ | ||||||
|  |     "import os\n", | ||||||
|  |     "import glob\n", | ||||||
|  |     "import shutil\n", | ||||||
|  |     "import matplotlib.pyplot as plt\n", | ||||||
|  |     "import matplotlib.ticker as ticker\n", | ||||||
|  |     "from matplotlib.ticker import FuncFormatter\n", | ||||||
|  |     "import numpy as np\n", | ||||||
|  |     "import pandas as pd\n", | ||||||
|  |     "import os\n", | ||||||
|  |     "import seaborn as sns\n", | ||||||
|  |     "import json\n", | ||||||
|  |     "from matplotlib.colors import LinearSegmentedColormap\n", | ||||||
|  |     "\n", | ||||||
|  |     "def clear_folder_make_ess_pv(folder_path):\n", | ||||||
|  |     "    if os.path.isdir(folder_path):\n", | ||||||
|  |     "        shutil.rmtree(folder_path)\n", | ||||||
|  |     "    os.makedirs(folder_path)\n", | ||||||
|  |     "    os.makedirs(os.path.join(folder_path,'ess'))\n", | ||||||
|  |     "    os.makedirs(os.path.join(folder_path,'pv'))\n", | ||||||
|  |     "\n", | ||||||
|  |     "folder_path = 'plots'\n", | ||||||
|  |     "clear_folder_make_ess_pv(folder_path)" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "code", | ||||||
|  |    "execution_count": null, | ||||||
|  |    "metadata": {}, | ||||||
|  |    "outputs": [], | ||||||
|  |    "source": [ | ||||||
|  |     "import matplotlib.pyplot as plt\n", | ||||||
|  |     "import seaborn as sns\n", | ||||||
|  |     "import numpy as np\n", | ||||||
|  |     "import pandas as pd\n", | ||||||
|  |     "from EnergySystem import EnergySystem\n", | ||||||
|  |     "from config import pv_config, grid_config, ess_config\n" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "code", | ||||||
|  |    "execution_count": null, | ||||||
|  |    "metadata": {}, | ||||||
|  |    "outputs": [], | ||||||
|  |    "source": [ | ||||||
|  |     "import json\n", | ||||||
|  |     "\n", | ||||||
|  |     "print(\"Version 0.0.5\")\n", | ||||||
|  |     "\n", | ||||||
|  |     "with open('config.json', 'r') as f:\n", | ||||||
|  |     "    js_data = json.load(f)\n", | ||||||
|  |     "\n", | ||||||
|  |     "\n", | ||||||
|  |     "    \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", | ||||||
|  |     "pv_lifetime = js_data[\"pv\"][\"lifetime\"]\n", | ||||||
|  |     "\n", | ||||||
|  |     "ess_loss = js_data[\"ess\"][\"loss\"]\n", | ||||||
|  |     "ess_cost_per_kW = js_data[\"ess\"][\"cost_per_kW\"]\n", | ||||||
|  |     "ess_lifetime = js_data[\"ess\"][\"lifetime\"]\n", | ||||||
|  |     "\n", | ||||||
|  |     "grid_loss = js_data[\"grid\"][\"loss\"]\n", | ||||||
|  |     "sell_price = js_data[\"grid\"][\"sell_price\"] #kWh\n", | ||||||
|  |     "grid_capacity = js_data[\"grid\"][\"capacity\"] #kWh\n", | ||||||
|  |     "\n", | ||||||
|  |     "pv_begin = js_data[\"pv_capacities\"][\"begin\"]\n", | ||||||
|  |     "pv_end = js_data[\"pv_capacities\"][\"end\"]\n", | ||||||
|  |     "pv_groups = js_data[\"pv_capacities\"][\"groups\"]\n", | ||||||
|  |     "\n", | ||||||
|  |     "ess_begin = js_data[\"ess_capacities\"][\"begin\"]\n", | ||||||
|  |     "ess_end = js_data[\"ess_capacities\"][\"end\"]\n", | ||||||
|  |     "ess_groups = js_data[\"ess_capacities\"][\"groups\"]\n", | ||||||
|  |     "\n", | ||||||
|  |     "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", | ||||||
|  |     "data = pd.read_csv('combined_data.csv')\n", | ||||||
|  |     "\n", | ||||||
|  |     "granularity = js_data[\"time_interval\"][\"numerator\"]\n", | ||||||
|  |     "\n", | ||||||
|  |     "months_days = [31,28,31,30,31,30,31,31,30,31,30,31]\n", | ||||||
|  |     "def get_month_coe(num, granularity):\n", | ||||||
|  |     "    return 60 / granularity * 24 * months_days[num]\n", | ||||||
|  |     "\n", | ||||||
|  |     "months_index = [get_month_coe(num, granularity) for num in range(12)]\n", | ||||||
|  |     "months_data = []\n", | ||||||
|  |     "for i in range(1,12):\n", | ||||||
|  |     "    months_index[i] += months_index[i-1]\n", | ||||||
|  |     "for i in range(12):\n", | ||||||
|  |     "    start = 0 if i == 0 else months_index[i-1]\n", | ||||||
|  |     "    end = months_index[i]\n", | ||||||
|  |     "    months_data.append(data.iloc[int(start):int(end)])\n", | ||||||
|  |     "    \n", | ||||||
|  |     "\n", | ||||||
|  |     "\n", | ||||||
|  |     "\n", | ||||||
|  |     "pv_capacities = np.linspace(pv_begin, pv_end, pv_groups)\n", | ||||||
|  |     "ess_capacities = np.linspace(ess_begin, ess_end, ess_groups)\n", | ||||||
|  |     "# results = pd.DataFrame(index=pv_capacities, columns= ess_capacities)\n", | ||||||
|  |     "# affords = 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" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "code", | ||||||
|  |    "execution_count": null, | ||||||
|  |    "metadata": {}, | ||||||
|  |    "outputs": [], | ||||||
|  |    "source": [ | ||||||
|  |     "hour_demand = []\n", | ||||||
|  |     "for index, row in data.iterrows():\n", | ||||||
|  |     "    time = row['time']\n", | ||||||
|  |     "    demand = row['demand']\n", | ||||||
|  |     "    if time.endswith('00'):\n", | ||||||
|  |     "        hour_demand.append(demand)\n", | ||||||
|  |     "plt.figure(figsize=(10,8))\n", | ||||||
|  |     "plt.plot(hour_demand)\n", | ||||||
|  |     "plt.ylabel('Demand Power / kW')\n", | ||||||
|  |     "plt.savefig('plots/demand.png')\n", | ||||||
|  |     "plt.close()" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "code", | ||||||
|  |    "execution_count": null, | ||||||
|  |    "metadata": {}, | ||||||
|  |    "outputs": [], | ||||||
|  |    "source": [ | ||||||
|  |     "def draw_results(results, filename, title_benefit, annot_benefit=False, figure_size=(10, 10)):\n", | ||||||
|  |     "    df=results\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", | ||||||
|  |     "    max_scale = max(abs(min_value/1000), abs(max_value/1000))\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/1000)\n", | ||||||
|  |     "\n", | ||||||
|  |     "    cmap = sns.color_palette(\"coolwarm\", as_cmap=True)\n", | ||||||
|  |     "    plt.figure(figsize=figure_size)\n", | ||||||
|  |     "    ax = sns.heatmap(df/1000, fmt=\".1f\", cmap=cmap, vmin=-max_scale, vmax=max_scale, 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_benefit)\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, | ||||||
|  |    "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, | ||||||
|  |    "metadata": {}, | ||||||
|  |    "outputs": [], | ||||||
|  |    "source": [ | ||||||
|  |     "def draw_cost(costs, filename, title_cost, annot_cost=False, figure_size=(10, 10)):\n", | ||||||
|  |     "    df = costs\n", | ||||||
|  |     "    df = df.astype(int)\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", | ||||||
|  |     "\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", | ||||||
|  |     "    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 / 1000000)\n", | ||||||
|  |     "\n", | ||||||
|  |     "    plt.figure(figsize=figure_size)\n", | ||||||
|  |     "    ax = sns.heatmap(df/1000000,  fmt=\".1f\", cmap='viridis', annot=annot_cost)\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_cost)\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, | ||||||
|  |    "metadata": {}, | ||||||
|  |    "outputs": [], | ||||||
|  |    "source": [ | ||||||
|  |     "def draw_overload(overload_cnt, filename, title_unmet, annot_unmet=False, figure_size=(10, 10), days=365, granularity=15):\n", | ||||||
|  |     "    df = overload_cnt\n", | ||||||
|  |     "    print(days, granularity)\n", | ||||||
|  |     "    coef = 60 / granularity * days * 24\n", | ||||||
|  |     "    print(coef)\n", | ||||||
|  |     "    print(df)\n", | ||||||
|  |     "    df = ( coef - df) / coef\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", | ||||||
|  |     "\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", | ||||||
|  |     "    # print(new_Data)\n", | ||||||
|  |     "    df = pd.concat([df, new_Data])\n", | ||||||
|  |     "\n", | ||||||
|  |     "\n", | ||||||
|  |     "    plt.figure(figsize=figure_size)\n", | ||||||
|  |     "    cmap = LinearSegmentedColormap.from_list(\"\", [\"white\", \"blue\"])\n", | ||||||
|  |     "    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.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", | ||||||
|  |     "    def fmt(x, pos):\n", | ||||||
|  |     "        return '{:.0f}%'.format(x * 100)\n", | ||||||
|  |     "    CS = ax.contour(X, Y, df,  colors='black', alpha=0.5)\n", | ||||||
|  |     "\n", | ||||||
|  |     "    ax.clabel(CS, inline=True, fontsize=10, fmt=FuncFormatter(fmt))\n", | ||||||
|  |     "\n", | ||||||
|  |     "    plt.xlim(0, df.shape[1] - 1)\n", | ||||||
|  |     "    plt.ylim(0, df.shape[0] - 1)\n", | ||||||
|  |     "    plt.title(title_unmet)\n", | ||||||
|  |     "    plt.xlabel('ESS Capacity (MWh)')\n", | ||||||
|  |     "    plt.ylabel('PV Capacity (MW)')\n", | ||||||
|  |     "    plt.savefig(filename)" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "code", | ||||||
|  |    "execution_count": null, | ||||||
|  |    "metadata": {}, | ||||||
|  |    "outputs": [], | ||||||
|  |    "source": [ | ||||||
|  |     "def cal_profit(es: EnergySystem, saved_money, days):\n", | ||||||
|  |     "    profit = saved_money - es.ess.get_cost_per_year() / 365 * days - es.pv.get_cost_per_year() / 365 * days\n", | ||||||
|  |     "    return profit" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "code", | ||||||
|  |    "execution_count": null, | ||||||
|  |    "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", | ||||||
|  |     "    pv = pv_config(capacity=pv_capacity, \n", | ||||||
|  |     "                    cost_per_kW=pv_cost_per_kW,\n", | ||||||
|  |     "                    lifetime=pv_lifetime, \n", | ||||||
|  |     "                    loss=pv_loss)\n", | ||||||
|  |     "    ess = ess_config(capacity=ess_capacity, \n", | ||||||
|  |     "                        cost_per_kW=ess_cost_per_kW, \n", | ||||||
|  |     "                        lifetime=ess_lifetime, \n", | ||||||
|  |     "                        loss=ess_loss,\n", | ||||||
|  |     "                        charge_power=ess_capacity,\n", | ||||||
|  |     "                        discharge_power=ess_capacity)\n", | ||||||
|  |     "    grid = grid_config(capacity=grid_capacity, \n", | ||||||
|  |     "                        grid_loss=grid_loss,\n", | ||||||
|  |     "                        sell_price= sell_price)\n", | ||||||
|  |     "    energySystem = EnergySystem(pv_type=pv, \n", | ||||||
|  |     "                                ess_type=ess, \n", | ||||||
|  |     "                                grid_type= grid)\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, netto_benefit, gen_energy, energySystem.generated)\n" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "code", | ||||||
|  |    "execution_count": null, | ||||||
|  |    "metadata": {}, | ||||||
|  |    "outputs": [], | ||||||
|  |    "source": [ | ||||||
|  |     "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, 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}-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}-month-{index+1}-unmet.png',\n", | ||||||
|  |     "                    title_unmet=title_unmet,\n", | ||||||
|  |     "                    annot_unmet=annot_unmet,\n", | ||||||
|  |     "                    figure_size=figure_size,\n", | ||||||
|  |     "                    days=months_days[index],\n", | ||||||
|  |     "                    granularity=granularity)\n", | ||||||
|  |     "\n", | ||||||
|  |     "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", | ||||||
|  |     "    for ess_capacity in ess_capacities:\n", | ||||||
|  |     "        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", | ||||||
|  |     "        title_cost=title_cost,\n", | ||||||
|  |     "        annot_cost=annot_cost,\n", | ||||||
|  |     "        figure_size=figure_size)\n", | ||||||
|  |     "draw_results(results=annual_result,\n", | ||||||
|  |     "                filename='plots/annual_benefit.png',\n", | ||||||
|  |     "                title_benefit=title_benefit,\n", | ||||||
|  |     "                annot_benefit=annot_benefit,\n", | ||||||
|  |     "                figure_size=figure_size)\n", | ||||||
|  |     "draw_overload(overload_cnt=annual_overload,\n", | ||||||
|  |     "                filename='plots/annual_unmet.png',\n", | ||||||
|  |     "                title_unmet=title_unmet,\n", | ||||||
|  |     "                annot_unmet=annot_unmet,\n", | ||||||
|  |     "                figure_size=figure_size)" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "code", | ||||||
|  |    "execution_count": null, | ||||||
|  |    "metadata": {}, | ||||||
|  |    "outputs": [], | ||||||
|  |    "source": [ | ||||||
|  |     "def save_data(data, filename):\n", | ||||||
|  |     "    data.to_csv(filename+'.csv')\n", | ||||||
|  |     "    data.to_json(filename + '.json')" | ||||||
|  |    ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |    "cell_type": "code", | ||||||
|  |    "execution_count": null, | ||||||
|  |    "metadata": {}, | ||||||
|  |    "outputs": [], | ||||||
|  |    "source": [ | ||||||
|  |     "if not os.path.isdir('data'):\n", | ||||||
|  |     "    os.makedirs('data')\n", | ||||||
|  |     "\n", | ||||||
|  |     "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" | ||||||
|  |    ] | ||||||
|  |   } | ||||||
|  |  ], | ||||||
|  |  "metadata": { | ||||||
|  |   "kernelspec": { | ||||||
|  |    "display_name": "Python 3", | ||||||
|  |    "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 | ||||||
|  | } | ||||||
							
								
								
									
										419
									
								
								main.py
									
									
									
									
									
								
							
							
						
						
									
										419
									
								
								main.py
									
									
									
									
									
								
							| @@ -1 +1,418 @@ | |||||||
| import matplotlib | #!/usr/bin/env python | ||||||
|  | # coding: utf-8 | ||||||
|  | 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): | ||||||
|  |         shutil.rmtree(folder_path) | ||||||
|  |     os.makedirs(folder_path) | ||||||
|  |     os.makedirs(os.path.join(folder_path,'ess')) | ||||||
|  |     os.makedirs(os.path.join(folder_path,'pv')) | ||||||
|  |  | ||||||
|  | folder_path = 'plots' | ||||||
|  | clear_folder_make_ess_pv(folder_path) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | import matplotlib.pyplot as plt | ||||||
|  | import seaborn as sns | ||||||
|  | import numpy as np | ||||||
|  | import pandas as pd | ||||||
|  | from EnergySystem import EnergySystem | ||||||
|  | from config import pv_config, grid_config, ess_config | ||||||
|  |  | ||||||
|  | import json | ||||||
|  |  | ||||||
|  | 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) | ||||||
|  |  | ||||||
|  | pv_loss = js_data["pv"]["loss"] | ||||||
|  | pv_cost_per_kW = js_data["pv"]["cost_per_kW"] | ||||||
|  | pv_lifetime = js_data["pv"]["lifetime"] | ||||||
|  |  | ||||||
|  | ess_loss = js_data["ess"]["loss"] | ||||||
|  | ess_cost_per_kW = js_data["ess"]["cost_per_kW"] | ||||||
|  | ess_lifetime = js_data["ess"]["lifetime"] | ||||||
|  |  | ||||||
|  | grid_loss = js_data["grid"]["loss"] | ||||||
|  | sell_price = js_data["grid"]["sell_price"] #kWh | ||||||
|  | grid_capacity = js_data["grid"]["capacity"] #kWh | ||||||
|  |  | ||||||
|  | pv_begin = js_data["pv_capacities"]["begin"] | ||||||
|  | pv_end = js_data["pv_capacities"]["end"] | ||||||
|  | pv_groups = js_data["pv_capacities"]["groups"] | ||||||
|  |  | ||||||
|  | ess_begin = js_data["ess_capacities"]["begin"] | ||||||
|  | ess_end = js_data["ess_capacities"]["end"] | ||||||
|  | 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) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # In[ ]: | ||||||
|  |  | ||||||
|  |  | ||||||
|  | hour_demand = [] | ||||||
|  | for index, row in data.iterrows(): | ||||||
|  |     time = row['time'] | ||||||
|  |     demand = row['demand'] | ||||||
|  |     if time.endswith('00'): | ||||||
|  |         hour_demand.append(demand) | ||||||
|  | plt.figure(figsize=(10,8)) | ||||||
|  | plt.plot(hour_demand) | ||||||
|  | plt.ylabel('Demand Power / kW') | ||||||
|  | plt.savefig('plots/demand.png') | ||||||
|  | plt.close() | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 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) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # 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 | ||||||
|  |  | ||||||
|  | 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) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 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: | ||||||
|  |         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) | ||||||
|  |  | ||||||
|  | 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) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # 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 | ||||||
|  |  | ||||||
|  | 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) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def save_data(data, filename): | ||||||
|  |     data.to_csv(filename+'.csv') | ||||||
|  |     data.to_json(filename + '.json') | ||||||
|  |  | ||||||
|  | if not os.path.isdir('data'): | ||||||
|  |     os.makedirs('data') | ||||||
|  |  | ||||||
|  | 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) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | draw_roi(annual_costs, annual_nettos, 'plots/annual_roi.png',  title_roi, 365, annot_benefit, figure_size) | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										19
									
								
								old/generate_electricity_price.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								old/generate_electricity_price.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | import pandas as pd | ||||||
|  | import numpy as np | ||||||
|  |  | ||||||
|  | start_date = '2023-01-01' | ||||||
|  | end_date = '2024-01-01' | ||||||
|  |  | ||||||
|  | # 创建时间索引 | ||||||
|  | time_index = pd.date_range(start=start_date, end=end_date, freq='15min') | ||||||
|  |  | ||||||
|  | # 生成电价数据,假设电价在0.28到0.32欧元/kWh之间波动 | ||||||
|  | price_data = np.random.uniform(0.28, 0.32, len(time_index)) | ||||||
|  |  | ||||||
|  | # 创建DataFrame | ||||||
|  | price_df = pd.DataFrame(data={'Time': time_index, 'ElectricityPrice': price_data}) | ||||||
|  |  | ||||||
|  | # 保存到CSV文件 | ||||||
|  | price_df.to_csv('electricity_price_data.csv', index=False) | ||||||
|  |  | ||||||
|  | print("Electricity price data generated and saved.") | ||||||
							
								
								
									
										56
									
								
								old/generatedata.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								old/generatedata.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | |||||||
|  | import pandas as pd | ||||||
|  | import numpy as np | ||||||
|  |  | ||||||
|  | # 设置随机种子以重现结果 | ||||||
|  | np.random.seed(43) | ||||||
|  |  | ||||||
|  | def simulate_sunlight(hour, month): | ||||||
|  |     # 假设最大日照强度在正午,根据月份调整最大日照强度 | ||||||
|  |     max_intensity = 1.0  # 夏季最大日照强度 | ||||||
|  |     if month in [12, 1, 2]:  # 冬季 | ||||||
|  |         max_intensity = 0.6 | ||||||
|  |     elif month in [3, 4, 10, 11]:  # 春秋 | ||||||
|  |         max_intensity = 0.8 | ||||||
|  |      | ||||||
|  |     # 计算日照强度,模拟早晚日照弱,中午日照强 | ||||||
|  |     intensity = max_intensity * np.sin(np.pi * (hour - 6) / 12)**2 if 6 <= hour <= 18 else 0 | ||||||
|  |     return intensity | ||||||
|  |  | ||||||
|  | def simulate_factory_demand(hour, day_of_week): | ||||||
|  |     # 周末工厂需求可能减少 | ||||||
|  |     if day_of_week in [5, 6]:  # 周六和周日 | ||||||
|  |         base_demand = 3000 | ||||||
|  |     else: | ||||||
|  |         base_demand = 6000 | ||||||
|  |      | ||||||
|  |     # 日常波动 | ||||||
|  |     if 8 <= hour <= 20: | ||||||
|  |         return base_demand + np.random.randint(100, 200)  # 白天需求量大 | ||||||
|  |     else: | ||||||
|  |         return base_demand - np.random.randint(0, 100)  # 夜间需求量小 | ||||||
|  |  | ||||||
|  | def generate_data(days=10): | ||||||
|  |     records = [] | ||||||
|  |     month_demand = 0 | ||||||
|  |     for day in range(days): | ||||||
|  |         month = (day % 365) // 30 + 1 | ||||||
|  |         day_of_week = day % 7 | ||||||
|  |         day_demand = 0 | ||||||
|  |         for hour in range(24): | ||||||
|  |             for minute in [0, 10, 20, 30, 40, 50]: | ||||||
|  |                 time = f'{hour:02d}:{minute:02d}' | ||||||
|  |                 sunlight = simulate_sunlight(hour, month) | ||||||
|  |                 demand = simulate_factory_demand(hour, day_of_week) | ||||||
|  |                 day_demand+=demand | ||||||
|  |                 records.append({'time': time, 'sunlight': sunlight, 'demand': demand}) | ||||||
|  |         print(f"day:{day}, day_demand: {day_demand}") | ||||||
|  |         month_demand += day_demand | ||||||
|  |         if day%30 == 0: | ||||||
|  |             print(f"month:{month}, month_demand:{month_demand}") | ||||||
|  |             month_demand = 0 | ||||||
|  |     return pd.DataFrame(records) | ||||||
|  |  | ||||||
|  | # 生成数据 | ||||||
|  | data = generate_data(365)  # 模拟一年的数据 | ||||||
|  | data.to_csv('simulation_data.csv', index=False) | ||||||
|  | print("Data generated and saved to simulation_data.csv.") | ||||||
							
								
								
									
										24
									
								
								old/generatepriceschedule.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								old/generatepriceschedule.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | import pandas as pd | ||||||
|  | import numpy as np | ||||||
|  |  | ||||||
|  | def generate_price_schedule(): | ||||||
|  |     records = [] | ||||||
|  |     # 假设一天分为三个时段:谷时、平时、峰时 | ||||||
|  |     times = [('00:00', '06:00', 0.25),   | ||||||
|  |              ('06:00', '18:00', 0.3),   | ||||||
|  |              ('18:00', '24:00', 0.35)]   | ||||||
|  |      | ||||||
|  |     # 随机调整每天的电价以增加现实性 | ||||||
|  |     for time_start, time_end, base_price in times: | ||||||
|  |         # 随机浮动5%以内 | ||||||
|  |         fluctuation = np.random.uniform(-0.005, 0.005) | ||||||
|  |         price = round(base_price + fluctuation, 3) | ||||||
|  |         records.append({'time_start': time_start, 'time_end': time_end, 'price': price}) | ||||||
|  |      | ||||||
|  |     return pd.DataFrame(records) | ||||||
|  |  | ||||||
|  | # 生成电价计划 | ||||||
|  | price_schedule = generate_price_schedule() | ||||||
|  | price_schedule.to_csv('price_schedule.csv', index=False) | ||||||
|  | print("Price schedule generated and saved to price_schedule.csv.") | ||||||
|  | print(price_schedule) | ||||||
							
								
								
									
										4
									
								
								old/price_schedule.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								old/price_schedule.csv
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | time_start,time_end,price | ||||||
|  | 00:00,06:00,0.247 | ||||||
|  | 06:00,18:00,0.3 | ||||||
|  | 18:00,24:00,0.349 | ||||||
| 
 | 
							
								
								
									
										52561
									
								
								old/simulation_data.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52561
									
								
								old/simulation_data.csv
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										39
									
								
								read_data.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								read_data.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  | import pandas as pd | ||||||
|  | import numpy as np | ||||||
|  | import 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' | ||||||
|  |  | ||||||
|  | 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) | ||||||
|  | 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', '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['PV yield[kW/kWp]'], row['FactoryPower'],row['ElectricityBuy'], row['ElectricitySell']]) | ||||||
|  |          | ||||||
|  |     print('The file is written to combined_data.csv') | ||||||
|  |  | ||||||
|  |  | ||||||
|  | print("Simulation data with electricity prices has been updated and saved.") | ||||||
							
								
								
									
										35041
									
								
								read_data/Berlin.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35041
									
								
								read_data/Berlin.csv
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										35041
									
								
								read_data/Cambodge.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35041
									
								
								read_data/Cambodge.csv
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										35041
									
								
								read_data/Marcedonia.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35041
									
								
								read_data/Marcedonia.csv
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										35041
									
								
								read_data/Riyahd.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35041
									
								
								read_data/Riyahd.csv
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										35041
									
								
								read_data/Serbia.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35041
									
								
								read_data/Serbia.csv
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										372
									
								
								read_data/convert_data.ipynb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										372
									
								
								read_data/convert_data.ipynb
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										79
									
								
								read_data/convert_data.py
									
									
									
									
									
										Normal 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') | ||||||
|  |  | ||||||
							
								
								
									
										35041
									
								
								read_data/electricity_price_data.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35041
									
								
								read_data/electricity_price_data.csv
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										35041
									
								
								read_data/electricity_price_data_sell.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35041
									
								
								read_data/electricity_price_data_sell.csv
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										35041
									
								
								read_data/factory_power1.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35041
									
								
								read_data/factory_power1.csv
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										16
									
								
								xlsx2csv.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								xlsx2csv.py
									
									
									
									
									
										Normal 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) | ||||||
		Reference in New Issue
	
	Block a user