def on_precommit(t): dt_sim_time = parser.parse(gridlabd.get_global('clock')).replace(tzinfo=None) #Run market only every five minutes if not ((dt_sim_time.second == 0) and (dt_sim_time.minute % (interval/60) == 0)): return t else: #interval in minutes #is not start time print('Start precommit: '+str(dt_sim_time)) global step; global df_house_state, df_battery_state, df_EV_state, df_PV_state; global df_buy_bids, df_supply_bids, df_awarded_bids; if step == 0: df_house_state = HHfct.get_settings_houses(houses,interval) #Save DB files and shorten dfs every 12 hours saving_interval = 1 if step == 0: global time_daystart time_daystart = time.time() if step > 0 and (dt_sim_time.hour == 0) and (dt_sim_time.minute == 0): #i = int(step/(saving_interval*12)) #for 5min interval dt_sim_time_prev = dt_sim_time - pandas.Timedelta(days=1) specifier = str(dt_sim_time_prev.year)+format(dt_sim_time_prev.month,'02d')+format(dt_sim_time_prev.day,'02d') df_supply_bids.to_csv(results_folder+'/df_supply_bids_'+specifier+'.csv') #df_supply_bids = pandas.DataFrame(columns = df_supply_bids.columns) df_buy_bids.to_csv(results_folder+'/df_buy_bids_'+specifier+'.csv') #df_buy_bids = pandas.DataFrame(columns = df_buy_bids.columns) df_awarded_bids.to_csv(results_folder+'/df_awarded_bids_'+specifier+'.csv') #df_awarded_bids = pandas.DataFrame(columns = df_awarded_bids.columns) df_buy_bids = pandas.DataFrame(columns=['timestamp','appliance_name','bid_price','bid_quantity']) df_supply_bids = pandas.DataFrame(columns=['timestamp','appliance_name','bid_price','bid_quantity']) df_awarded_bids = pandas.DataFrame(columns=['timestamp','appliance_name','bid_price','bid_quantity','S_D']) time_dayend = time.time() print('Time needed for past simulation day '+str(dt_sim_time)+': '+str((time_dayend - time_daystart)/60.)+' min') time_daystart = time_dayend #Update physical values for new period #global df_house_state; df_house_state = HHfct.update_house(dt_sim_time,df_house_state) if len(batterylist) > 0: df_battery_state = Bfct.update_battery(df_battery_state) if len(EVlist) > 0: if EV_data == 'None': df_EV_state = EVfct.update_EV_rnd(dt_sim_time,df_EV_state) else: df_EV_state = EVfct.update_EV(dt_sim_time,df_EV_state) if len(pvlist) > 0: df_PV_state = PVfct.update_PV(dt_sim_time,df_PV_state) #Initialize market global df_prices, df_WS; retail, mean_p, var_p = Mfct.create_market(df_WS,df_prices,p_max,prec,price_intervals,dt_sim_time) #Submit bids df_house_state = HHfct.calc_bids_HVAC(dt_sim_time,df_house_state,retail,mean_p,var_p) retail,df_buy_bids = HHfct.submit_bids_HVAC(dt_sim_time,retail,df_house_state,df_buy_bids) #Batteries if len(batterylist) > 0: if ((dt_sim_time.hour == 0) and (dt_sim_time.minute == 0)) or step == 0: specifier = str(dt_sim_time.year)+format(dt_sim_time.month,'02d')+format(dt_sim_time.day,'02d') df_battery_state = Bfct.schedule_battery_ordered(df_WS,df_battery_state,dt_sim_time,specifier) #sell, buy = Bfct.schedule_battery_cvx(df_WS,df_battery_state,dt_sim_time) df_battery_state = Bfct.calc_bids_battery(dt_sim_time,df_battery_state,retail,mean_p,var_p) retail,df_supply_bids,df_buy_bids = Bfct.submit_bids_battery(dt_sim_time,retail,df_battery_state,df_supply_bids,df_buy_bids) if len(EVlist) > 0: df_EV_state = EVfct.calc_bids_EV(dt_sim_time,df_EV_state,retail,mean_p,var_p) retail,df_buy_bids = EVfct.submit_bids_EV(dt_sim_time,retail,df_EV_state,df_buy_bids) if len(pvlist) > 0: global df_PV_forecast; if (load_forecast == 'myopic') or (df_PV_forecast is None): df_PV_state = PVfct.calc_bids_PV(dt_sim_time,df_PV_state,retail) retail,df_supply_bids = PVfct.submit_bids_PV(dt_sim_time,retail,df_PV_state,df_supply_bids) elif load_forecast == 'perfect': #PV_forecast = df_PV_forecast['PV_infeed'].loc[dt_sim_time] PV_forecast = df_PV_forecast['PV_infeed'].loc[(df_PV_forecast.index >= dt_sim_time) & (df_PV_forecast.index < dt_sim_time + pandas.Timedelta(str(int(interval/60))+' min'))].min()/1000 if PV_forecast > 0.0: retail.sell(PV_forecast,0.0,gen_name='PV') df_supply_bids = df_supply_bids.append(pandas.DataFrame(columns=df_supply_bids.columns,data=[[dt_sim_time,'PV',0.0,PV_forecast]]),ignore_index=True) #Include unresponsive load retail, load_SLACK, unresp_load, df_buy_bids = Mfct.include_unresp_load(dt_sim_time,retail,df_prices,df_buy_bids,df_awarded_bids) #Claudio's control #retail, load_SLACK, unresp_load, df_buy_bids = Mfct.include_unresp_load_control(dt_sim_time,retail,df_prices,df_buy_bids,df_awarded_bids) #print('This fct is for control only') #df_awarded_bids = df_awarded_bids.append(pandas.DataFrame(columns=df_awarded_bids.columns,data=[[dt_sim_time,'unresp_load',float(p_max),unresp_load,'S']]),ignore_index=True) #Include supply # COINCIDENT PEAK / XCEL price / EIM supply_costs = float(min(df_WS[which_price].loc[dt_sim_time],retail.Pmax)) retail.sell(C,supply_costs,gen_name='WS') #in [USD/kW] #How can I tweak clearing that we can name biider 'WS'? df_supply_bids = df_supply_bids.append(pandas.DataFrame(columns=df_supply_bids.columns,data=[[dt_sim_time,'WS',supply_costs,C]]),ignore_index=True) print('Supply costs: '+str(supply_costs)) #Market clearing retail.clear() Pd = retail.Pd # cleared demand price print('Clearing price: '+str(Pd)) Qd = retail.Qd #in kW print('Clearing quantity: '+str(Qd)) df_temp = pandas.DataFrame(index=[dt_sim_time],columns=['clearing_price','clearing_quantity','unresponsive_loads','slack_t-1'],data=[[Pd,Qd,unresp_load,load_SLACK]]) df_prices = df_prices.append(df_temp) ### #Redistribute prices and quantities to market participants ### #Save and implement market result for each HVAC system if allocation_rule == 'by_price': #print('Set HVAC by price') df_house_state,df_awarded_bids = HHfct.set_HVAC_by_price(dt_sim_time,df_house_state,mean_p,var_p, Pd,df_awarded_bids) #Switches the HVAC system on and off directly (depending on bid >= p) elif allocation_rule == 'by_award': df_house_state,df_awarded_bids = HHfct.set_HVAC_by_award(dt_sim_time,df_house_state,retail,df_awarded_bids) #Switches the HVAC system on and off directly (depending on award) else: sys.exit('No valid pricing rule') if len(pvlist) > 0: df_awarded_bids = PVfct.set_PV(dt_sim_time,retail,df_PV_state,df_awarded_bids) if len(batterylist) > 0: if allocation_rule == 'by_price': df_bids_battery, df_awarded_bids = Bfct.set_battery_by_price(dt_sim_time,df_battery_state,mean_p,var_p, Pd, df_awarded_bids) #Controls battery based on bid <-> p elif allocation_rule == 'by_award': df_bids_battery, df_awarded_bids = Bfct.set_battery_by_award(dt_sim_time,df_battery_state,retail, df_awarded_bids) #Controls battery based on award if len(EVlist) > 0: if allocation_rule == 'by_price': df_EV_state, df_awarded_bids = EVfct.set_EV_by_price(dt_sim_time,df_EV_state,mean_p,var_p, Pd, df_awarded_bids) #Controls EV based on bid <-> p elif allocation_rule == 'by_award': df_EV_state, df_awarded_bids = EVfct.set_EV_by_award(dt_sim_time,df_EV_state,retail,df_awarded_bids) #Controls EV based on award #import pdb; pdb.set_trace() #Save all simulation results temporarily at each hour for potential restart # if dt_sim_time.minute == 0: # print('Last save at '+str(dt_sim_time)) # gridlabd.save('tmp_model.glm') # df_house_state.to_csv('tmp_df_house_state.csv') # df_PV_state.to_csv('tmp_df_PV_state.csv') # df_battery_state.to_csv('tmp_df_battery_state.csv') # df_EV_state.to_csv('tmp_df_EV_state.csv') # df_prices.to_csv('tmp_df_prices.csv') # df_supply_bids.to_csv('tmp_df_supply_bids.csv') # df_buy_bids.to_csv('tmp_df_buy_bids.csv') # df_awarded_bids.to_csv('tmp_df_awarded_bids.csv') step += 1 retail.reset() return t
def on_precommit(t): dt_sim_time = parser.parse( gridlabd.get_global('clock')).replace(tzinfo=None) #Run market only every five minutes if not ((dt_sim_time.second == 0) and (dt_sim_time.minute % (interval / 60) == 0)): return t else: #interval in minutes #is not start time print('Start precommit: ' + str(dt_sim_time)) global step global df_house_state global df_battery_state global df_EV_state global df_PV_state if step == 0: df_house_state = HHfct.get_settings_houses(houses, interval) #Save interim results saving_interval = 30 if (dt_sim_time.hour % saving_interval == 0) and (dt_sim_time.minute == 0): saving_results(dt_sim_time, saving_interval) #Update physical values for new period #global df_house_state; print('Update house') df_house_state = HHfct.update_house(dt_sim_time, df_house_state) if len(batterylist) > 0: print('Update battery') df_battery_state = Bfct.update_battery(df_battery_state) print('Battery updated') if len(EVlist) > 0: print('Update EV') df_EV_state = EVfct.update_EV(dt_sim_time, df_EV_state) print('EV updated') if len(pvlist) > 0: print('Update PV') df_PV_state = PVfct.update_PV(dt_sim_time, df_PV_state) print('PV updated') #Initialize market global df_prices, df_WS print('Create market') retail, mean_p, var_p = Mfct.create_market(df_prices, p_max, prec, price_intervals) #Submit bids df_house_state = HHfct.calc_bids_HVAC(dt_sim_time, df_house_state, retail, mean_p, var_p) retail = HHfct.submit_bids_HVAC(dt_sim_time, retail, df_house_state) #Batteries if len(batterylist) > 0: print('Reschedule batteries') if ((dt_sim_time.hour == 0) and (dt_sim_time.minute == 0)) or step == 0: print('Reschedule batteries: ' + str(dt_sim_time)) df_battery_state = Bfct.schedule_battery_ordered( df_WS, df_battery_state, dt_sim_time) #sell, buy = Bfct.schedule_battery_cvx(df_WS,df_battery_state,dt_sim_time) print('Calculate battery bids') df_battery_state = Bfct.calc_bids_battery(dt_sim_time, df_battery_state, retail, mean_p, var_p) print('Submit battery bids') retail = Bfct.submit_bids_battery(dt_sim_time, retail, df_battery_state) if len(EVlist) > 0: df_EV_state = EVfct.calc_bids_EV(dt_sim_time, df_EV_state, retail, mean_p, var_p) retail = EVfct.submit_bids_EV(dt_sim_time, retail, df_EV_state) print('Include PV') if len(pvlist) > 0: df_PV_state = PVfct.calc_bids_PV(dt_sim_time, df_PV_state, retail) retail = PVfct.submit_bids_PV(dt_sim_time, retail, df_PV_state) #Include unresponsive load print('Include unresp load') load_SLACK, unresp_load = Mfct.include_unresp_load( dt_sim_time, retail, df_prices) #Include supply supply_costs = float( min(df_WS[which_price].loc[dt_sim_time], retail.Pmax)) retail.sell( C, supply_costs, gen_name='WS' ) #in [USD/kW] #How can I tweak clearing that we can name biider 'WS'? print('Supply costs: ' + str(supply_costs)) #Market clearing retail.clear() Pd = retail.Pd # cleared demand price print('Clearing price: ' + str(Pd)) Qd = retail.Qd #in kW print('Clearing quantity: ' + str(Qd)) df_temp = pandas.DataFrame(index=[dt_sim_time], columns=[ 'clearing_price', 'clearing_quantity', 'unresponsive_loads', 'slack_t-1' ], data=[[Pd, Qd, unresp_load, load_SLACK]]) df_prices = df_prices.append(df_temp) ### #Redistribute prices and quantities to market participants ### #Save market result for each HVAC system if allocation_rule == 'by_price': #print('Set HVAC by price') df_house_state = HHfct.set_HVAC_by_price( dt_sim_time, df_house_state, mean_p, var_p, Pd ) #Switches the HVAC system on and off directly (depending on bid >= p) elif allocation_rule == 'by_award': df_house_state = HHfct.set_HVAC_by_award( dt_sim_time, df_house_state, retail ) #Switches the HVAC system on and off directly (depending on award) else: sys.exit('No valid pricing rule') if len(batterylist) > 0: if allocation_rule == 'by_price': df_bids_battery = Bfct.set_battery_by_price( dt_sim_time, df_battery_state, mean_p, var_p, Pd) #Controls battery based on bid <-> p elif allocation_rule == 'by_award': df_bids_battery = Bfct.set_battery_by_award( dt_sim_time, df_battery_state, retail) #Controls battery based on award #EVs if len(EVlist) > 0: if allocation_rule == 'by_price': df_EV_state = EVfct.set_EV_by_price( dt_sim_time, df_EV_state, mean_p, var_p, Pd) #Controls EV based on bid <-> p elif allocation_rule == 'by_award': df_EV_state = EVfct.set_EV_by_award( dt_sim_time, df_EV_state, retail) #Controls EV based on award step += 1 retail.reset() gridlabd.save('dump_model.glm') return t
def on_precommit(t): dt_sim_time = parser.parse(gridlabd.get_global('clock')).replace(tzinfo=None) #Run market only every five minutes if not ((dt_sim_time.second == 0) and (dt_sim_time.minute % (interval/60) == 0)): return t else: #interval in minutes #is not start time print('Start precommit: '+str(dt_sim_time)) global step; global df_house_state, df_battery_state, df_EV_state, df_PV_state; global df_buy_bids, df_supply_bids, df_awarded_bids; if step == 0: df_house_state = HHfct.get_settings_houses(houses,interval) #Save DB files and shorten dfs every 24 hours saving_interval = 1 if step == 0: global time_daystart time_daystart = time.time() if step > 0 and (dt_sim_time.hour == 0) and (dt_sim_time.minute == 0): #i = int(step/(saving_interval*12)) #for 5min interval dt_sim_time_prev = dt_sim_time - pandas.Timedelta(days=1) specifier = str(dt_sim_time_prev.year)+format(dt_sim_time_prev.month,'02d')+format(dt_sim_time_prev.day,'02d') df_supply_bids.to_csv(results_folder+'/df_supply_bids_'+specifier+'.csv') #df_supply_bids = pandas.DataFrame(columns = df_supply_bids.columns) df_buy_bids.to_csv(results_folder+'/df_buy_bids_'+specifier+'.csv') #df_buy_bids = pandas.DataFrame(columns = df_buy_bids.columns) df_awarded_bids.to_csv(results_folder+'/df_awarded_bids_'+specifier+'.csv') #df_awarded_bids = pandas.DataFrame(columns = df_awarded_bids.columns) df_buy_bids = pandas.DataFrame(columns=['timestamp','appliance_name','bid_price','bid_quantity']) df_supply_bids = pandas.DataFrame(columns=['timestamp','appliance_name','bid_price','bid_quantity']) df_awarded_bids = pandas.DataFrame(columns=['timestamp','appliance_name','bid_price','bid_quantity','S_D']) time_dayend = time.time() print('Time needed for past simulation day '+str(dt_sim_time)+': '+str((time_dayend - time_daystart)/60.)+' min') time_daystart = time_dayend #Update physical values for new period df_house_state = HHfct.update_house(dt_sim_time,df_house_state) if len(batterylist) > 0: df_battery_state = Bfct.update_battery(df_battery_state) if len(EVlist) > 0: if EV_data == 'None': df_EV_state = EVfct.update_EV_rnd(dt_sim_time,df_EV_state) else: df_EV_state = EVfct.update_EV(dt_sim_time,df_EV_state) if len(pvlist) > 0: df_PV_state = PVfct.update_PV(dt_sim_time,df_PV_state) #Initialize market global df_tokens, df_controlroom; if system_op == 'fixed_proc': retail, mean_t, var_t = Mfct.create_market_noEIM(df_controlroom,df_tokens,p_max,prec,price_intervals,dt_sim_time) elif system_op == 'EIM': global df_WS retail, mean_t, var_t = Mfct.create_market(df_WS,df_tokens,p_max,prec,price_intervals,dt_sim_time) else: import sys; sys.exit('This system_op does not exist') retail.surplusControl = 1 # Surplus goes to customer #Customer bidding #HVACs df_house_state = HHfct.calc_bids_HVAC(dt_sim_time,df_house_state,retail,mean_t,var_t) retail,df_buy_bids = HHfct.submit_bids_HVAC(dt_sim_time,retail,df_house_state,df_buy_bids) #Batteries if len(batterylist) > 0: if ((dt_sim_time.hour == 0) and (dt_sim_time.minute == 0)) or step == 0: specifier = str(dt_sim_time.year)+format(dt_sim_time.month,'02d')+format(dt_sim_time.day,'02d') df_battery_state = Bfct.schedule_battery_ordered(df_WS,df_battery_state,dt_sim_time,specifier) #sell, buy = Bfct.schedule_battery_cvx(df_WS,df_battery_state,dt_sim_time) df_battery_state = Bfct.calc_bids_battery(dt_sim_time,df_battery_state,retail,mean_t,var_t) retail,df_supply_bids,df_buy_bids = Bfct.submit_bids_battery(dt_sim_time,retail,df_battery_state,df_supply_bids,df_buy_bids) if len(EVlist) > 0: df_EV_state = EVfct.calc_bids_EV(dt_sim_time,df_EV_state,retail,mean_t,var_t) retail,df_buy_bids = EVfct.submit_bids_EV(dt_sim_time,retail,df_EV_state,df_buy_bids) #PV bids if len(pvlist) > 0: global df_PV_forecast; if (load_forecast == 'myopic') or (df_PV_forecast is None): df_PV_state = PVfct.calc_bids_PV(dt_sim_time,df_PV_state,retail) if customer_op == 'baseline': retail,df_buy_bids = PVfct.submit_bids_PV(dt_sim_time,retail,df_PV_state,df_buy_bids) elif customer_op == 'direct': retail,df_supply_bids = PVfct.submit_bids_PV(dt_sim_time,retail,df_PV_state,df_supply_bids) elif load_forecast == 'perfect': #PV_forecast = df_PV_forecast['PV_infeed'].loc[dt_sim_time] PV_forecast = df_PV_forecast['PV_infeed'].loc[(df_PV_forecast.index >= dt_sim_time) & (df_PV_forecast.index < dt_sim_time + pandas.Timedelta(str(int(interval/60))+' min'))].min()/1000 if PV_forecast > 0.0: if customer_op == 'baseline': # buying back PV generation import pdb; pdb.set_trace() retail.buy(PV_forecast,-RR,gen_name='PV') df_buy_bids = df_buy_bids.append(pandas.DataFrame(columns=df_buy_bids.columns,data=[[dt_sim_time,'PV',-RR,PV_forecast]]),ignore_index=True) elif customer_op == 'direct': retail.sell(PV_forecast,0.0,gen_name='PV') df_supply_bids = df_supply_bids.append(pandas.DataFrame(columns=df_supply_bids.columns,data=[[dt_sim_time,'PV',0.0,PV_forecast]]),ignore_index=True) #Unresponsive load ( does not care about baseline / direct - always max willingness to pay) retail, load_SLACK, unresp_load, df_buy_bids = Mfct.determine_unresp_load(dt_sim_time,retail,df_tokens,df_buy_bids,df_awarded_bids) if customer_op == 'direct': # unresp load does not participate in the DR market in the baseline scenario retail.buy(unresp_load,appliance_name='unresp') df_buy_bids = df_buy_bids.append(pandas.DataFrame(columns=df_buy_bids.columns,data=[[dt_sim_time,'unresponsive_loads',p_max,round(float(unresp_load),prec)]]),ignore_index=True) #Supply from transmission level max_capacity = df_controlroom['C_max'].loc[dt_sim_time] #Max import min_capacity = df_controlroom['C_min'].loc[dt_sim_time] #Min import / max export #HCE coincident_peak_forecasted = df_controlroom['coincident_peak_forecasted'].loc[dt_sim_time] # HCE if customer_op == 'baseline': # cost change compared to the baseline # Determine value of DR if coincident_peak_forecasted == 0: DR_value = fixed_procurement_cost - RR #df_controlroom['fixed_procurement'].loc[dt_sim_time] else: DR_value = coincident_peak_rate - RR #df_controlroom['coincident_peak_rate'].loc[dt_sim_time] if system_op == 'EIM': import sys; sys.exit('EIM not allowed for baseline custom_op') # In MVP: no export retail.buy(100000.,DR_value,appliance_name='load_reduction') #in [USD/kW] df_buy_bids = df_buy_bids.append(pandas.DataFrame(columns=df_buy_bids.columns,data=[[dt_sim_time,'load_reduction',DR_value,100000.]]),ignore_index=True) retail.sell(100000.,DR_value+0.001,gen_name='load_increase') #in [USD/kW] df_supply_bids = df_supply_bids.append(pandas.DataFrame(columns=df_supply_bids.columns,data=[[dt_sim_time,'load_increase',DR_value+0.001,100000.]]),ignore_index=True) elif customer_op == 'direct': # Determine marginal supply costs if system_op == 'fixed_proc': if coincident_peak_forecasted == 0: supply_costs = fixed_procurement_cost #df_controlroom['fixed_procurement'].loc[dt_sim_time] else: supply_costs = coincident_peak_rate #df_controlroom['coincident_peak_rate'].loc[dt_sim_time] elif system_op == 'EIM': supply_costs = df_WS['RT'].loc[dt_sim_time] # Place bids if min_capacity > 0.0: #Minimum import retail.sell(min_capacity,-retail.Pmax,gen_name='min_import') #in [USD/kW] df_supply_bids = df_supply_bids.append(pandas.DataFrame(columns=df_supply_bids.columns,data=[[dt_sim_time,'min_import',-retail.Pmax,min_capacity]]),ignore_index=True) #Additional import retail.sell(max_capacity - min_capacity,supply_costs,gen_name='add_import') #in [USD/kW] df_supply_bids = df_supply_bids.append(pandas.DataFrame(columns=df_supply_bids.columns,data=[[dt_sim_time,'add_import',supply_costs,max_capacity - min_capacity]]),ignore_index=True) elif min_capacity == 0: #No export, no minimum import retail.sell(max_capacity,supply_costs,gen_name='import') #in [USD/kW] df_supply_bids = df_supply_bids.append(pandas.DataFrame(columns=df_supply_bids.columns,data=[[dt_sim_time,'import',supply_costs,max_capacity]]),ignore_index=True) else: #No minimum import retail.sell(max_capacity,supply_costs,gen_name='import') #in [USD/kW] df_supply_bids = df_supply_bids.append(pandas.DataFrame(columns=df_supply_bids.columns,data=[[dt_sim_time,'import',supply_costs,max_capacity]]),ignore_index=True) #Possible export retail.buy(-min_capacity,supply_costs-0.01,appliance_name='export') #in [USD/kW] df_buy_bids = df_buy_bids.append(pandas.DataFrame(columns=df_buy_bids.columns,data=[[dt_sim_time,'export',supply_costs-0.01,-min_capacity]]),ignore_index=True) else: import sys; sys.exit('No such custom_op') #Market clearing retail.clear() Pd = retail.Pd # cleared demand price print('Clearing price: '+str(Pd)) Qd = retail.Qd #in kW print('Clearing quantity: '+str(Qd)) partial = retail.partial # Demand or supply alpha = retail.alpha # Share of marginal bids #Check system conditions available_supply = df_supply_bids.loc[df_supply_bids['timestamp'] == dt_sim_time]['bid_quantity'].sum() available_demand = df_buy_bids.loc[df_buy_bids['timestamp'] == dt_sim_time]['bid_quantity'].sum() if available_supply >= unresp_load*0.999: if abs(available_supply - Qd) < 0.1: system_op_mode = 'SUPPLY_CONTRAINED' # Not sufficient supply elif abs(available_demand - Qd) < 0.1: system_op_mode = 'DEMAND_CONTRAINED' # Not sufficient demand else: system_op_mode = 'NORMAL' # Not sufficient demand else: system_op_mode = 'EMERGENCY' #Save market / system result df_temp = pandas.DataFrame(index=[dt_sim_time],columns=df_tokens.columns,data=[[Pd,Qd,partial,alpha,unresp_load,system_op_mode,load_SLACK]]) df_tokens = df_tokens.append(df_temp) ### #Redistribute prices and quantities to market participants ### #no alpha and partial yet if allocation_rule == 'by_price': #print('Set HVAC by price') df_house_state,df_awarded_bids = HHfct.set_HVAC_by_price(dt_sim_time,df_house_state,mean_t,var_t, Pd,df_awarded_bids) #Switches the HVAC system on and off directly (depending on bid >= p) elif allocation_rule == 'by_award': df_house_state,df_awarded_bids = HHfct.set_HVAC_by_award(dt_sim_time,df_house_state,retail,df_awarded_bids) #Switches the HVAC system on and off directly (depending on award) else: sys.exit('No valid pricing rule') if len(pvlist) > 0: # no control of PVs (if inverter cannot disconnect remotely) #df_awarded_bids = PVfct.set_PV(dt_sim_time,retail,df_PV_state,df_awarded_bids) # control of PVs (if inverter can disconnect remotely) df_awarded_bids = PVfct.set_PV_by_price(dt_sim_time,df_PV_state,Pd,df_awarded_bids,partial,alpha) #import pdb; pdb.set_trace() #no alpha and partial yet if len(batterylist) > 0: if allocation_rule == 'by_price': df_bids_battery, df_awarded_bids = Bfct.set_battery_by_price(dt_sim_time,df_battery_state,mean_t,var_t, Pd, df_awarded_bids) #Controls battery based on bid <-> p elif allocation_rule == 'by_award': df_bids_battery, df_awarded_bids = Bfct.set_battery_by_award(dt_sim_time,df_battery_state,retail, df_awarded_bids) #Controls battery based on award #no alpha and partial yet if len(EVlist) > 0: if allocation_rule == 'by_price': df_EV_state, df_awarded_bids = EVfct.set_EV_by_price(dt_sim_time,df_EV_state,mean_t,var_t, Pd, df_awarded_bids) #Controls EV based on bid <-> p elif allocation_rule == 'by_award': df_EV_state, df_awarded_bids = EVfct.set_EV_by_award(dt_sim_time,df_EV_state,retail,df_awarded_bids) #Controls EV based on award #import pdb; pdb.set_trace() #Save all simulation results temporarily at each hour for potential restart # if dt_sim_time.minute == 0: # print('Last save at '+str(dt_sim_time)) # gridlabd.save('tmp_model.glm') # df_house_state.to_csv('tmp_df_house_state.csv') # df_PV_state.to_csv('tmp_df_PV_state.csv') # df_battery_state.to_csv('tmp_df_battery_state.csv') # df_EV_state.to_csv('tmp_df_EV_state.csv') # df_prices.to_csv('tmp_df_prices.csv') # df_supply_bids.to_csv('tmp_df_supply_bids.csv') # df_buy_bids.to_csv('tmp_df_buy_bids.csv') # df_awarded_bids.to_csv('tmp_df_awarded_bids.csv') # Every DeltaT change calculate tokens step += 1 retail.reset() return t
def on_precommit(t): dt_sim_time = parser.parse(gridlabd.get_global('clock')).replace(tzinfo=None) #Run market only every five minutes if not ((dt_sim_time.second == 0) and (dt_sim_time.minute % (interval/60) == 0)): return t else: #interval in minutes #is not start time print('Start precommit: '+str(dt_sim_time)) global step; global df_house_state, df_battery_state, df_EV_state, df_PV_state; global df_buy_bids, df_supply_bids, df_awarded_bids; if step == 0: df_house_state = HHfct.get_settings_houses(houses,interval) #Save DB files and shorten dfs every 12 hours saving_interval = 1 if step > 0 and (dt_sim_time.hour%saving_interval == 0) and (dt_sim_time.minute == 0): i = int(step/(saving_interval*12)) #for 5min interval df_supply_bids.to_csv(results_folder+'/df_supply_bids.csv') #df_supply_bids = pandas.DataFrame(columns = df_supply_bids.columns) df_buy_bids.to_csv(results_folder+'/df_buy_bids.csv') #df_buy_bids = pandas.DataFrame(columns = df_buy_bids.columns) df_awarded_bids.to_csv(results_folder+'/df_awarded_bids.csv') #df_awarded_bids = pandas.DataFrame(columns = df_awarded_bids.columns) #Get current ToU price retail = Mfct.Market() retail.Pmin = 0.0 retail.Pmax = p_max retail.Pprec = prec if (dt_sim_time.hour >= ToU_min) & (dt_sim_time.hour < ToU_max): Pd = p_max else: Pd = p_min df_temp = pandas.DataFrame(index=[dt_sim_time],columns=['clearing_price','clearing_quantity','unresponsive_loads','slack_t-1'],data=[[Pd,0.0,0.0,0.0]]) df_prices = df_prices.append(df_temp) #Update physical values for new period #global df_house_state; df_house_state = HHfct.update_house(dt_sim_time,df_house_state) if len(batterylist) > 0: df_battery_state = Bfct.update_battery(df_battery_state) if len(EVlist) > 0: df_EV_state = EVfct.update_EV(dt_sim_time,df_EV_state) #if len(pvlist) > 0: # df_PV_state = PVfct.update_PV(dt_sim_time,df_PV_state) #Determine willingness to pay for HVACs df_house_state = HHfct.calc_bids_HVAC(dt_sim_time,df_house_state,retail,mean_p,var_p) #Batteries try to sell in peak times, and buy in non-peak times until they are full #peak hours: sell if (dt_sim_time.hour >= ToU_min) & (dt_sim_time.hour < ToU_max): df_battery_state #Quantity depends on SOC and u df_battery_state['residual_s'] = round((3600./interval)*(df_battery_state['SOC_t'] - df_battery_state['SOC_min']*df_battery_state['SOC_max']),prec) #Recalculate to kW df_battery_state['q_sell'] = df_battery_state[['residual_s','u_max']].min(axis=1) #in kW / only if fully dischargeable df_battery_state['q_sell'].loc[df_battery_state['q_sell'] < 0.1] = 0.0 df_battery_state['p_sell'] = -p_max #sell in any case df_battery_state['q_buy'] = 0.0 df_battery_state['p_buy'] = -p_max else: safety_fac = 0.99 df_battery_state['residual_b'] = round((3600./interval)*(safety_fac*df_battery_state['SOC_max'] - df_battery_state['SOC_t']),prec) #Recalculate to kW df_battery_state['q_buy'] = df_battery_state[['residual_b','u_max']].min(axis=1) #in kW df_battery_state['q_buy'].loc[df_battery_state['q_buy'] < 0.1] = 0.0 df_battery_state['p_buy'] = p_max #buy in any case df_battery_state['q_sell'] = 0.0 df_battery_state['p_sell'] = p_max #never sell #Determine willingness to pay for EVs #Quantity safety_fac = 0.99 df_EV_state['q_buy'] = 0.0 #general df_EV_state['residual_SOC'] = round((3600./interval)*(safety_fac*df_EV_state['SOC_max'] - df_EV_state['SOC_t']),prec) df_EV_state['q_buy'].loc[df_EV_state['connected'] == 1] = df_EV_state.loc[df_EV_state['connected'] == 1][['residual_SOC','u_max']].min(axis=1) #in kW df_EV_state['q_buy'].loc[df_EV_state['q_buy'] < 1.] = 0.0 #Price df_EV_state['p_buy'] = 0.0 #general #peak hours: only charge if necessary if (dt_sim_time.hour >= ToU_min) & (dt_sim_time.hour < ToU_max): #Home-based charging df_EV_state['delta'] = df_EV_state['next_event'] - dt_sim_time df_EV_state['residual_t'] = df_EV_state['delta'].apply(lambda x: x.seconds)/3600. #residual time until departure; in h df_EV_state['time_needed_charging'] = df_EV_state['residual_SOC']/df_EV_state['u_max'] #in h df_EV_state['must_charge'] = 0 df_EV_state['must_charge'].loc[df_EV_state['residual_t'] <= df_EV_state['time_needed_charging']] = 1 #import pdb; pdb.set_trace() #df_EV_state.at[df_EV_state.loc[df_EV_state['must_charge'] == 0].index,'p_buy'] = 0.0 df_EV_state['p_buy'].loc[df_EV_state['must_charge'] == 0] = 0.0 #df_EV_state.at[df_EV_state.loc[df_EV_state['must_charge'] == 1].index,'p_buy'] = p_max df_EV_state['p_buy'].loc[df_EV_state['must_charge'] == 1] = p_max else: df_EV_state['p_buy'] = p_max #Commercial df_EV_state.loc[df_EV_state['charging_type'].str.contains('comm') & (df_EV_state['connected'] == 1) & (df_EV_state['q_buy'] > 0.001),'p_buy'] = retail.Pmax #max for commercial cars #Dispatch allocation_rule == 'by_price' #open loop! df_house_state,df_awarded_bids = HHfct.set_HVAC_by_price(dt_sim_time,df_house_state,mean_p,var_p, Pd,df_awarded_bids) #Switches the HVAC system on and off directly (depending on bid >= p) df_bids_battery, df_awarded_bids = Bfct.set_battery_by_price(dt_sim_time,df_battery_state,mean_p,var_p, Pd, df_awarded_bids) #Controls battery based on bid <-> p df_EV_state, df_awarded_bids = EVfct.set_EV_by_price(dt_sim_time,df_EV_state,mean_p,var_p, Pd, df_awarded_bids) #Controls EV based on bid <-> p step += 1 return t