import numpy as np import pandas as pd import csv import os import glob pd.options.mode.chained_assignment = None # default='warn' #load in all the houses at once path = os.getcwd() csv_files = glob.glob(os.path.join(path, "*.csv")) #put all these .csv house data files into a dictionary house_input_dict = {} for i, f in zip(range(84), csv_files): df = pd.read_csv(f) x = f.split("\\")[-1] id = x.split(".")[0] new = {id:df} house_input_dict.update(new) #load in the household assignment of disconnection period col_names = ['house_number', 'period_letter'] outage_block = pd.read_csv(r"C:\Users\mckin\Desktop\3hr Power Cuts\Disconnection Period House Assignment.csv", names=col_names, header=None) #time zones of outage outage_times_col_names = ['timeblocks', 'zone', 'index period start', 'index period end'] outage_times = pd.read_csv(r"C:\Users\mckin\Desktop\3hr Power Cuts\outage times.csv", names = outage_times_col_names, header=None) #Loading in the disconnection level scenario #This is level 1 disconnection_scenario = pd.read_csv(r"C:\Users\mckin\Desktop\3hr Power Cuts\scenario times - lvl 8.csv") daysofweek = ['Mon', 'Tue', 'Wed', 'Thurs', 'Fri', 'Sat', 'Sun'] #import house electricity tariff table headers = ['house', 'tariff'] elec_tariff = pd.read_csv(r"C:\Users\mckin\Desktop\3hr Power Cuts\House tariff.csv", names = headers, header=None) for house in house_input_dict.keys(): HouseData = house_input_dict[house] print(house) #finding the disconnection period letter for the current house in the loop x = house house_no = x.split(" -")[0] house_index = outage_block.index[outage_block['house_number'] == house_no].tolist() period = outage_block['period_letter'][house_index].item() print(house_no, 'belongs to outage block', period) #finding out the tariff of this household currently in the loop d = elec_tariff.index[elec_tariff['house'] == house_no].tolist() tariff = elec_tariff['tariff'][d].item() print(house_no, 'is on', tariff, 'tariff') blocks = disconnection_scenario[period] blocks2 = pd.DataFrame(blocks, columns=[period]) blocks2 = blocks2.dropna() blocks2['extracted'] = np.nan for i in range(len(blocks2)): value = int(blocks2[period][i].split(".")[1]) blocks2['extracted'][i] = value blocks2['day'] = np.nan for i in range(len(blocks2)): value = blocks2[period][i].split(".")[0] blocks2['day'][i] = value blocks2['index period start'] = np.nan b = -1 for i in blocks2['extracted']: b = b + 1 a = outage_times['index period start'][i-1] blocks2['index period start'][b] = a weeks = list(range(1,5)) final_headings = [] for week_no in weeks: for day in blocks2['day']: heading = day + str(week_no) final_headings.append(heading) index_list = blocks2['index period start'] list1 = np.where(index_list == 0)[0] if tariff == 'Economy 7': for i in list1: index_list[i] = index_list[i]+1 index_list = pd.concat([index_list] * 4, axis=0) #need to check if the next power outage is the immediate next 3hr slot length = (len(blocks2))-1 next_outage =[] for i in range(length): if blocks2['day'][i] == blocks2['day'][i+1]: if blocks2['index period start'][i+1] == blocks2['index period start'][i] + 6: next_outage = 1 #forcing the code to go the opportunistic charging way: next_outage = 1 affected_dict = {} if next_outage == 1: #This occurs in disconnection levels 10 & 15 print('Opportunistically Charging Regime') #probably best to just recalculate everything again from scratch (i.e. get rid of it all) outages = [] for day, index in zip(final_headings, index_list): new = day + ' ' + str(int(index)) outages.append(new) #from all the periods above, find out when the vehicles at each house can actually charge #for standard houses - easy - can just have it charge whenever an option to charge comes about #need to make a total list of all the options (1-8 for every day of week) indexs = [0, 6, 12, 18, 24, 30, 36, 42] days = ['Mon', 'Tue', 'Wed', 'Thurs', 'Fri', 'Sat', 'Sun'] weeks = [1, 2, 3, 4] possible_charging = [] for week in weeks: for day in days: for i in indexs: if tariff == 'Standard': new = day + str(week) + ' ' + str(i) else: if i == 0: i = i + 1 new = day + str(week) + ' ' + str(i) else: new = day + str(week) + ' ' + str(i) possible_charging.append(new) #now go through possible_charging, check against the excel imported scenario outages and remove if there is a match #leaving behind only the time options that a car can actually charge can_charge = list(set(possible_charging) - set(outages)) can_charge = sorted(can_charge, key=possible_charging.index) #now that we have the days and indexs when charging can occur, time to #delete the current charging energy and power columns and re-calculate #going through but they can only charge on these specific indexs #standard is the easiest - do that one first headers = [] for week in weeks: for day in days: headers.append(str(day) + str(week)) can_charge2 = [] #actualy, from the above 'can_charge' list, cross reference that list #and get rid of any of the ones which can't charge in as the car is not at home. for zone in can_charge: daynum = zone.split(' ')[0] index_start = zone.split(' ')[1] if tariff == 'Standard': index_end = int(index_start) +7 if index_end == 49: index_end = 48 else: if int(index_start) == 1: index_end = int(index_start) +6 else: index_end = int(index_start) +7 if index_end == 49: index_end = 48 #now check that cars are at home during these days and between these start and end indexs test = [] #to turn to 1 at home at all during the duration of whole #power cut (3hr duration) and so can charge at some point during it for i in range(int(index_start), int(index_end)): if HouseData[daynum + " Location Code"][i] == 0: test = 1 if test != 1: can_charge.remove(zone) for zone in can_charge: daynum = zone.split(' ')[0] index_start = zone.split(' ')[1] if tariff == 'Standard': index_end = int(index_start) +7 if index_end == 49: index_end = 48 else: if int(index_start) == 1: index_end = int(index_start) +6 else: index_end = int(index_start) +7 if index_end == 49: index_end = 48 for i in range(int(index_start), int(index_end)): can_charge2.append(daynum + ' ' + str(i)) print('The available charging times:') print(can_charge2) #now need to recalculate all the battery capacity and add in charging events #like starting EV charging model from scratch basically #day by day loop for idx, day in enumerate(headers): for i in range (1, 48): x = day + ' ' + str(i) if HouseData[day + " Charging Power"][i] == 6.6: #check it can be charging at this time first if x in can_charge2: #can charge if HouseData[day + " Location Code"][i] == 0: if HouseData[day + " Location Code"][i-1] != 0: #just got home, so charging has to wait 30 minutes HouseData[day + " Charging Energy"][i] = 0 HouseData[day + " Charging Power"][i] = 0 HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] - (HouseData[day + " Energy"][i] - HouseData[day + " Energy"][i-1]) else: if HouseData[day + " Battery Capacity"][i-1] < 29.6: HouseData[day + " Charging Energy"][i] = 3.3 HouseData[day + " Charging Power"][i] = 6.6 HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] + 3.3 if HouseData[day + " Battery Capacity"][i] >= 29.6: delta = HouseData[day + " Battery Capacity"][i] - 29.6 HouseData[day + " Charging Energy"][i] = 3.3 - delta HouseData[day + " Battery Capacity"][i] = 29.6 elif HouseData[day + " Battery Capacity"][i-1] == 29.6: HouseData[day + " Charging Energy"][i] = 0 HouseData[day + " Charging Power"][i] = 0 HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] else: #dont charge HouseData[day + " Charging Energy"][i] = 0 HouseData[day + " Charging Power"][i] = 0 if HouseData[day + " Location Code"][i] == HouseData[day + " Location Code"][i-1]: #car has not moved locations HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] else: if HouseData[day + " Energy"][i] == HouseData[day + " Energy"][i-1]: HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] else: if HouseData[day + " Battery Capacity"][i-1] > (HouseData[day + " Energy"][i] - HouseData[day + " Energy"][i-1]): HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] - (HouseData[day + " Energy"][i] - HouseData[day + " Energy"][i-1]) else: HouseData[day + " Battery Capacity"][i] = 0 else: #dont charge HouseData[day + " Charging Energy"][i] = 0 HouseData[day + " Charging Power"][i] = 0 if HouseData[day + " Location Code"][i] == HouseData[day + " Location Code"][i-1]: #car has not moved locations HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] else: if HouseData[day + " Energy"][i] == HouseData[day + " Energy"][i-1]: HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] else: if HouseData[day + " Battery Capacity"][i-1] > (HouseData[day + " Energy"][i] - HouseData[day + " Energy"][i-1]): HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] - (HouseData[day + " Energy"][i] - HouseData[day + " Energy"][i-1]) else: HouseData[day + " Battery Capacity"][i] = 0 else: #its not charging, going into the day, but can it start now at 00:30? if x in can_charge2: #can charge if HouseData[day + " Location Code"][i] == 0: if HouseData[day + " Location Code"][i-1] != 0: #just got home, so charging has to wait 30 minutes HouseData[day + " Charging Energy"][i] = 0 HouseData[day + " Charging Power"][i] = 0 HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] - (HouseData[day + " Energy"][i] - HouseData[day + " Energy"][i-1]) else: if HouseData[day + " Battery Capacity"][i-1] < 29.6: HouseData[day + " Charging Energy"][i] = 3.3 HouseData[day + " Charging Power"][i] = 6.6 HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] + 3.3 if HouseData[day + " Battery Capacity"][i] >= 29.6: delta = HouseData[day + " Battery Capacity"][i] - 29.6 HouseData[day + " Charging Energy"][i] = 3.3 - delta HouseData[day + " Battery Capacity"][i] = 29.6 elif HouseData[day + " Battery Capacity"][i-1] == 29.6: HouseData[day + " Charging Energy"][i] = 0 HouseData[day + " Charging Power"][i] = 0 HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] else: #dont charge HouseData[day + " Charging Energy"][i] = 0 HouseData[day + " Charging Power"][i] = 0 if HouseData[day + " Location Code"][i] == HouseData[day + " Location Code"][i-1]: #car has not moved locations HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] else: if HouseData[day + " Energy"][i] == HouseData[day + " Energy"][i-1]: HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] else: if HouseData[day + " Battery Capacity"][i-1] > (HouseData[day + " Energy"][i] - HouseData[day + " Energy"][i-1]): HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] - (HouseData[day + " Energy"][i] - HouseData[day + " Energy"][i-1]) else: HouseData[day + " Battery Capacity"][i] = 0 else: #cant charge HouseData[day + " Charging Energy"][i] = 0 HouseData[day + " Charging Power"][i] = 0 if HouseData[day + " Location Code"][i] == HouseData[day + " Location Code"][i-1]: #car has not moved locations HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] else: if HouseData[day + " Energy"][i] == HouseData[day + " Energy"][i-1]: HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] else: if HouseData[day + " Battery Capacity"][i-1] > (HouseData[day + " Energy"][i] - HouseData[day + " Energy"][i-1]): HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] - (HouseData[day + " Energy"][i] - HouseData[day + " Energy"][i-1]) else: HouseData[day + " Battery Capacity"][i] = 0 #Amending the state of charge column HouseData[day + " State of Charge (%)"][i] = (HouseData[day + " Battery Capacity"][i]/37)*100 #copy last line to start of next day, making sure to continue or not continue charging if day != 'Sun4': if HouseData[day + " Charging Power"][47] == 6.6: if HouseData[day + " Battery Capacity"][47] == 29.6: HouseData[headers[idx+1] + " Battery Capacity"][0] = 29.6 HouseData[headers[idx+1] + " Charging Power"][0] = 0 HouseData[headers[idx+1] + " Charging Energy"][0] = 0 else: HouseData[headers[idx+1] + " Battery Capacity"][0] = 29.6 + 3.3 if HouseData[headers[idx+1] + " Battery Capacity"][0] > 29.6: HouseData[headers[idx+1] + " Battery Capacity"][0] = 29.6 delta = HouseData[headers[idx+1] + " Battery Capacity"][0] - 29.6 HouseData[headers[idx+1] + " Charging Energy"][0] = 3.3 - delta HouseData[headers[idx+1] + " Charging Power"][0] = 6.6 else: HouseData[headers[idx+1] + " Charging Power"][0] = 6.6 HouseData[headers[idx+1] + " Charging Energy"][0] = 3.3 else: # not charging #print('on ', house, ' this is ', day, ' and the capacity being copied across is', HouseData[day + " Battery Capacity"][i-1]) HouseData[headers[idx+1] + " Battery Capacity"][0] = HouseData[day + " Battery Capacity"][47] HouseData[headers[idx+1] + " Charging Power"][0] = 0 HouseData[headers[idx+1] + " Charging Energy"][0] = 0 else: continue #Amending the state of charge column HouseData[day + " State of Charge (%)"][0] = (HouseData[day + " Battery Capacity"][0]/37)*100 else: #This is for disconnection levels 1 & 5 #check if its already charging print('This is Disconnection Level 1 or 5') for day, index in zip(final_headings, index_list): if tariff == 'Standard': for i in range(0,7): index2 = index + i if index2 >= 48: #no index 48 position continue else: if HouseData[day + " Charging Power"][index2] == 6.6: affected = {day:index} affected_dict.update(affected) else: #Economy7 for i in range(0,6): index2 = index + i if index2 >= 48: #no index 48 position continue else: if HouseData[day + " Charging Power"][index2] == 6.6: affected = {day:index} affected_dict.update(affected) if len(affected_dict) == 0: print(house, 'not affected') print('The affected charging events are:', affected_dict) #none have power outages consecutively in Level 5 Disconnection #now we know this, we can change the spreadsheet as required to account for the 3hr outages that will affect it if len(affected_dict) != 0: if tariff == 'Standard': for day in affected_dict.keys(): if affected_dict[day] <= 40: end = affected_dict[day] +7 else: end = 47 for i in range(int(affected_dict[day]), int(end)): HouseData[day + " Charging Power"][i] = 0 HouseData[day + " Charging Energy"][i] = 0 if affected_dict[day] == 0: #charging at midnight print('It was standard tariff midnight charging - need to work out this code') else: if HouseData[day + " Location Code"][i] == HouseData[day + " Location Code"][i-1]: HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] else: if HouseData[day + " Location Code"][i+1] != HouseData[day + " Location Code"][i]: HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] else: HouseData[day + " Battery Capacity"][i+1] = HouseData[day + " Battery Capacity"][i-1] - HouseData[day + " Energy"][i-1] HouseData[day + " State of Charge (%)"][i] = (HouseData[day + " Battery Capacity"][i]/37)*100 if end != 47: if HouseData[day + " Location Code"][end+1] == 0: HouseData[day + " Charging Power"][end+1] = 6.6 HouseData[day + " Charging Energy"][end+1] = 3.3 HouseData[day + " Battery Capacity"][end+1] = HouseData[day + " Battery Capacity"][end] + 3.3 else: continue if end != 47: for i in range(int(end), 48): if HouseData[day + " Location Code"][i] == 0: if HouseData[day + " Battery Capacity"][i-1] < 29.6: HouseData[day + " Charging Energy"][i] = 3.3 HouseData[day + " Charging Power"][i] = 6.6 HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] + 3.3 if HouseData[day + " Battery Capacity"][i] >= 29.6: delta = HouseData[day + " Battery Capacity"][i] - 29.6 HouseData[day + " Charging Energy"][i] = 3.3 - delta HouseData[day + " Battery Capacity"][i] = 29.6 HouseData[day + " State of Charge (%)"][i] = (HouseData[day + " Battery Capacity"][i]/37)*100 else: continue else: #its an Economy tariff household for day in affected_dict.keys(): end = affected_dict[day] +6 for i in range(int(affected_dict[day]), int(end)): if affected_dict[day] == 1: #midnight charges, starts at 00:30 if HouseData[day + " Location Code"][i] == 0: HouseData[day + " Charging Power"][i] = 0 HouseData[day + " Charging Energy"][i] = 0 HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][0] else: #the car leaves the house during the power outage with no charging at all #would need to recalculate all the capacities and SOC through the rest of the day continue HouseData[day + " State of Charge (%)"][i] = HouseData[day + " State of Charge (%)"][0] for i in range(int(end), int(end)+5): if HouseData[day + " Location Code"][i] == 0: if HouseData[day + " Battery Capacity"][i-1] < 29.6: HouseData[day + " Charging Energy"][i] = 3.3 HouseData[day + " Charging Power"][i] = 6.6 HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] + 3.3 if HouseData[day + " Battery Capacity"][i] >= 29.6: delta = HouseData[day + " Battery Capacity"][i] - 29.6 HouseData[day + " Charging Energy"][i] = 3.3 - delta HouseData[day + " Battery Capacity"][i] = 29.6 else: #doesn't fully recharge before the car has to leave the household #means will have to fully recalculate the battery capacity all through the rest of the day... if HouseData[day + " Location Code"][i+1] == HouseData[day + " Location Code"][i]: if HouseData[day + " Location Code"][i+2] != HouseData[day + " Location Code"][i]: HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] HouseData[day + " Battery Capacity"][i+1] = HouseData[day + " Battery Capacity"][i] - HouseData[day + " Energy"][i+1] HouseData[day + " Battery Capacity"][i+2] = HouseData[day + " Battery Capacity"][i+1] - (HouseData[day + " Energy"][i+2] - ouseData[day + " Energy"][i+1]) else: print('Normal scenario for going from home to work') HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] - HouseData[day + " Energy"][i] HouseData[day + " Battery Capacity"][i+1] = HouseData[day + " Battery Capacity"][i] - HouseData[day + " Energy"][i+1] else: HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][i-1] HouseData[day + " State of Charge (%)"][i] = (HouseData[day + " Battery Capacity"][i]/37)*100 else: #normal economy household but for some reason this household doesnt charge at midnight? #or the charging event is interrupted halfway through if HouseData[day + " Location Code"][i] == 0: HouseData[day + " Charging Power"][i] = 0 HouseData[day + " Charging Energy"][i] = 0 HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][int(affected_dict[day]-1)] leave = i else: #car leaves home during the power outage HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][leave] - HouseData[day + " Energy"][i] for i in range(int(end)-1, 48): HouseData[day + " Battery Capacity"][i] = HouseData[day + " Battery Capacity"][int(end)-2] - HouseData[day + " Energy"][i] newpath = r'C:\Users\mckin\Desktop\Level 8 Disconnection (Opportunistically)' if not os.path.exists(newpath): os.makedirs(newpath) HouseData.to_csv(r'C:\Users\mckin\Desktop\Level 8 Disconnection (Opportunistically)\ '+str(house)+ '.csv') print(house, 'SAVED') print('--------------------------------')