def run_savnw_simulation(datapath, outfile1, outfile2, outfile3, prgfile): import psspy psspy.psseinit() savfile = 'Converted_NETS-NYPS 68 Bus System_C.sav' snpfile = 'NETS-NYPS 68 Bus System.snp' if datapath: savfile = os.path.join(datapath, savfile) snpfile = os.path.join(datapath, snpfile) #why produce these two kinds of files? psspy.lines_per_page_one_device(1, 90) psspy.progress_output(2, prgfile, [0, 0]) ierr = psspy.case(savfile) if ierr: psspy.progress_output(1, "", [0, 0]) print(" psspy.case Error") return ierr = psspy.rstr(snpfile) if ierr: psspy.progress_output(1, "", [0, 0]) print(" psspy.rstr Error") return # fault + line trip psspy.strt(0, outfile1) psspy.run(0, 1.0, 1000, 1, 0) psspy.dist_bus_fault(52, 1, 138.0, [0.0, -0.2E+10]) psspy.run(0, 1.1, 1000, 1, 0) psspy.dist_clear_fault(1) psspy.dist_branch_trip(52, 55, '1') psspy.run(0, 1.2, 1000, 1, 0) psspy.dist_machine_trip(1, '1') psspy.run(0, 5.0, 1000, 1, 0) # line trip (with faults) + generator trip psspy.case(savfile) psspy.rstr(snpfile) psspy.strt(0, outfile2) psspy.run(0, 1.0, 1000, 1, 0) psspy.dist_bus_fault(52, 1, 138.0, [0.0, -0.2E+10]) psspy.run(0, 1.1, 1000, 1, 0) psspy.dist_clear_fault(1) psspy.run(0, 1.2, 1000, 1, 0) psspy.dist_machine_trip(8, '1') psspy.run(0, 5.0, 1000, 1, 0) psspy.case(savfile) psspy.rstr(snpfile) psspy.strt(0, outfile3) psspy.run(0, 1.0, 1000, 1, 0) psspy.dist_branch_trip(32, 33, '1') psspy.run(0, 5.0, 1000, 1, 0) psspy.lines_per_page_one_device(2, 10000000) psspy.progress_output(1, "", [0, 0])
def check_pssedongle(): try: psspy.psseinit(90000) return True except: _, e, _ = sys.exc_info() print str(e) return False
def network(): """Set up the PSS/E case""" cwd = os.path.dirname(__file__) casename = os.path.join(cwd, 'cases/simple.sav') psspy.psseinit(10) psspy.case(casename) return {'load_bus': 1, 'gen': 2, 'load': 100.0}
def __init__(self): # psse self._psspy = psspy psspy.psseinit(0) psspy.report_output(6, '', []) psspy.progress_output(6, '', []) psspy.alert_output(6, '', []) psspy.prompt_output(6, '', []) return None
def inicia_psse(self): # Guardamos el stdout consola = sys.stdout # Abrimos archivo nulo (no existe) sys.stdout = open(os.devnull, 'w') #Redireccion de los mensajes de PSS/E a Python redirect.psse2py() #Inicializacion del numero de nudos en memoria del PSS/E psspy.psseinit(150000) # Redirigimos el stdout a la consola sys.stdout = consola
def getGeneratedPower(): with silence(): # initialize psspy.psseinit() # load case psspy.case(CASE_STUDY) PWR_GEN=[] for _id in MACHINE_IDS: _, _pmax = psspy.macdat(ibus=_id, id='1', string='PMAX') # find power of machine Pgen = P_gen*_pmax PWR_GEN.append(Pgen) return PWR_GEN
def run_savnw_simulation(datapath, outfile1, outfile2, outfile3, prgfile): import psspy psspy.psseinit() savfile = 'savcnv.sav' snpfile = 'savnw.snp' if datapath: savfile = os.path.join(datapath, savfile) snpfile = os.path.join(datapath, snpfile) psspy.lines_per_page_one_device(1, 90) psspy.progress_output(2, prgfile, [0, 0]) ierr = psspy.case(savfile) if ierr: psspy.progress_output(1, "", [0, 0]) print(" psspy.case Error") return ierr = psspy.rstr(snpfile) if ierr: psspy.progress_output(1, "", [0, 0]) print(" psspy.rstr Error") return psspy.strt(0, outfile1) psspy.run(0, 1.0, 1000, 1, 0) psspy.dist_bus_fault(154, 1, 230.0, [0.0, -0.2E+10]) psspy.run(0, 1.05, 1000, 1, 0) psspy.dist_clear_fault(1) psspy.run(0, 5.0, 1000, 1, 0) psspy.case(savfile) psspy.rstr(snpfile) psspy.strt(0, outfile2) psspy.run(0, 1.0, 1000, 1, 0) psspy.dist_machine_trip(3018, '1') psspy.run(0, 5.0, 1000, 1, 0) psspy.case(savfile) psspy.rstr(snpfile) psspy.strt(0, outfile3) psspy.run(0, 1.0, 1000, 1, 0) psspy.dist_branch_trip(3005, 3007, '1') psspy.run(0, 5.0, 1000, 1, 0) psspy.lines_per_page_one_device(2, 10000000) psspy.progress_output(1, "", [0, 0])
def _initialize_psse(self): redirect.psse2py() psspy.psseinit(1000) # Read load flow and dynamic files psspy.read(0, self.raw_file) psspy.dyre_new([1, 1, 1, 1], self.dyr_file, "", "", "") psspy.fdns([0, 0, 0, 1, 1, 0, 0, 0]) # Convert Generator and Loads psspy.cong(0) # Order Network for matrix operation psspy.ordr(0) # Factorize Admittance matrix psspy.fact() # Solve switching study network solutions psspy.tysl()
def __init__(self, workdir, raw_file_dir): ''' Constructor: - Store work and raw folder paths - Initialize PSS/E ''' assert(os.path.isdir(workdir)) assert(os.path.isdir(raw_file_dir) or os.path.isfile(raw_file_dir)) self.workdir = workdir self.raw_file_dir = raw_file_dir self.rawfilelist = [] self.busNumbers = [] self.caseName = '' redirect.psse2py() psspy.psseinit(100)
def run_savnw_simulation(datapath, outfile, prgfile): import psspy psspy.psseinit() savfile = 'Converted_NETS-NYPS 68 Bus System_C.sav' snpfile = 'NETS-NYPS 68 Bus System.snp' if datapath: savfile = os.path.join(datapath, savfile) snpfile = os.path.join(datapath, snpfile) psspy.lines_per_page_one_device(1,90) psspy.progress_output(2,prgfile,[0,0]) # directly output to file ierr = psspy.case(savfile) if ierr: psspy.progress_output(1,"",[0,0]) print(" psspy.case Error") return ierr = psspy.rstr(snpfile) if ierr: psspy.progress_output(1,"",[0,0]) print(" psspy.rstr Error") return # branches ibus,jbus,id=read_rawdata.branch_bus() for i,gener in enumerate(all_gener): psspy.case(savfile) psspy.rstr(snpfile) psspy.strt(0,outfile[i]) psspy.run(0, 1.0,1000,1,0) dist_branch_fault(ibus[i], jbus[i], id[i]) psspy.run(0, 1.2,1000,1,0) psspy.dist_clear_fault(1) psspy.run(0, 5.0,1000,1,0) psspy.lines_per_page_one_device(2,10000000)#Integer DEVICE Indicates which of the four output devices is to be processed (input; #1 for disk files. #2 for the report window. #3 for the first primary hard copy output device. #4 for the second primary hard copy output device. psspy.progress_output(1,"",[0,0]) return outfile,prgfile
def __init__(self, raw_file_dir): ''' Constructor: - Store work and raw folder paths - Initialize PSS/E ''' assert os.path.isdir(raw_file_dir) or os.path.isfile(raw_file_dir) self.raw_file_dir = raw_file_dir self.rawfilelist = [] self.buses = {} self.machines = {} self.loads = {} self.trafos = {} self.case_name = '' redirect.psse2py() psspy.psseinit(100)
def run_savnw_simulation(datapath, outfile, prgfile): import psspy psspy.psseinit() savfile = 'Converted_NETS-NYPS 68 Bus System_C.sav' snpfile = 'NETS-NYPS 68 Bus System.snp' if datapath: savfile = os.path.join(datapath, savfile) snpfile = os.path.join(datapath, snpfile) psspy.lines_per_page_one_device(1, 90) psspy.progress_output(2, prgfile, [0, 0]) # directly output to file #psspy.chsb(0,1,[-1,-1,-1,1,13,0]) ierr = psspy.case(savfile) if ierr: psspy.progress_output(1, "", [0, 0]) print(" psspy.case Error") return ierr = psspy.rstr(snpfile) if ierr: psspy.progress_output(1, "", [0, 0]) print(" psspy.rstr Error") return # run generator trip automatically for i in range(16): psspy.case(savfile) psspy.rstr(snpfile) psspy.strt(0, outfile[i]) #psspy.chsb(0,1,[-1,-1,-1,1,13,0]) psspy.run(0, 1.0, 1000, 1, 0) psspy.dist_machine_trip(i + 1, '1') psspy.run(0, 5.0, 1000, 1, 0) psspy.lines_per_page_one_device( 2, 10000000 ) #Integer DEVICE Indicates which of the four output devices is to be processed (input; #1 for disk files. #2 for the report window. #3 for the first primary hard copy output device. #4 for the second primary hard copy output device. psspy.progress_output(1, "", [0, 0]) return outfile, prgfile
def __init__(self, workdir, raw_file_dir): ''' Constructor: - Store work and raw folder paths - Initialize PSS/E ''' assert (os.path.isdir(workdir)) assert (os.path.isdir(raw_file_dir) or os.path.isfile(raw_file_dir)) self.workdir = workdir self.raw_file_dir = raw_file_dir self.rawfilelist = [] self.busNumbers = [] self.caseName = '' redirect.psse2py() psspy.psseinit(100)
def inicia_psse(print_alert_psse=False): """ :param print_alert_psse: Para indicar si en la consal debe aparecer las alaertas de PSSE :return: """ # start = time.clock() # Guardamos el stdout consola = sys.stdout # Abrimos archivo nulo (no existe) sys.stdout = open(os.devnull, 'w') #Redireccion de los mensajes de PSS/E a Python redirect.psse2py() #Inicializacion del numero de nudos en memoria del PSS/E psspy.psseinit(150000) # Redirigimos el stdout a la consola sys.stdout = consola if print_alert_psse: psspy.prompt_output(6, "", [0, 0]) psspy.alert_output(6, "", [0, 0]) psspy.progress_output(6, "", [0, 0])
def psse_init(self, logger): """ Inicializuje PSS/E pro vypocty v pripade, ze nebylo inicializovano drive. @return: V pripade chyby je potreba proverit API dokumentaci PSS/E """ with redirected_stdout() as fake_stdout: ierr = psspy.psseinit() if ierr != 0: logger.error("Nepodarilo se spustit PSSE.") sys.exit() name, major, minor, update, date, stat = psspy.psseversion() logger.info("{} ve verzi {}.{}.{} vydano {}.".format( name.replace(" ", ""), major, minor, update, date)) return
def Initialize_Case(case_file): psspy.psseinit(150000) #Initialize size of case, just choose large number psspy.case(case_file) #Load example case savnw.sav
PSSE_LOCATION_34 = r"""C:\Program Files (x86)\PTI\PSSE34\PSSPY27""" PSSE_LOCATION_33 = r"""C:\Program Files (x86)\PTI\PSSE33\PSSBIN""" if os.path.isdir(PSSE_LOCATION_34): sys.path.append(PSSE_LOCATION_34) import psse34, psspy else: os.environ['PATH'] = PSSE_LOCATION_33 + ';' + os.environ['PATH'] sys.path.append(PSSE_LOCATION_33) import psspy from psspy import _i, _f # importing the default integer and float values used by PSS\E(every API uses them) import PowerSystemPsseLibrary as powerlib import numpy as np import scipy as sp psspy.psseinit(80000) import StringIO from studydata_IEEE118 import bus_num, response_buses, line_trip, pq, load_bus, load_bus_region, gen_bus_region # endregion #====================================================================================================================== @contextmanager def silence(file_object=None): """ Discard stdout (i.e. write to null device) or optionally write to given file-like object. """
# Call up PSS/E from Python import sys, os sys.path.append(pssbin_path) os.environ['PATH'] = (pssbin_path + ';' + os.environ['PATH']) import psspy, redirect, dyntools, pssplot # Import PSS/E default _i = psspy.getdefaultint() _f = psspy.getdefaultreal() _s = psspy.getdefaultchar() redirect.psse2py() # -------------------------------------------------- # # initiate psspy.psseinit(2000) # 2000 bus at most, this number can be changed # Load and solve the powerflow case psspy.case(sav_case) # configure the solver psspy.fnsl(options1=0, options5=0) # sikve the power flow case iVal = psspy.solved() if iVal == 0: print "Met convergence tolerance" elif iVal == 1: print "The iteration limit exceeded" elif iVal > 1: print "Blown up or others" # ------------------------------------------------- # # Dynamic Simulation
from math import hypot, atan2, pi if deg: return hypot(x, y), 180.0*atan2(y, x)/pi else: return hypot(x, y), atan2(y, x) #--------------------------------------------------------------------- import numpy as np import matplotlib.pyplot as plt import math from itertools import groupby # PSS/E Saved case #CASE = r"C:\Program Files\PTI\PSSE32\EXAMPLE\12TH_PLAN_MAR_2017R1.sav" SAVFILE_LOCATION = r"C:\Program Files (x86)\PTI\PSSE33\EXAMPLE\\" CASE = r"12TH_PLAN_MAR_2017R1.sav" psspy.psseinit(9000) psspy.case(SAVFILE_LOCATION + CASE) ###------------------------ ierr = psspy.bus_data_2(44010, intgar1=4) #BkroA ierr = psspy.bus_data_2(44031, intgar1=4) #RTPSG2 ierr = psspy.bus_data_2(44034, intgar1=4) #RTPSG3 ierr = psspy.bus_data_2(44035, intgar1=4) #RTPSG4 ierr = psspy.bus_data_2(44036, intgar1=4) #KODRG3 ierr = psspy.bus_data_2(44037, intgar1=4) #KODRG4 ierr = psspy.bus_data_2(44140, intgar1=4) #CHAS1 ierr = psspy.bus_data_2(44141, intgar1=4) #RNIGNJ1 ierr = psspy.bus_data_2(44214, intgar1=4) #RNIGNJ2 ierr = psspy.bus_data_2(44219, intgar1=4) #GOLA2 ierr = psspy.bus_data_2(44227, intgar1=4) #RTPS2 ierr = psspy.bus_data_2(44228, intgar1=4) #MOSB2
print('Running PSSE...') import sys sys.path.append('C:\Program Files (x86)\PTI\PSSEXplore34\PSSBIN' ) #make this point to the pssbin directory os.environ['PATH'] = (r'C:\Program Files (x86)\PTI\PSSEXplore34\PSSBIN;' + os.environ['PATH']) import redirect redirect.psse2py() import psspy psspy.throwPsseExceptions = True nbuses = 50 #max no of buses pathname = r"C:\Users\Narasimham\Desktop\Sevenbus\Loads" #path of the folder containing the solved base case casefile = os.path.join(pathname, "7Bus_conv.sav") #use the solved base case ierr = psspy.psseinit(nbuses) psspy.case(casefile) for i in range(2, 26): print('Changing additional loads...') psspy.load_chng_4(1, '1', realar1=sheet.cell(row=i, column=2).value, realar2=0.01 * sheet.cell(row=i, column=2).value) psspy.load_chng_4(3, '1', realar1=sheet.cell(row=i, column=3).value, realar2=0.01 * sheet.cell(row=i, column=3).value) psspy.load_chng_4(4, '1', realar1=sheet.cell(row=i, column=4).value, realar2=0.01 * sheet.cell(row=i, column=4).value)
def QVAnalysis(CASE,ireg,activateplot): busno = 44999 # Fictitious generator bus genid = 1 status = 1 pgen = 0.0 # Fict gen P output Qlimit = 9999.0 # Fict. gen Q limit pmax = 0.0 # Fict gen P limit #-------------------------------- def add_machine(): psspy.plant_data(busno, intgar1=ireg) psspy.machine_data_2( busno, str(genid), intgar1=int(status), realar1=pgen, realar3=Qlimit, realar4=-Qlimit, realar5=pmax) def get_mvar(i): """ Changes the voltage set point at the synchronous machine solves the case returns the the new reactive power output of the sync machine. """ psspy.plant_data(busno, realar1=i) ierr = psspy.fnsl() val = psspy.solved() if val == 0: ierr, mvar = psspy.macdat(busno, str(genid), 'Q') return mvar else: return None def get_genExhausted(pv): """ get the number of gen whose reactive power got exhausted. """ genExhausted = [] GenReactivePowerOutput = getGenReactivePowerOutput(pv) GenReactivePowerMax = getGenReactivePowerMax(pv) GenReactivePowerMin = getGenReactivePowerMin(pv) for i in range(0,len(pv)): if GenReactivePowerOutput[i] == GenReactivePowerMax[i] \ or GenReactivePowerOutput[i] == GenReactivePowerMin[i]: genExhausted.append(pv[i]) return genExhausted psspy.psseinit(12000) psspy.case(CASE) psspy.solution_parameters_3(intgar2=60) # set number of solution iterations. psspy.bus_data_2(busno, intgar1=2, name='TEST') psspy.branch_data(i=busno, j=ireg) all_bus = findAllBuses() pq,pv,slackBus = findAllBusType(all_bus) add_machine() # get gen that exhausted its reactive power genExhausted_old = get_genExhausted(pv) pu = [x for x in np.arange(1.0, 0.2, -0.005)] varlist = [] voltagelist = [] for v in pu: res = get_mvar(v) if res: psspy.save("temp") varlist.append(res) voltagelist.append(v) else: break # get new gen that exhausted its reactive power psspy.case("temp") busGenExhausted = [] genExhausted_new = get_genExhausted(pv) for bus in genExhausted_new: if bus not in genExhausted_old: busGenExhausted.append(bus) QminIndex = np.argmin(varlist) Qmin = varlist[QminIndex] Vmin = voltagelist[QminIndex] if activateplot == 1: plt.plot(voltagelist, varlist, '-o') plt.plot(Vmin,Qmin,'ro') plt.xlabel('PU') plt.ylabel('MVar') plt.grid() return Qmin,Vmin,busGenExhausted
def runSimulation(self): """Runs the simulation by crating an instance of psspy, loading the raw and dyr data, applying the disturbance and controling PEV output power. Finally plots in native PSS/E or export to matlab.""" sufix = str(self._disturbance)+"_"+str(self._control) conec_file = trash_dir+"\\CC1_"+sufix+".out" conet_file = trash_dir+"\\CT1_"+sufix+".out" compile_file = trash_dir+"\\compile_"+sufix+".out" psspy.psseinit(49) #suppress output if required, else redirect it to python if self._suppress_output: psspy.report_output(6,"",[0,0]) psspy.progress_output(6,"",[0,0]) #psspy.progress_output(2,r"""pot.txt""",[0,0]) else: #redirect psse output to python import redirect redirect.psse2py() #---------------------- #read in case data psspy.read(0,self._power_system_object._raw_filename) #solve the power flow psspy.fdns([0,0,0,1,1,1,99,0]) #---------------------- #convert all generators psspy.cong(0) #---------------------- #conv_standard_loads #change the vector of numbers to get constant current, admittance or power conversion utils.convertLoads([0.0,100.0,0.0,100.0]) #convert the PEVs to constant power loads utils.convertPEVs() #---------------------------------------- #read in dynamics data psspy.dyre_new([1,1,1,1],self._power_system_object._dyr_filename,"","","") #solve power flow with dynamics tysl - and fact devices (was in tutorial) - not sure if we need it though psspy.fact() psspy.tysl(1) #set up pre designated channels self._channels.setUpChannels() #designate channel output_file psspy.strt(0,self._channels._channel_file) self._performDynamicSimulation() if self._plot: self._channels.plot(self._channels._channels_to_include) if self._export_to_matlab: description = sufix.replace(" ","_").replace(".","_").replace("=","__") self._channels.exportToMatlab(matlab_dir+"\\"+description+".m",description,True,True,self._export_figures) if self._export_figures: import win32com.client h = win32com.client.Dispatch('matlab.application') h.Execute ("cd('"+os.getcwd()+"\\"+matlab_dir+"');") h.Execute (description) #clean up try: os.remove(conec_file) except: pass try: os.remove(conet_file) except: pass try: os.remove(compile_file) except: pass return self._channels
def main(): # set output path outpath = r"""TpeOut\\""" # TPE reduction TPE_list = r"""TPE_list.xlsx""" rootbus1_list, bus_red_list, d1bus_list, rootbus2_list, retdbus_list, N_tpe = read_bus_TPE(TPE_list) for instance_i in range(N_tpe): bus_root1 = rootbus1_list[instance_i] bus_root2 = rootbus2_list[instance_i] bus_ret = retdbus_list[instance_i] bus_red = bus_red_list[instance_i] bus_d1 = d1bus_list[instance_i] # read power flow model before reduction step i psspy.psseinit(50000) if instance_i == 0: psspy.read(0, r"""FullModel\wecc179_v33.raw""") else: pass psspy.fnsl([1, 0, 0, 1, 1, 0, 0, 0]) # get power flow data pfd = PFData() pfd.getdata(psspy) # count elements in full model if instance_i == 0: n_gen_bf, n_load_bf, n_bus_bf, n_line_bf, n_xfmr_bf, n_shunt_bf = CountEle(pfd) # prepare data for two-port equivalent P1, Q1, Vm1, Va1, PrateA1, PrateB1, P3, Q3, Vm3, Va3, PrateA3, PrateB3, PL, QL, PG, QG, MW_ll, MW_ul, Mvar_ll,\ Mvar_ul, MVA_base, PS, QS, load_bus, gen_bus, shunt_bus = read_subsys_TPE(pfd, bus_root1, bus_red, bus_d1, bus_root2, bus_ret) # calculate TPE equivalent Vm2, Va2, r1, x1, r2, x2 = CalcTwoPortEqui(pfd, P1, Q1, Vm1, Va1, P3, Q3, Vm3, Va3, PL, QL, PG, QG, PS, QS) # Implement two-port equivalent in PSSE DoTpeInPsse(psspy, pfd, bus_root1, bus_root2, bus_ret, bus_red, bus_d1, PL, QL, PG, QG, PS, QS, PrateA1, PrateB1, PrateA3, PrateB3, MW_ll, MW_ul, Mvar_ll, Mvar_ul, MVA_base, Vm2, Va2, r1, x1, r2, x2) # save new power flow data psspy.rawd_2(0, 1, [0, 0, 1, 0, 0, 0, 0], 0, outpath + "tpe_step_" + str(instance_i + 1)) # calc a summary for TPE reduction pfd.getdata(psspy) n_gen_af, n_load_af, n_bus_af, n_line_af, n_xfmr_af, n_shunt_af = CountEle(pfd) # print("\nTPE reduction summary:") print("(# of elements, Before, After, Reduction %)") print("-----------------------------------------------") print(" Buses: ", n_bus_bf, n_bus_af, str(float((n_bus_bf - n_bus_af))/n_bus_bf*100)[0:5] + "%") print(" Generations: ", n_gen_bf, n_gen_af, str(float((n_gen_bf - n_gen_af))/n_gen_bf*100)[0:5] + "%") print(" Loads: ", n_load_bf, n_load_af, str(float((n_load_bf - n_load_af))/n_load_bf*100)[0:5] + "%") print(" Lines: ", n_line_bf, n_line_af, str(float((n_line_bf - n_line_af))/n_line_bf*100)[0:5] + "%") print("Transformers: ", n_xfmr_bf + 1, n_xfmr_af + 1, str(float((n_xfmr_bf - n_xfmr_af))/(n_xfmr_bf+1)*100)[0:5] + "%") print(" Shunts: ", n_shunt_bf, n_shunt_af, str(float((n_shunt_bf - n_shunt_af)) / (n_shunt_bf + 1) * 100)[0:5] + "%")
def Initialize_Case(in_file): psspy.psseinit(50) psspy.case(in_file) #Load example case savnw.sav
if os.path.isdir(PSSE_LOCATION_34): sys.path.append(PSSE_LOCATION_34) import psse34, psspy else: os.environ['PATH'] = PSSE_LOCATION_33 + ';' + os.environ['PATH'] sys.path.append(PSSE_LOCATION_33) import psspy from psspy import _i, _f # importing the default integer and float values used by PSS\E(every API uses them) MyLibraryLocation = r"""C:\Users\Duotong\Google Drive\researches\PMUbasedVArcontrol\DuotongYang\PSSE_simulation\EMSDataAnalysis\20160908\EMSDataAnalysis\MyLibrary""" sys.path.append(MyLibraryLocation) import PowerSystemPsseLibrary as powerlib import numpy as np import scipy as sp psspy.psseinit(80000) import StringIO @contextmanager def silence(file_object=None): """ Discard stdout (i.e. write to null device) or optionally write to given file-like object. """ if file_object is None: file_object = open(os.devnull, 'w') old_stdout = sys.stdout try: sys.stdout = file_object
### Initialization import os, sys import csv psspath = r'C:\Program Files (x86)\PTI\PSSEUniversity32\PSSBIN' sys.path.append(psspath) os.environ['PATH'] += ';' + psspath import psspy import redirect import random redirect.psse2py() psspy.psseinit(10000) import excelpy ################################################################################################################ ################################################################################################################ ################################################################################################################ ################################################################################################################ ## This Section controls the program ## flags turn on/off parts of the code flag1 = 0 ## STEP1- Python: Run TEST4.py program to generate data from PSSE flag4 = 0 ## STEP4- Python: Apply Random Disturbance on the network flag7 = 1 ## STEP7- Apply the Control to the disturbed model in Python ### Begining of the main routine
def __init__(self, studyCase): ''' Constructor ''' psspy.psseinit(1000) psspy.case(studyCase)
def Run_SIM(x,dyr_file,out_file): #inputs are strings\ dyre = r"""C:\Users\psse\Desktop\Phylicia\Error and Accuracy Tracking Project Sp18\RTS96\%s""" %dyr_file out = r"""C:\Users\psse\Desktop\Phylicia\Error and Accuracy Tracking Project Sp18\RTS96\Channels\opt_%s.out""" %out_file print dyr_file ierr = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] #checking for errors output = StringIO.StringIO() with silence(output): ierr[0] = psspy.psseinit(200000) #need to have this high, otherwise there are not enough output channels ierr[1] = psspy.case(r"""C:\Users\psse\Desktop\Phylicia\Error and Accuracy Tracking Project Sp18\RTS96\RTS96DYN.sav""") ierr[2] = psspy.fdns([0,0,0,1,1,0,99,0]) ierr[3] = psspy.cong(0) ierr[4] = psspy.conl(0,1,1,[0,0],[ 100.0,0.0,0.0, 100.0]) ierr[5] = psspy.conl(0,1,2,[0,0],[ 100.0,0.0,0.0, 100.0]) ierr[6] = psspy.conl(0,1,3,[0,0],[ 100.0,0.0,0.0, 100.0]) ierr[7] = psspy.ordr(0) ierr[8] = psspy.fact() ierr[9] = psspy.tysl(0) ierr[10] = psspy.dyre_new([1,1,1,1],dyre,"","","") ierr[11] = psspy.chsb(0,1,[-1,-1,-1,1,13,0]) #record voltage ierr[12] = psspy.chsb(0,1,[-1,-1,-1,1,12,0]) #record frequency ierr[13] = psspy.chsb(0,1,[-1,-1,-1,1,1,0]) #angle ierr[14] = psspy.chsb(0,1,[-1,-1,-1,1,16,0]) #line P & Q ierr[15] = psspy.strt_2([0,0],out) ierr[16] = psspy.run(0, 0.1,1,1,0) #ierr[17] = psspy.dist_branch_fault(217,218,r"""1""",1, 230.0,[0.0,-0.2E+10]) #Line Fault, NaN (network no good) #ierr[17] = psspy.dist_bus_fault(211,1, 230.0,[0.0,-0.2E+10]) #bus Fault, NaN (network no good) #a = int(x[0]) #b = int(x[1]) #ierr[17] = psspy.branch_chng_3(a,b,r"""1""",[0,_i,_i,_i,_i,_i],[_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f],[_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f],"") #Line Outage x = int(x) print "before machine change" ierr[17] = psspy.machine_chng_2(x,r"""1""",[0,_i,_i,_i,_i,_i],[_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f]) #Generator Outage print "after machine change" ierr[18] = psspy.change_channel_out_file(out) ierr[19] = psspy.run(0, 0.5,1,1,0) #this was 10 psspy.dist_clear_fault(1) psspy.change_channel_out_file(out) psspy.run(1, 10.0,1,1,0) ierr[20] = psspy.delete_all_plot_channels() print "completed simulation" print ierr run_output = output.getvalue() current_error = 0 if "Network not converged" in run_output: print "Network not converged" #need to have something in if statement otherwise you get an indentation error result = 0 #this will go out to a if condition to rerun the program with a different selection of buses at this accuracy current_error = 1 #raise SystemExit #this will quit the program elif "NaN" in run_output: print "NaN, network is no good" result = 0 #this will go out to a if condition to rerun the program with a different selection of buses at this accuracy current_error = 1 #raise SystemExit #this will quit the program if current_error == 0 and "INITIAL CONDITIONS CHECK O.K." in run_output: print "continuing with study..." #Gather the data and output to excel data = dyntools.CHNF(out) #getting data from channel.out file d,e,z=data.get_data() #gathering data from data in dictionary format #Concatenate data so all data from one simulation is in one file c = 1 #must start at 1, not zero #Save Frequency and Voltage while c < 726: if c < 100: #Record Angle v=z[c] new_v = ", ".join(str(i) for i in v) #this removes the brackets at the beginning and end of the list so can be processed in matlab a = np.matrix(new_v) #make it into a matrix if c ==1: ang_all = np.copy(a) else: ang_all = np.concatenate((ang_all,a),axis=0) #changed to concatenate vertically to test them all individually if c > 99 and c < 173: #Record Frequency v=z[c] new_v = ", ".join(str(i) for i in v) #this removes the brackets at the beginning and end of the list so can be processed in matlab f = np.matrix(new_v) #make it into a matrix if c ==100: f_all = np.copy(f) else: f_all = np.concatenate((f_all,f),axis=0) #changed to concatenate vertically to test them all individually if c > 172 and c < 246: #Record voltage magnitude v=z[c] new_v = ", ".join(str(i) for i in v) #this removes the brackets at the beginning and end of the list so can be processed in matlab f = np.matrix(new_v) #make it into a matrix if c == 173: all = np.copy(f) else: all = np.concatenate((all,f),axis=0) #changed to concatenate vertically to test them all individually if c > 245 and c < 726: #Record P and Q if float(c/2) == int(c/2): #P , even numbers v=z[c] new_v = ", ".join(str(i) for i in v) #this removes the brackets at the beginning and end of the list so can be processed in matlab f = np.matrix(new_v) #make it into a matrix if c == 246: P_all = np.copy(f) else: P_all = np.concatenate((P_all,f),axis=0) #changed to concatenate vertically to test them all individually else: #Q, odd numbers v=z[c] new_v = ", ".join(str(i) for i in v) #this removes the brackets at the beginning and end of the list so can be processed in matlab f = np.matrix(new_v) #make it into a matrix if c == 247: Q_all = np.copy(f) else: Q_all = np.concatenate((Q_all,f),axis=0) #changed to concatenate vertically to test them all individually c = c+1 result = [all, f_all, ang_all, P_all, Q_all] #0 is voltage, 1 is frequency return result
return hypot(x, y), 180.0 * atan2(y, x) / pi else: return hypot(x, y), atan2(y, x) #--------------------------------------------------------------------- import numpy as np import matplotlib.pyplot as plt import math from itertools import groupby # PSS/E Saved case #CASE = r"C:\Program Files\PTI\PSSE32\EXAMPLE\12TH_PLAN_MAR_2017R1.sav" SAVFILE_LOCATION = r"C:\Program Files (x86)\PTI\PSSE33\EXAMPLE\\" CASE = r"12TH_PLAN_MAR_2017R1.sav" psspy.psseinit(9000) psspy.case(SAVFILE_LOCATION + CASE) ###------------------------ ierr = psspy.bus_data_2(44010, intgar1=4) #BkroA ierr = psspy.bus_data_2(44031, intgar1=4) #RTPSG2 ierr = psspy.bus_data_2(44034, intgar1=4) #RTPSG3 ierr = psspy.bus_data_2(44035, intgar1=4) #RTPSG4 ierr = psspy.bus_data_2(44036, intgar1=4) #KODRG3 ierr = psspy.bus_data_2(44037, intgar1=4) #KODRG4 ierr = psspy.bus_data_2(44140, intgar1=4) #CHAS1 ierr = psspy.bus_data_2(44141, intgar1=4) #RNIGNJ1 ierr = psspy.bus_data_2(44214, intgar1=4) #RNIGNJ2 ierr = psspy.bus_data_2(44219, intgar1=4) #GOLA2 ierr = psspy.bus_data_2(44227, intgar1=4) #RTPS2 ierr = psspy.bus_data_2(44228, intgar1=4) #MOSB2
parent=root, ) import os import sys PSSE_LOCATION = r'c:/program files/pti/psse32/pssbin' sys.path.append(PSSE_LOCATION) os.environ['PATH'] += ';' + PSSE_LOCATION import psspy import redirect redirect.psse2py() psspy.throwPsseExceptions = True psspy.psseinit(1000) psspy.case(savedcase) ierr, (fromnumber, tonumber) = psspy.abrnint( sid=-1, flag=3, # for all in service branches and two winding transformers. string=["FROMNUMBER", "TONUMBER"]) ierr, (weights,) = psspy.abrncplx( sid=-1, flag=3, string=["RX"] ) def inverse(cplx): return 1 / cplx.imag
def runSimulation(self): """Runs the simulation by crating an instance of psspy, loading the raw and dyr data, applying the disturbance and controling PEV output power. Finally plots in native PSS/E or export to matlab.""" sufix = str(self._disturbance) + "_" + str(self._control) conec_file = trash_dir + "\\CC1_" + sufix + ".out" conet_file = trash_dir + "\\CT1_" + sufix + ".out" compile_file = trash_dir + "\\compile_" + sufix + ".out" psspy.psseinit(49) #suppress output if required, else redirect it to python if self._suppress_output: psspy.report_output(6, "", [0, 0]) psspy.progress_output(6, "", [0, 0]) #psspy.progress_output(2,r"""pot.txt""",[0,0]) else: #redirect psse output to python import redirect redirect.psse2py() #---------------------- #read in case data psspy.read(0, self._power_system_object._raw_filename) #solve the power flow psspy.fdns([0, 0, 0, 1, 1, 1, 99, 0]) #---------------------- #convert all generators psspy.cong(0) #---------------------- #conv_standard_loads #change the vector of numbers to get constant current, admittance or power conversion utils.convertLoads([0.0, 100.0, 0.0, 100.0]) #convert the PEVs to constant power loads utils.convertPEVs() #---------------------------------------- #read in dynamics data psspy.dyre_new([1, 1, 1, 1], self._power_system_object._dyr_filename, "", "", "") #solve power flow with dynamics tysl - and fact devices (was in tutorial) - not sure if we need it though psspy.fact() psspy.tysl(1) #set up pre designated channels self._channels.setUpChannels() #designate channel output_file psspy.strt(0, self._channels._channel_file) self._performDynamicSimulation() if self._plot: self._channels.plot(self._channels._channels_to_include) if self._export_to_matlab: description = sufix.replace(" ", "_").replace(".", "_").replace("=", "__") self._channels.exportToMatlab( matlab_dir + "\\" + description + ".m", description, True, True, self._export_figures) if self._export_figures: import win32com.client h = win32com.client.Dispatch('matlab.application') h.Execute("cd('" + os.getcwd() + "\\" + matlab_dir + "');") h.Execute(description) #clean up try: os.remove(conec_file) except: pass try: os.remove(conet_file) except: pass try: os.remove(compile_file) except: pass return self._channels
import os,sys,csv,pdb PSSE_LOCATION_34 = r"""C:\Program Files (x86)\PTI\PSSE34\PSSPY27""" PSSE_LOCATION_33 = r"""C:\Program Files (x86)\PTI\PSSE33\PSSBIN""" if os.path.isdir(PSSE_LOCATION_34): sys.path.append(PSSE_LOCATION_34) import psse34, psspy else: os.environ['PATH'] = PSSE_LOCATION_33 + ';' + os.environ['PATH'] sys.path.append(PSSE_LOCATION_33) import psspy from psspy import _i,_f # importing the default integer and float values used by PSS\E(every API uses them) from pprint import pprint psspy.psseinit(80000) import StringIO #endregion #region[ Defined Functions ] @contextmanager def silence(file_object=None): """ Discard stdout (i.e. write to null device) or optionally write to given file-like object. """ if file_object is None: file_object = open(os.devnull, 'w')
def main(): try: ''' Drives a PSS/E Dynamic simulation and returns values ''' ##### Get everything set up on the PSSE side redirect.psse2py() #output = StringIO.StringIO() with silence(): psspy.psseinit(buses=80000) _i = psspy.getdefaultint() _f = psspy.getdefaultreal() _s = psspy.getdefaultchar() """ # Redirect any psse outputs to psse_log psspy.report_output(2,psse_log,[0,0]) psspy.progress_output(2,psse_log,[0,0]) #ignored psspy.alert_output(2,psse_log,[0,0]) #ignored psspy.prompt_output(2,psse_log,[0,0]) #ignored """ k = 1 for rawFile in RawFileList: # get the percentage loading from the raw file name if rawFile == 'savnw_conp.raw': PL = '100' else: rawFileName = rawFile.replace('.raw', '') PL = rawFileName[-3:] #Parameters. CONFIGURE THIS settings = { # use the same raw data in PSS/E and TS3ph ##################################### 'filename': rawFile, #use the same raw data in PSS/E and TS3ph ################################################################################ 'dyr_file': dyrFile, 'out_file': 'output2.out', 'pf_options': [ 0, #disable taps 0, #disable area exchange 0, #disable phase-shift 0, #disable dc-tap 0, #disable switched shunts 0, #do not flat start 0, #apply var limits immediately 0, #disable non-div solution ] } ##### Load Raw Datafile and do power flow print "\n Reading raw file:", settings['filename'] # " Reading raw file: {0:s}".format('text') FaultRpu = 1e-06 Sbase = 100.0 #FaultBusNomVolt = float(BusDataDict[FaultBus].NominalVolt) #Zbase = FaultBusNomVolt**2/Sbase # float since Sbase is a float #Rohm = FaultRpu*Zbase # fault impedance in ohms ########################## # run nested loops to see if there are any abnormal low voltages simCount = 0 # to keep track of how many simulations are already done croppedHVLineSet = list(HVLineSet) for line1 in croppedHVLineSet: for line2 in croppedHVLineSet: # stability_indicator = 1 # Bus_issues = [] # list of buses where issues (low voltage or high dv_dt) are reported # the lines cannot be the same if line1 == line2: continue # part to ensure there is no duplication of events currentSet = line1 + ';' + line2 currentSetReverse = line2 + ';' + line1 # if case causes topology inconsistencies, continue if currentSet in topology_inconsistent_set or currentSetReverse in topology_inconsistent_set: continue line1Elements = line1.split(',') line2Elements = line2.split(',') # Line 1 params L1Bus1 = int(line1Elements[0]) L1Bus2 = int(line1Elements[1]) L1cktID = line1Elements[2].strip("'").strip() # Line 2 params L2Bus1 = int(line2Elements[0]) L2Bus2 = int(line2Elements[1]) L2cktID = line2Elements[2].strip("'").strip() FaultBusList = [L2Bus1, L2Bus2] # apply faults at both buses for FaultBus in FaultBusList: output = StringIO.StringIO() with silence(): ierr = psspy.read(0, settings['filename']) #This is for the power flow. I'll use the solved case instead ierr = psspy.fnsl(settings['pf_options']) ##### Prepare case for dynamic simulation # Load conversion (multiple-step) psspy.conl(_i, _i, 1, [0, _i], [_f, _f, _f, _f]) # all constant power load to constant current, constant reactive power load to constant admittance # standard practice for dynamic simulations, constant MVA load is not acceptable psspy.conl(1, 1, 2, [_i, _i], [100.0, 0.0, 0.0, 100.0]) psspy.conl(_i, _i, 3, [_i, _i], [_f, _f, _f, _f]) ierr = psspy.cong(0) #converting generators ierr = psspy.ordr( 0 ) #order the network nodes to maintain sparsity ierr = psspy.fact( ) #factorise the network admittance matrix ierr = psspy.tysl(0) #solving the converted case ierr = psspy.dynamicsmode(0) #enter dynamics mode print "\n Reading dyr file:", settings['dyr_file'] ierr = psspy.dyre_new([1, 1, 1, 1], settings['dyr_file']) ierr = psspy.docu(0, 1, [ 0, 3, 1 ]) #print the starting point of state variables # select time step ############################################################## ierr = psspy.dynamics_solution_params( [_i, _i, _i, _i, _i, _i, _i, _i], [ _f, _f, 0.00833333333333333, _f, _f, _f, _f, _f ], 'out_file') # the number here is the time step ################################################################################ ##### select channels ierr = psspy.delete_all_plot_channels( ) # clear channels # get all the bus voltages, angles and frequencies for bus in BusDataDict: bus = int(bus) ierr = psspy.voltage_and_angle_channel( [-1, -1, -1, bus]) ierr = psspy.bus_frequency_channel([-1, bus]) eventStr = PL + '/' + line1 + ';' + line2 + '/F' + str( FaultBus) print 'Event: {}'.format(eventStr) # get the nominal voltages as well as the fault impedance in ohms FaultBusNomVolt = float( BusDataDict[str(FaultBus)].NominalVolt) Zbase = FaultBusNomVolt**2 / Sbase # float since Sbase is a float Rohm = FaultRpu * Zbase # fault impedance in ohms # run simulation till just before the fault ResultsDict = {} #output = StringIO.StringIO() with silence(output): ierr = psspy.strt(0, settings['out_file']) ierr = psspy.run(0, 0.1, 1, 1, 1) ierr = psspy.dist_branch_trip( L1Bus1, L1Bus2, L1cktID) #output = StringIO.StringIO() with silence(output): ierr = psspy.run(0, 0.2, 1, 1, 1) #fault on time outputStr = output.getvalue() if "Network not converged" in outputStr: print 'For ' + eventStr + ':' print 'Network did not converge between branch 1 trip and fault application, skipping...' continue ####### # check for convergence during fault #output = StringIO.StringIO() with silence(output): ierr = psspy.dist_bus_fault( FaultBus, 3, 0.0, [Rohm, 0.0]) ierr = psspy.run(0, 0.3, 1, 1, 1) #fault off time ierr = psspy.dist_clear_fault(1) outputStr = output.getvalue() if "Network not converged" in outputStr: print 'For ' + eventStr + ':' print 'Network did not converge during fault, skipping...' continue # check for convergence between fault clearance and second branch trip #output = StringIO.StringIO() with silence(output): ierr = psspy.run(0, 0.31, 1, 1, 1) #fault off time ierr = psspy.dist_branch_trip( L2Bus1, L2Bus2, L2cktID) ierr = psspy.run(0, 0.35, 1, 1, 1) #fault off time # check for non-convergence #output = StringIO.StringIO() outputStr = output.getvalue() if "Network not converged" in outputStr: print 'For ' + eventStr + ':' print 'Network did not converge between fault clearance and branch 2 trip, skipping...' continue # select run time ############################################################## output = StringIO.StringIO() with silence(output): ierr = psspy.run( 0, 10.0, 1, 1, 1 ) #exit time (second argument is the end time) ################################################################################ # check for non-convergence outputStr = output.getvalue() if "Network not converged" in outputStr: print 'For ' + eventStr + ':' print 'Network did not converge sometime after 2nd branch trip, skipping...' continue outputData = dyntools.CHNF(settings['out_file']) data = outputData.get_data() channelDict = data[ 1] # dictionary where the value is the channel description valueDict = data[ 2] # dictionary where the values are the signal values, keys match that of channelDict tme = valueDict['time'] # get time ResultsDict['time'] = tme for key in channelDict: if key == 'time': continue signalDescr = channelDict[key] words = signalDescr.split() signalType = words[0].strip() bus = words[1].strip() #print Bus + ' ' + signalType if bus not in ResultsDict: ResultsDict[bus] = Results() if signalType == 'VOLT': ResultsDict[bus].volt = valueDict[key] elif signalType == 'ANGL': ResultsDict[bus].angle = valueDict[key] elif signalType == 'FREQ': ResultsDict[bus].freq = valueDict[key] EventsDict[eventStr] = ResultsDict simCount += 1 print 'Simulation ' + str(simCount) + ' out of ' + str( totalSims) # Uncomment next two lines if you want to see the output #with open('output'+str(k) + '.txt','w') as f: # f.write(outputStr) k += 1 save_obj(EventsDict, 'EventData') except Exception: traceback.print_exc(file=logfile) sys.exit(0)
import redirect import psspy import dyntools # getting the raw file ##### Get everything set up on the PSSE side redirect.psse2py() #output = StringIO.StringIO() with silence(): psspy.psseinit(buses=80000) _i=psspy.getdefaultint() _f=psspy.getdefaultreal() _s=psspy.getdefaultchar() # some important parameters FaultRpu = 1e-06 Sbase = 100.0
#Definition of observable Areas - Lines within these areas + tielines will be monitored and reported observable_areas = excel_sheet_to_list(configuration_excel, observable_areas_configuration_sheet) # Activation of PSSE PSSE_LOCATION = r"C:\Program Files (x86)\PTI\PSSE33\PSSBIN" sys.path.append(PSSE_LOCATION) os.environ['PATH'] = os.environ['PATH'] + ';' + PSSE_LOCATION import psspy _f = psspy.getdefaultreal() _i = psspy.getdefaultint() _s = psspy.getdefaultchar() psspy.psseinit(0) psspy.case(PSSE_model_sav) #Start of process psspy.fnsl(powerflow_settings[powerflow_normal] ) #lahendus (Full Newton-Raphson/Lock taps/Lock shunts) #Get inital data for areas area_parameters = ["LOAD", "GEN", "LOSS", "INT"] list_of_area_data = [] for area in areas:
os.environ['PATH']) import psse34 import psspy import redirect import numpy import math import matplotlib as mpl import matplotlib.pyplot as plt import dyntools # OPEN PSS _i = psspy.getdefaultint() _f = psspy.getdefaultreal() _s = psspy.getdefaultchar() redirect.psse2py() psspy.psseinit(50000) ierr = psspy.progress_output(6, ' ', [0, 0]) # disable output ierr = psspy.prompt_output(6, ' ', [0, 0]) # disable output ierr = psspy.report_output(6, ' ', [0, 0]) # disable output # Set Simulation Path. LoadScenario = "SimplifiedSystem" ClauseName = "5.2.5.1 Reactive Power Capability" ProgramPath = "F:/PosDoc Projects/11_Industrial Projects/NEOEN_HW/P_SimulationProgram/" GridInfoPath = "F:/PosDoc Projects/11_Industrial Projects/NEOEN_HW/NEM_files/" + LoadScenario + "/" HuaweiModelPath = "F:/PosDoc Projects/11_Industrial Projects/NEOEN_HW/D_HuaweiModels/34" OutputFilePath = ProgramPath + "SimulationOutput.out" FigurePath = "F:/PosDoc Projects/11_Industrial Projects/NEOEN_HW/R_Results/" PowerFlowFileName = 'NEOEN Western Downs Solar Farm_C3WV_3.raw'
optionally write to given file-like object. """ if file_object is None: file_object = open(os.devnull, 'w') old_stdout = sys.stdout try: sys.stdout = file_object yield finally: sys.stdout = old_stdout output = StringIO.StringIO() with silence(output): psspy.psseinit(80000) # initialize PSS\E in python savecase = 'IEEE 57 bus.sav' psspy.case(savecase) # find all the buses psspy.bsys(0,0,[0.0,0.0],1,[1],0,[],0,[],0,[]) ierr,all_bus = psspy.abusint(0,1,['number']) bus_num = all_bus[0] #List of all machines psspy.bsys(sid = 1,numbus = len(bus_num), buses = bus_num) ierr,machine_bus = psspy.amachint(1,1,['NUMBER']) machine_bus = machine_bus[0] ierr,machine_id = psspy.amachchar(1,1,['ID']) machine_id = machine_id[0]