Source code for procsimulator.CommunityManager

from abc import ABC, abstractmethod
import pandas as pd
import os
import math
import shutil
import errno
import datetime
from Input import Input
import numpy as np


[docs]class CommunityManager(ABC):
[docs] def calculate_bin_used_capacity(self, bins_capacities, placed_timeslots, production_baseload, n_bins_per_hour): """ Updates the bin capacity for the second part of the optimization (increases the production_baseload to the bin capacity of the first part, and subtracts the energy of the placed timeslots in the first step. Args: bins_capacities: bin capacities of the bins in the 1st step of the optimization placed_timeslots: placed timeslots in the 1st step (in order to subtract the energy of them to the bin capacity) - if they are placed, the bin capacity decreases production_baseload: value to increment in the bin capacities, which corresponds to the value of energy that can be acquired from the grid in the 2nd step n_bins_per_hour: number of bins per hour (parameter of the strategy) to know the quantity of bins in a day (e.g. if bins of 30 minutes, n_bins_per_hour = 2) Returns: array with x positions in a day (where the number of positions is 24*n_bins_per_hour) with the bin capacity of each bin """ binUsedCapacity = [0] * 24 * n_bins_per_hour for bin in range(len(bins_capacities)): binUsedCapacity[bin] = bins_capacities[bin] binUsedCapacity[bin] += production_baseload for timeslot in placed_timeslots: tm = timeslot.split("-") weight = float(tm[2]) bin = int(tm[3]) - 1 # bin 1 is 0 position (00:00-00:59) binUsedCapacity[bin] -= weight return binUsedCapacity
[docs] def get_production_max_after_first_optimization(self, netload_second_optim, fd, production_baseload, n_bins_per_hour, fact): """ Calculates the maximum production peak for each bin of the second step (calculates the maximum in the netload dataframe after updating the profiles of 1st step, and have to increase the production_baseload and decrease the energy of the placed timeslots of the 1st step) Args: netload_second_optim: dataframe which contains the netload after updating the profiles of the 1st step (to calculate the maximum peak in the 2nd step) fd: consumption profile date (to production_baseload: value to increment in the bin capacities, which corresponds to the value of energy that can be acquired from the grid in the 2nd step n_bins_per_hour: number of bins per hour (parameter of the strategy) to know the quantity of bins in a day (e.g. if bins of 30 minutes, n_bins_per_hour = 2) fact: minutes of each bin (e.g. if bins of 30 minutes, fact = 30) Returns: array with x positions in a day (where the number of positions is 24*n_bins_per_hour) with the bin maximum production peak of each bin """ bins_maximum_second_optimization = [] for z in range(0, 24): startMin = 0 endMin = fact - 1 for w in range(0, n_bins_per_hour): max = netload_second_optim[ (netload_second_optim['Date'] >= str(fd) + ' ' + str(z).zfill(2) + ':' + str(startMin).zfill(2) + ':00') & ( netload_second_optim['Date'] <= str(fd) + ' ' + str(z).zfill(2) + ':' + str(endMin).zfill(2) + ':00')][ 'Production'].max() # demand when the production is max binUsage = netload_second_optim.loc[netload_second_optim[ (netload_second_optim['Date'] >= str(fd) + ' ' + str(z).zfill(2) + ':' + str(startMin).zfill(2) + ':00') & ( netload_second_optim['Date'] <= str(fd) + ' ' + str(z).zfill(2) + ':' + str(endMin).zfill(2) + ':00')][ 'Production'].idxmax()]["Demand"] bins_maximum_second_optimization.append(max + production_baseload - binUsage) startMin = startMin + fact endMin = endMin + fact return bins_maximum_second_optimization
[docs] def remove_flexible_consumption(self): """ Removes the flexible consumption of the consumption profile, in order to have the baseload consumption (that consumption that can not be shifted. In order to do this, the consumption of the flexible appliances are subtracted from the netload and community dataframes (notice that each flexible has it own consumption profile for each house) Returns: netload dataframe with the non-flexible consumption """ flexible_timeslots = self.cg.get_timeslots(self.cg.get_community(), True) df_community = pd.read_csv(self.path_steps_after_first + '/community.csv', sep=';') # Header=None to indicate that the first row is data and not colummn names df_community.columns = ['Date', 'Power'] df_netload = pd.read_csv(self.path_steps_after_first + '/netload.csv', sep=';') # Header=None to indicate that the first row is data and not colummn names df_netload.columns = ['Date', 'Demand', 'PV_Production', 'Wind_Production', 'Production', 'Netload'] for timeslot in flexible_timeslots: df_appliance = pd.read_csv(self.path_steps_after_first + '/house' + str(timeslot["House"]) + '/' + timeslot["Appliance"] + ".csv", sep=';') # Header=None to indicate that the first row is data and not colummn names df_appliance.columns = ['Date', 'Power'] df_total = pd.read_csv(self.path_steps_after_first + '/house' + str(timeslot["House"]) + '/total.csv', sep=';') # Header=None to indicate that the first row is data and not colummn names df_total.columns = ['Date', 'Power'] start_obj = datetime.datetime.strptime(timeslot["Start"], '%Y-%m-%d %H:%M:%S') # Convert string to datetime object end_obj = datetime.datetime.strptime(timeslot["End"], '%Y-%m-%d %H:%M:%S') # Convert string to datetime object obj = start_obj while (obj != end_obj + datetime.timedelta(minutes=1)): # Update house total consumption indexTotal = df_total[df_total.Date == str(obj)].index # Get index of the row df_total.loc[indexTotal, 'Power'] = float(df_total[df_total.Date == str(obj)]["Power"]) - float(df_appliance[df_appliance.Date == str(obj)]["Power"]) # Update community consumption indexCommunity = df_community[df_community.Date == str(obj)].index # Get index of the row df_community.loc[indexCommunity, 'Power'] = float(df_community[df_community.Date == str(obj)]["Power"]) - float(df_appliance[df_appliance.Date == str(obj)]["Power"]) # Update community netload indexNetload = df_netload[df_netload.Date == str(obj)].index # Get index of the row df_netload.loc[indexNetload, 'Demand'] = float(df_netload[df_netload.Date == str(obj)]["Demand"]) - float(df_appliance[df_appliance.Date == str(obj)]["Power"]) # Update appliance consumption - has to be the last update since the others dataframes use this dataframe indexAppliance = df_appliance[df_appliance.Date == str(obj)].index # Get index of the row df_appliance.loc[indexAppliance, 'Power'] = 0 obj = obj + datetime.timedelta(minutes=1) # Next minute # After all minutes of the appliance updated output_directory = os.path.join('', self.path_steps_after_first + '/house' + str(timeslot["House"])) outname = os.path.join(output_directory, str(timeslot["Appliance"]) + '.csv') df_appliance.to_csv(outname, columns=['Date', 'Power'], sep=";", index=False) outname = os.path.join(output_directory, 'total.csv') df_total.to_csv(outname, columns=['Date', 'Power'], sep=";", index=False) output_directory = os.path.join('', self.path_steps_after_first) outname = os.path.join(output_directory, 'community.csv') df_community.to_csv(outname, columns=['Date', 'Power'], sep=";", index=False) outname = os.path.join(output_directory, 'netload.csv') df_netload.to_csv(outname, columns=['Date', 'Demand', 'PV_Production', 'Wind_Production', 'Production', 'Netload'], sep=";", index=False) return df_netload
[docs] def create_profiles_after_strategy(self, placed_timeslots, all_timeslots_objects, initial_path, final_path, short_initial_path, short_final_path, remove_flex_cons, n_bins_per_hour, fact): """ Implementing the abstract function (from the parent) which updates the profiles after applying the strategy. Args: placed_timeslots: array of the placed timeslots all_timeslots_objects: array of all timeslots with all the information (Start, End, Appliance, Power, House, etc) initial_path: path of the minutes (1/60Hz) dataframe (e.g. "(...)/output/minute") final_path: path of the dataframe after the strategy (e.g. "(...)/output/afteroptimization") short_initial_path: folder of the minutes (1/60Hz) dataframe (e.g. "minutes") short_final_path: folder of the dataframe after the strategy e.g. "afteroptimization") remove_flex_cons: if True, the flexible consumption will be removed, otherwise the flexible consumption will not be removed (in 1st step, it was True to remove the flexible consumption and in the 2nd step it was False because the flexible consumption has already been removed) n_bins_per_hour: number of bins per hour (parameter of the strategy) to know the quantity of bins in a day (e.g. if bins of 30 minutes, n_bins_per_hour = 2) fact: minutes of each bin (e.g. if bins of 30 minutes, fact = 30) Returns: output of update_consumption_profiles_based_on_optimization function """ return self.update_consumption_profiles_based_on_optimization(placed_timeslots, all_timeslots_objects, initial_path, final_path, short_initial_path, short_final_path, remove_flex_cons, n_bins_per_hour, fact)
[docs] def update_consumption_profiles_based_on_optimization(self, placed_timeslots, all_timeslots_objects, initial_path, final_path, short_initial_path, short_final_path, remove_flex_cons, n_bins_per_hour, fact): """ Implementing the function which updates the profiles after applying the strategy. Args: placed_timeslots: array of the placed timeslots all_timeslots_objects: array of all timeslots with all the information (Start, End, Appliance, Power, House, etc) initial_path: path of the minutes (1/60Hz) dataframe (e.g. "(...)/output/minute") final_path: path of the dataframe after the strategy (e.g. "(...)/output/afteroptimization") short_initial_path: folder of the minutes (1/60Hz) dataframe (e.g. "minutes") short_final_path: folder of the dataframe after the strategy e.g. "afteroptimization") remove_flex_cons: if True, the flexible consumption will be removed, otherwise the flexible consumption will not be removed (in 1st step, it was True to remove the flexible consumption and in the 2nd step it was False because the flexible consumption has already been removed) n_bins_per_hour: number of bins per hour (parameter of the strategy) to know the quantity of bins in a day (e.g. if bins of 30 minutes, n_bins_per_hour = 2) fact: minutes of each bin (e.g. if bins of 30 minutes, fact = 30) Returns: array with 2 positions: array of the placed timeslots [0] and flexible dataframe [1] """ # Remove all files of the folder and the folder (before copying the consumption profiles) if os.path.exists(final_path): shutil.rmtree(final_path) # Create the folder if not os.path.exists(final_path): os.mkdir(final_path) # Copy the consumption profiles to after optimization folder in order to change it consumption after the optimization of the timeslots try: src_files = os.listdir(initial_path) for file_name in src_files: full_file_name = os.path.join(initial_path, file_name) if os.path.isfile(full_file_name): shutil.copy(full_file_name, final_path) elif os.path.isdir(full_file_name): shutil.copytree(full_file_name, full_file_name.replace(short_initial_path, short_final_path)) except OSError as e: if e.errno != errno.EEXIST: raise # community profile # communityBefore = pd.read_csv('output/minute/community.csv', sep=';') # Header=None to indicate that the first row is data and not colummn names # communityBefore.columns = ['Date', 'Power'] df_flexible = "" if (remove_flex_cons): df_flexible = self.remove_flexible_consumption() #showNetloadGraph(finalPath + '/netload.csv') community_after = pd.read_csv(final_path + '/community.csv', sep=';') # Header=None to indicate that the first row is data and not colummn names community_after.columns = ['Date', 'Power'] netload_after = pd.read_csv(final_path + '/netload.csv', sep=';') # Header=None to indicate that the first row is data and not colummn names netload_after.columns = ['Date', 'Demand', 'PV_Production', 'Wind_Production', 'Production', 'Netload'] # Reset community consumption #community_after['Power'] = 0 #netload_after['Demand'] = 0 placed_appliances = [] placed_houses = [] placed_timeslots_array = [] for timeslot in placed_timeslots: timeslot = timeslot.split("-") first_item_date = str(int(timeslot[5])-1) timeslot_number = int(float(timeslot[0])) timeslot_sub_item_number = int(float(timeslot[1])) timeslot_power = float(timeslot[2]) timeslot_first_bin = str(int(timeslot[3]) - 1) # bin 1 corresponds to midnight, bin 2 corresponds to 1 am, etc timeslot_number_of_bins = timeslot[4] timeslot_last_bin = str(int(float(first_item_date)) + (int(float(timeslot_number_of_bins)) - 1)) timeslot_bin_before_opt = str(int(float(timeslot[7])) - 1) # Gets all the fields of the timeslot (Start, End, Appliance, House, etc) timeslot_obj = all_timeslots_objects[timeslot_number] # If a timeslot is placed, all the subitemms are placed # each house consumption profile # total_before = pd.read_csv('output/minute/house' + str(timeslotObj["House"]) + '/total.csv', sep=';') # total_before.columns = ['Date', 'Power'] total_after = pd.read_csv(final_path + '/house' + str(timeslot_obj["House"]) + '/total.csv', sep=';') total_after.columns = ['Date', 'Power'] # Reset all houses consumption #if (str(timeslot_obj["House"]) not in placed_houses): #total_after['Power'] = 0 #placed_houses.append(str(timeslot_obj["House"])) # each appliance consumption profile (of a specific house) df_before = pd.read_csv(self.path_steps_minutes + '/house' + str(timeslot_obj["House"]) + '/' + timeslot_obj["Appliance"] + ".csv", sep=';') # Header=None to indicate that the first row is data and not colummn names df_before.columns = ['Date', 'Power'] df_after = pd.read_csv(final_path + '/house' + str(timeslot_obj["House"]) + '/' + timeslot_obj["Appliance"] + ".csv", sep=';') # Header=None to indicate that the first row is data and not colummn names df_after.columns = ['Date', 'Power'] # Reset all appliance consumption #if ((str(timeslot_obj["House"]) + "-" + str(timeslot_obj["Appliance"])) not in placed_appliances): #dfAfter['Power'] = 0 #placed_appliances.append(str(timeslot_obj["House"]) + "-" + str(timeslot_obj["Appliance"])) # when there's more than one item of a timeslot: # 1) if its the first hour - starts at the first minutes of the timeslot and ends at 59 miutes # 2) if its a middle hour (not the first and not the last) - starts at 00 minutes and ends at 59 minutes # 3) if its the last hour - starts at 00 and ends at the last minutes of the timeslot # e.g. timeslot from 8.53 to 10.15: # hour 8 (bin 9) -> 08:53 (original) - 08:59 (first) # hour 9 (bin 10) -> 09:00 - 09:59 (middle) # hour 10 (bin 11) -> 10:00 - 10:15 (original) (last) tim_new_hour = int(math.floor(int(timeslot_first_bin)/n_bins_per_hour)) tim_new_min = int((int(timeslot_first_bin)%n_bins_per_hour)*fact) tim_old_hour = int(math.floor(int(timeslot_bin_before_opt)/n_bins_per_hour)) tim_old_min = int((int(timeslot_bin_before_opt) % n_bins_per_hour) * fact) if (int(timeslot_number_of_bins) > 1): if (int(first_item_date) == int(timeslot_first_bin)): timeslot_start_date = str(timeslot_obj["Start"]) timeslot_end_date = str(timeslot_obj["Start"])[0:11] + str(tim_old_hour).zfill(2) + ":" + str(tim_old_min + (fact - 1)).zfill(2) + ":00" new_optimization_start_date = str(timeslot_obj["Start"])[0:11] + str(tim_new_hour).zfill(2) + ":" + str(int(tim_new_min+(fact-1)) - (int(tim_old_min+(fact-1))-int(timeslot_obj["Start"][14:16]))).zfill(2) + ":00" new_optimization_end_date = str(timeslot_obj["Start"])[0:11] + str(tim_new_hour).zfill(2) + ":" + str(tim_new_min + (fact - 1)).zfill(2) + ":00" elif (int(timeslot_first_bin) == int(timeslot_last_bin)): timeslot_start_date = str(timeslot_obj["Start"])[0:11] + str(tim_old_hour).zfill(2) + ":" + str(tim_old_min).zfill(2) + ":00" timeslot_end_date = str(timeslot_obj["End"]) new_optimization_start_date = str(timeslot_obj["Start"])[0:11] + str(tim_new_hour).zfill(2) + ":" + str(tim_new_min).zfill(2) + ":00" new_optimization_end_date = str(timeslot_obj["Start"])[0:11] + str(tim_new_hour).zfill(2) + ":" + str(int(tim_new_min) + (int(timeslot_obj["End"][14:16])-int(tim_old_min))).zfill(2) + ":00" else: timeslot_start_date = str(timeslot_obj["Start"])[0:11] + str(tim_old_hour).zfill(2) + ":" + str(tim_old_min).zfill(2) + ":00" timeslot_end_date = str(timeslot_obj["Start"])[0:11] + str(tim_old_hour).zfill(2) + ":" + str(tim_old_min + (fact - 1)).zfill(2) + ":00" new_optimization_start_date = str(timeslot_obj["Start"])[0:11] + str(tim_new_hour).zfill(2) + ":" + str(tim_new_min).zfill(2) + ":00" new_optimization_end_date = str(timeslot_obj["Start"])[0:11] + str(tim_new_hour).zfill(2) + ":" + str(tim_new_min + (fact - 1)).zfill(2) + ":00" else: timeslot_start_date = str(timeslot_obj["Start"]) timeslot_end_date = str(timeslot_obj["End"]) new_optimization_start_date = str(timeslot_obj["Start"])[0:11] + str(tim_new_hour).zfill(2) + ":" + str(int(tim_new_min + (fact - 1)) - (int(tim_old_min + (fact - 1)) - int(timeslot_obj["Start"][14:16]))).zfill(2) + ":00" new_optimization_end_date = str(timeslot_obj["Start"])[0:11] + str(tim_new_hour).zfill(2) + ":" + str(int(tim_new_min) + (int(timeslot_obj["End"][14:16]) - int(tim_old_min))).zfill(2) + ":00" # list of placed timeslots placed_timeslots_array.append(str(timeslot_obj["House"]) + "*" + str(timeslot_obj["Appliance"]) + "*" + str(timeslot_number) + "*" + str(new_optimization_start_date) + "*" + str(new_optimization_end_date)) # before optimization (original) start_obj_before = datetime.datetime.strptime(timeslot_start_date, '%Y-%m-%d %H:%M:%S') # Convert string to datetime object end_obj_before = datetime.datetime.strptime(timeslot_end_date, '%Y-%m-%d %H:%M:%S') # Convert string to datetime object obj_before = start_obj_before # after optimization start_obj_after = datetime.datetime.strptime(new_optimization_start_date, '%Y-%m-%d %H:%M:%S') # Convert string to datetime object end_obj_after = datetime.datetime.strptime(new_optimization_end_date, '%Y-%m-%d %H:%M:%S') # Convert string to datetime object obj_after = start_obj_after while (obj_after != end_obj_after + datetime.timedelta(minutes=1)): index_netload_after = netload_after[netload_after.Date == str(obj_after)].index # Get index of the row index_after = community_after[community_after.Date == str(obj_after)].index # Get index of the row index_total_after = total_after[total_after.Date == str(obj_after)].index # sGet index of the row index_app_after = df_after[df_after.Date == str(obj_after)].index # Get index of the row netload_after.loc[index_netload_after, 'Demand'] = float(netload_after[netload_after.Date == str(obj_after)]["Demand"]) + float(df_before[df_before.Date == str(obj_before)]["Power"]) # Subtract the energy of that timeslot from the community energy netload_after.loc[netload_after['Production'] < 0, 'Production'] = 0 community_after.loc[index_after, 'Power'] = float(community_after[community_after.Date == str(obj_after)]["Power"]) + float(df_before[df_before.Date == str(obj_before)]["Power"]) # Subtract the energy of that timeslot from the community energy total_after.loc[index_total_after, 'Power'] = float(total_after[total_after.Date == str(obj_after)]["Power"]) + float(df_before[df_before.Date == str(obj_before)]["Power"]) # Subtract the energy of that timeslot from the total energy of that house (the house which corresponds the timeslot) df_after.loc[index_app_after, 'Power'] = float(df_after[df_after.Date == str(obj_after)]["Power"]) + float(df_before[df_before.Date == str(obj_before)]["Power"]) # Subtract the energy of that timeslot from the total energy of that house (the house which corresponds the timeslot) obj_before = obj_before + datetime.timedelta(minutes=1) # Next minute obj_after = obj_after + datetime.timedelta(minutes=1) # Next minute # After while - when the consumption profile is updated for each minute of the timeslot output_directory = os.path.join('', final_path + '/house' + str(timeslot_obj["House"])) outname = os.path.join(output_directory, str(timeslot_obj["Appliance"]) + '.csv') df_after.to_csv(outname, columns=['Date', 'Power'], sep=";", index=False) # After all timeslots updated - update the total of each house output_directory = os.path.join('', final_path + '/house' + str(timeslot_obj["House"])) outname = os.path.join(output_directory, 'total.csv') df_after.to_csv(outname, columns=['Date', 'Power'], sep=";", index=False) netload_after["Netload"] = netload_after["Demand"] - netload_after["Production"] # After all timeslots updated - update the community profile output_directory = os.path.join('', final_path) outname = os.path.join(output_directory, 'community.csv') community_after.to_csv(outname, columns=['Date', 'Power'], sep=";", index=False) # After all timeslots updated - update the community profile outname = os.path.join(output_directory, 'netload.csv') netload_after.to_csv(outname, columns=['Date', 'Demand', 'PV_Production', 'Wind_Production', 'Production', 'Netload'], sep=";", index=False) return [placed_timeslots_array, df_flexible]
[docs] def prepare_inputs(self, fact, save_to_file = False, import_prices_hour = [], export_prices_hour = []): """ Prepares the inputs for the optimization problem. :return: """ netload = pd.read_csv(self.path_steps_minutes + '/netload.csv', sep=';') # Header=None to indicate that the first row is data and not colummn names netload.columns = ['Date', 'Demand', 'PV_Production', 'Wind_Production', 'Production', 'Netload'] # Plotd # netload.plot(x="Date", y=["Demand", "Production", "Netload"], kind="line", figsize=(10, 10)) # plt.show() fd = str(netload.iloc[0]["Date"])[0:10] bins_capacities = [] bins_maximum = [] bins_export_prices = [] bins_import_prices = [] houses_production = [] n_bins_per_hour = int(60 / fact) # Default values (one value per bin - depends on the number of bins of the day) if (len(import_prices_hour) != 24*n_bins_per_hour): print("There are no enough import prices for each bin. Default values will be used.") import_prices_hour = [0.0] * 24*n_bins_per_hour if (len(export_prices_hour) != 24*n_bins_per_hour): print("There are no enough export prices for each bin. Default values will be used.") export_prices_hour = [0.0] * 24*n_bins_per_hour for z in range(0, 24): startMin = 0 endMin = fact - 1 for w in range(0, n_bins_per_hour): tmp_prod = [] for index, house in enumerate(self.cg.get_community()): prod = pd.read_csv(self.path_steps_minutes + '/house' + str(index) + '/energy.csv', sep=';') prod.columns = ['Date', 'Power'] prod_avg = prod[ (prod['Date'] >= str(fd) + ' ' + str(z).zfill(2) + ':' + str(startMin).zfill(2) + ':00') & ( netload['Date'] <= str(fd) + ' ' + str(z).zfill(2) + ':' + str(endMin).zfill(2) + ':00')][ 'Power'].mean() tmp_prod.append(prod_avg) houses_production.append(tmp_prod) avg = netload[ (netload['Date'] >= str(fd) + ' ' + str(z).zfill(2) + ':' + str(startMin).zfill(2) + ':00') & ( netload['Date'] <= str(fd) + ' ' + str(z).zfill(2) + ':' + str(endMin).zfill(2) + ':00')][ 'Production'].mean() max = netload[ (netload['Date'] >= str(fd) + ' ' + str(z).zfill(2) + ':' + str(startMin).zfill(2) + ':00') & ( netload['Date'] <= str(fd) + ' ' + str(z).zfill(2) + ':' + str(endMin).zfill(2) + ':00')][ 'Production'].max() bins_capacities.append(avg) #bins_capacities.append(avg+5000) bins_maximum.append(max) bins_export_prices.append(export_prices_hour[z]) bins_import_prices.append(import_prices_hour[z]) startMin = startMin + fact endMin = endMin + fact self.timeslots = self.cg.get_timeslots(self.cg.get_community(), True) community = self.cg.get_community() appliances_flexibility = {"DISHWASHER": 12, "VACUUMCLEANER": 8, "WASHINGMACHINE": 10, "DRYER": 5, "IRON": 5, "COOKINGSTOVE": 1} # appliances_flexibility = {"DISHWASHER": 12, "VACUUMCLEANER": 12, "WASHINGMACHINE": 12, "DRYER": 12, "IRON": 12, "COOKINGSTOVE": 12} flexibilities_array = self.cg.get_community_flexibility(community) contracted_power = self.cg.calculate_contracted_power(community) house_items = [ [] for i in range(len(community))] house_items_max = [ [] for i in range(len(community))] house_items_date = [ [] for i in range(len(community))] house_items_num = [ [] for i in range(len(community))] house_items_flex = [ [] for i in range(len(community))] house_s_soc = [ [] for i in range(len(community))] house_s_min = [ [] for i in range(len(community))] house_s_max = [ [] for i in range(len(community))] if (save_to_file): dates = [] items = [] items_max = [] timeslot_numbers = [] count = 0 flexibilities = [] print("Timeslots List") for timeslot in self.timeslots: print(timeslot) # Fill timeslots (with subitems) array df = pd.read_csv(self.path_steps_minutes + '/house' + str(timeslot['House']) + '/' + timeslot['Appliance'] + ".csv", sep=';') # Header=None to indicate that the first row is data and not colummn names df.columns = ['Date', 'Power'] df = df[:24 * 60 * 60] # Only the first day is important (24 hours * 60 minutes * 60 seconds) # df = df.fillna(0) # fills nan with 0 # Fill dates array start_hour = int(str(timeslot['Start'])[11:13]) end_hour = int(str(timeslot['End'])[11:13]) start_date = str(timeslot['Start'])[0:10] start_minute = int(str(timeslot['Start'])[14:16]) end_minute = int(str(timeslot['End'])[14:16]) hour = start_hour temp_date = [] temp_tim = [] temp_num = [] temp_max = [] temp_flex = [] while (hour <= end_hour): for w in range(0, n_bins_per_hour): if (n_bins_per_hour > 1): # for example, if we have bins of 30 minutes and the startMinute is 30 or higher, then we just have the second bin of that hour if (w != n_bins_per_hour - 1 and hour == start_hour and start_minute >= fact * (w + 1)): continue if (hour == end_hour and end_minute < fact * w): continue if (hour == start_hour and start_minute < fact * (w + 1) and start_minute >= fact * w): start = start_minute else: start = w * fact if (hour == end_hour and fact * (w + 1) >= end_minute): end = end_minute elif (hour == start_hour and w == 0): end = fact - 1 else: end = (w + 1) * fact - 1 duration_in_minutes = end - start + 1 tim = (df[(df['Date'] >= str(start_date) + ' ' + str(hour).zfill(2) + ':' + str(start).zfill(2) + ':00') & ( df['Date'] <= str(start_date) + ' ' + str(hour).zfill(2) + ':' + str(end).zfill(2) + ':00')][ 'Power'].mean()) * (duration_in_minutes / 60) max = df[(df['Date'] >= str(start_date) + ' ' + str(hour).zfill(2) + ':' + str(start).zfill(2) + ':00') & ( df['Date'] <= str(start_date) + ' ' + str(hour).zfill(2) + ':' + str(end).zfill(2) + ':00')][ 'Power'].max() temp_date.append((hour * n_bins_per_hour) + w + 1) # 10 am corresponds to bin 11 temp_tim.append(tim) temp_max.append(max) temp_num.append(count) temp_flex.append(flexibilities_array[int(timeslot['House'])] * appliances_flexibility[timeslot['Appliance']]) hour = hour + 1 # Individual houses inputs house_items[int(timeslot["House"])].append(temp_tim) house_items_max[int(timeslot["House"])].append(temp_max) house_items_date[int(timeslot["House"])].append(temp_date) house_items_num[int(timeslot["House"])].append(temp_num) house_items_flex[int(timeslot["House"])].append(temp_flex) dates.append(temp_date) items.append(temp_tim) items_max.append(temp_max) timeslot_numbers.append(temp_num) flexibilities.append(temp_flex) count = count + 1 df = pd.DataFrame(flexibilities) df.to_csv('inputs/flexibilities.csv', index=False) df = pd.DataFrame(dates) df.to_csv('inputs/dates.csv', index=False) df = pd.DataFrame(items) df.to_csv('inputs/items.csv', index=False) df = pd.DataFrame(items_max) df.to_csv('inputs/items_max.csv', index=False) df = pd.DataFrame(timeslot_numbers) df.to_csv('inputs/timeslot_numbers.csv', index=False) df = pd.DataFrame(houses_production) df.to_csv('inputs/houses_production.csv', index=False) for index, house in enumerate(community): df = pd.DataFrame(house_items[index]) df.to_csv(self.path_steps_minutes + '/house' + str(index) + '/house_items.csv', index=False) df = pd.DataFrame(house_items_max[index]) df.to_csv(self.path_steps_minutes + '/house' + str(index) + '/house_items_max.csv', index=False) df = pd.DataFrame(house_items_date[index]) df.to_csv(self.path_steps_minutes + '/house' + str(index) + '/house_items_date.csv', index=False) df = pd.DataFrame(house_items_num[index]) df.to_csv(self.path_steps_minutes + '/house' + str(index) + '/house_items_num.csv', index=False) df = pd.DataFrame(house_items_flex[index]) df.to_csv(self.path_steps_minutes + '/house' + str(index) + '/house_items_flex.csv', index=False) else: flexibilities = pd.read_csv('inputs/flexibilities.csv') flexibilities = flexibilities.to_numpy() flexibilities = [[x for x in y if not np.isnan(x)] for y in flexibilities] dates = pd.read_csv('inputs/dates.csv') dates = dates.to_numpy() dates = [[x for x in y if not np.isnan(x)] for y in dates] items = pd.read_csv('inputs/items.csv') items = items.to_numpy() items = [[x for x in y if not np.isnan(x)] for y in items] items_max = pd.read_csv('inputs/items_max.csv') items_max = items_max.to_numpy() items_max = [[x for x in y if not np.isnan(x)] for y in items_max] timeslot_numbers = pd.read_csv('inputs/timeslot_numbers.csv') timeslot_numbers = timeslot_numbers.to_numpy() timeslot_numbers = [[x for x in y if not np.isnan(x)] for y in timeslot_numbers] houses_production = pd.read_csv('inputs/houses_production.csv') houses_production = houses_production.to_numpy() houses_production = [[x for x in y if not np.isnan(x)] for y in houses_production] for index, house in enumerate(community): try: df = pd.read_csv(self.path_steps_minutes + '/house' + str(index) + '/house_items.csv') house_items[index] = df.to_numpy() house_items[index] = [[x for x in y if not np.isnan(x)] for y in house_items[index]] except: house_items[index] = [] try: df = pd.read_csv(self.path_steps_minutes + '/house' + str(index) + '/house_items_max.csv') house_items_max[index] = df.to_numpy() house_items_max[index] = [[x for x in y if not np.isnan(x)] for y in house_items_max[index]] except: house_items_max[index] = [] try: df = pd.read_csv(self.path_steps_minutes + '/house' + str(index) + '/house_items_date.csv') house_items_date[index] = df.to_numpy() house_items_date[index] = [[x for x in y if not np.isnan(x)] for y in house_items_date[index]] except: house_items_date[index] = [] try: df = pd.read_csv(self.path_steps_minutes + '/house' + str(index) + '/house_items_num.csv') house_items_num[index] = df.to_numpy() house_items_num[index] = [[x for x in y if not np.isnan(x)] for y in house_items_num[index]] except: house_items_num[index] = [] try: df = pd.read_csv(self.path_steps_minutes + '/house' + str(index) + '/house_items_flex.csv') house_items_flex[index] = df.to_numpy() house_items_flex[index] = [[x for x in y if not np.isnan(x)] for y in house_items_flex[index]] except: house_items_flex[index] = [] for index, house in enumerate(community): df = pd.read_csv(self.path_steps_minutes + '/house' + str(index) + '/house_s.csv', sep=";") house_s_soc[index] = df.to_numpy()[:,0] * 1000 house_s_soc[index] = [x for x in house_s_soc[index]] df = pd.read_csv(self.path_steps_minutes + '/house' + str(index) + '/house_s.csv', sep=";") house_s_min[index] = df.to_numpy()[:,1] * 1000 house_s_min[index] = [x for x in house_s_min[index]] df = pd.read_csv(self.path_steps_minutes + '/house' + str(index) + '/house_s.csv', sep=";") house_s_max[index] = df.to_numpy()[:,2] * 1000 house_s_max[index] = [x for x in house_s_max[index]] num_houses = len(community) # Storage Inputs storage_df = pd.read_csv('inputs/s_inputs.csv') s_initial_soc = storage_df.to_numpy()[:,0] * 1000 s_min = storage_df.to_numpy()[:,1] * 1000 s_max = storage_df.to_numpy()[:,2] * 1000 print("Community Flexibilities:") print(flexibilities) print("Bin Capacities:") print(bins_capacities) print("Bin Maximum:") print(bins_maximum) print("Dates:") print(dates) print("Timeslots:") print(items) print("Timeslots Maximum:") print(items_max) print("Numbers:") print(timeslot_numbers) print("Storage Max") print(s_max) print("Storage Min") print(s_min) print("Storage Initial SOC") print(s_initial_soc) print("Houses Production:") print(houses_production) print("Export Price:") print(bins_export_prices) print("Import Price:") print(bins_import_prices) print("Timeslots (Individual):") print(house_items) print("Timeslots Maximum (Individual):") print(house_items_max) print("Dates (Individual):") print(house_items_date) print("Numbers (Individual):") print(house_items_num) print("Flexibilities (Individual):") print(house_items_flex) print("S SOC (Individual):") print(house_s_soc) print("S Max (Individual):") print(house_s_max) print("S Min (Individual):") print(house_s_min) res = Input(contracted_power, fd, dates, items, bins_capacities, timeslot_numbers, bins_maximum, items_max, n_bins_per_hour, flexibilities, bins_export_prices, bins_import_prices, s_max, s_min, s_initial_soc, num_houses, houses_production, house_items, house_items_max, house_items_date, house_items_num, house_items_flex, house_s_soc, house_s_max, house_s_min) return res
[docs] @abstractmethod def execute(self, *args): """ This function should be implemented in a class which inherits from this one. This goal is to define all the steps necessary to implement the provided strategy which will allow to do a good management of the renewable resources of the community. Args: args: can have as many arguments as you want """ pass