Source code for models.fleet_EV_load_simulator.scripts.main

from pathlib import Path
import pandas as pd
from ... import utils
from .ev_component_gen import (generate_vehicle_trip_population_distribution_df, 
                               generate_vehicle_trip_region_distribution_df,
                               create_uncoordinated_components,
                               create_coordinated_components,
                               create_v2g_components)

import warnings
warnings.filterwarnings("ignore")

utils.print_update(level=1,message="Initializing EV Fleet load component simulator...")

print_level_base=2


[docs] def get_pypsa_ev_components(start_date:str, end_date:str, ev_charging:str, ev_population:float): # Description: main script for creating a cutout of the modelled region # creating the hydro cutout based on hydro site locations and the basins they are located within # and each basins upstream basins. # Configuration inputs: config_file = Path("models/fleet_EV_load_simulator/config/config.yaml") # (i) read needed data # Load configuration file here # NOTE: I will update this likely to pull from my own configuration file later # NOTE: Please make it a yaml utils.print_update(level=print_level_base,message="Loading EV fleet scenario configuration...") cfg = utils.load_config(config_file) # load some params called by multiple functions start_date_sim_str = start_date end_date_sim_str = end_date p_nom_per_charger = float(cfg["p_nom_per_charger"]) ev_population = float(ev_population) trip_distribution = cfg["trip_distribution"] # Accessing is generally: cfg["outter_key"]["inner_key"] # string for ev penetration scenario ev_pen_str = str(int(ev_population * 100)) utils.print_update(level=print_level_base+1,message=f"Setting up ev-penetration scenario : {ev_pen_str}") # (1) load_data here: # use config for file paths # df_tp_i = pd.read_csv(cfg['tp_path']) df_tp_i = pd.read_csv(cfg['travel_pattern_path']) utils.print_update(level=print_level_base+1,message=f"Travel pattern data loaded from {cfg['travel_pattern_path']}") # df_battery = pd.read_csv(cfg["battery_path"]) df_battery = pd.read_csv(cfg["EV_typical_range"]) utils.print_update(level=print_level_base+1,message=f"EV typical range data loaded from {cfg['EV_typical_range']}") df_cvc = pd.read_csv(cfg["cvc_path"]) df_pvc = pd.read_csv(cfg["pvc_path"]) utils.print_update(level=print_level_base+1,message=f"Regional vehicle count data loaded from {cfg['cvc_path']} and {cfg['pvc_path']}") utils.print_update(level=print_level_base+2,message="Cleaning regional vehicle count data...") # Combine commercial and residential vehicle fleets total_vehicles_df = pd.merge(df_cvc, df_pvc, on=['Regional District', 'Representative Vehicle'], how='outer') total_vehicles_df.fillna(0, inplace=True) total_vehicles_df['Vehicle Count'] = ev_population * (total_vehicles_df["Vehicle Count_x"] + total_vehicles_df["Vehicle Count_y"]) df_tvc = total_vehicles_df[df_pvc.columns.tolist()].copy() # (2) Functions to create table of all trips needed: # Use the gen-load-ts-uncoordinated.ipynb for a starting point since # we made updates since the other file was used. # redesign ts_template_gen to take inputs of a start_time: "2019-03-10 00:00:00" # and an end_time as "2019-03-17 23:00:00" # These should come from the configuration file utils.print_update(level=print_level_base,message=f"Processing Trip distribution for : {trip_distribution}") if trip_distribution == "population": df_final = generate_vehicle_trip_population_distribution_df(df_tvc, df_tp_i, df_battery, start_date_sim_str, end_date_sim_str) elif trip_distribution == "region": df_final = generate_vehicle_trip_region_distribution_df(df_tvc, df_tp_i, df_battery, start_date_sim_str, end_date_sim_str) else: utils.print_update(level=print_level_base+1 ,message="ERROR: Trip distribution method must be specified as either 'population' or 'region'!", alert=True) # (3) Load timeseries dictionary generation function: # (4) save pickle date of the pypsa ready dictionaries to results/pypsa-components/ # NOTE: Need 3 different functions once for each charging strategy # charge_strat = cfg["charging"].lower() charge_strat=ev_charging.lower() utils.print_update(level=print_level_base,message=f"Processing scenario data for charging strategy : {charge_strat}") if charge_strat == "uncoordinated": utils.print_update(level=print_level_base+1,message=f"Creating pypsa components for charging strategy :{charge_strat}") load_fpath = cfg["ev_prefix_path"] + charge_strat + "_"+ev_pen_str + "_" + cfg["ev_load_path"] create_uncoordinated_components(df_final, df_battery, start_date_sim_str, end_date_sim_str, load_fpath, p_nom_per_charger) elif charge_strat == "coordinated": utils.print_update(level=print_level_base+1,message=f"Creating pypsa components for charging strategy :{charge_strat}") load_fpath = cfg["ev_prefix_path"] + charge_strat + "_"+ev_pen_str + "_" + cfg["ev_load_path"] bus_fpath = cfg["ev_prefix_path"] + charge_strat + "_"+ev_pen_str + "_" + cfg["ev_bus_path"] charger_fpath = cfg["ev_prefix_path"] + charge_strat + "_"+ev_pen_str + "_" + cfg["ev_charger_path"] discharger_fpath = cfg["ev_prefix_path"] + charge_strat +"_"+ ev_pen_str + "_" + cfg["ev_discharger_path"] battery_fpath = cfg["ev_prefix_path"] + charge_strat + "_"+ev_pen_str + "_" + cfg["ev_battery_path"] create_coordinated_components(df_final, df_battery, start_date_sim_str, end_date_sim_str, cfg['ev_battery_cyclic'], cfg['ev_battery_initial_frac'], p_nom_per_charger, load_fpath, bus_fpath, charger_fpath, battery_fpath) elif charge_strat == "v2g": utils.print_update(level=print_level_base+1,message=f"Creating pypsa components for charging strategy :{charge_strat}") load_fpath = cfg["ev_prefix_path"] + charge_strat +"_"+ ev_pen_str + "_" + cfg["ev_load_path"] bus_fpath = cfg["ev_prefix_path"] + charge_strat + "_"+ev_pen_str + "_" + cfg["ev_bus_path"] charger_fpath = cfg["ev_prefix_path"] + charge_strat +"_"+ ev_pen_str + "_" + cfg["ev_charger_path"] discharger_fpath = cfg["ev_prefix_path"] + charge_strat + "_"+ev_pen_str + "_" + cfg["ev_discharger_path"] battery_fpath = cfg["ev_prefix_path"] + charge_strat + "_"+ev_pen_str + "_" + cfg["ev_battery_path"] create_v2g_components(df_final, df_battery, start_date_sim_str, end_date_sim_str, cfg['ev_battery_cyclic'], cfg['ev_battery_initial_frac'], p_nom_per_charger, cfg['p_nom_per_discharger'], load_fpath, bus_fpath, charger_fpath, discharger_fpath, battery_fpath) # elif 'hybrid' in charge_strat: # utils.print_update(level=print_level_base+1,message=f"Creating pypsa components for charging strategy :{charge_strat}") # charge_strat_main = "coordinated" # ev_pen_str_main=ev_pen_str # utils.print_update(level=print_level_base+2,message=f"Creating pypsa components for main strategy :{charge_strat_main} with {ev_pen_str_main}% EV penetration") # load_fpath = cfg["ev_prefix_path"] + charge_strat_main + "_"+ev_pen_str_main + "_" + cfg["ev_load_path"] # bus_fpath = cfg["ev_prefix_path"] + charge_strat_main + "_"+ev_pen_str_main + "_" + cfg["ev_bus_path"] # charger_fpath = cfg["ev_prefix_path"] + charge_strat_main + "_"+ev_pen_str_main + "_" + cfg["ev_charger_path"] # discharger_fpath = cfg["ev_prefix_path"] + charge_strat_main +"_"+ ev_pen_str_main + "_" + cfg["ev_discharger_path"] # battery_fpath = cfg["ev_prefix_path"] + charge_strat_main + "_"+ev_pen_str_main + "_" + cfg["ev_battery_path"] # create_coordinated_components(df_final, df_battery, start_date_sim_str, end_date_sim_str, # cfg['ev_battery_cyclic'], cfg['ev_battery_initial_frac'], p_nom_per_charger, # load_fpath, bus_fpath, charger_fpath, battery_fpath) # charge_strat_filler = "uncoordinated" # ev_pen_str_filler= str(100- int(ev_pen_str_main)) # utils.print_update(level=print_level_base+2,message=f"Creating pypsa components for filler strategy :{charge_strat_filler} with {ev_pen_str_filler}% EV penetration") # ## Recreate 'df_tvc' for remaining vehicles from total population # total_vehicles_df['Vehicle Count'] = (1-ev_population) * (total_vehicles_df["Vehicle Count_x"] + total_vehicles_df["Vehicle Count_y"]) # df_tvc = total_vehicles_df[df_pvc.columns.tolist()].copy() # if trip_distribution == "population": # df_final = generate_vehicle_trip_population_distribution_df(df_tvc, df_tp_i, df_battery, start_date_sim_str, end_date_sim_str) # elif trip_distribution == "region": # df_final = generate_vehicle_trip_region_distribution_df(df_tvc, df_tp_i, df_battery, start_date_sim_str, end_date_sim_str) # else: # utils.print_update(level=print_level_base+1 ,message="ERROR: Trip distribution method must be specified as either 'population' or 'region'!", # alert=True) # load_fpath = cfg["ev_prefix_path"] + charge_strat_filler + "_"+ev_pen_str_filler + "_" + cfg["ev_load_path"] # create_uncoordinated_components(df_final, df_battery, start_date_sim_str, # end_date_sim_str, load_fpath, p_nom_per_charger) else: utils.print_update(level=print_level_base+1, message="ERROR: Charging Strategy specified is not implemented!", alert=True)
# (4) save pickle date of the pypsa ready dictionaries to results/pypsa-components/ #NOTE: Try loading these into a notebook and run our simplified pypsa to make sure they work