def select_channel(self, signal_list): psspy.delete_all_plot_channels() for i in signal_list.keys(): bus_list = signal_list.get(i)[0] if bus_list: psspy.bsys(sid=i, numbus=len(bus_list), buses=bus_list) variable_list = signal_list.get(i)[1] for variable in variable_list: f = None if variable == 'STATE': f = psspy.state_channel elif variable == 'VAR': f = psspy.var_channel if f is not None: for j in bus_list: f(status=[-1, j], ident=variable + str(j)) else: list_ = [ -1, -1, -1, 1, map_Signal2Channel.get(variable), 1 ] if bus_list: psspy.chsb(i, 0, list_) else: psspy.chsb(0, 1, list_) psspy.strt(0, self.out_file)
def Islanding(Time_Trip, Time_Reconnect, End_Time, Out_File): psspy.strt(0,Out_File) #Start our case and specify our output file psspy.run(0,0.0,1,1,0) #Run until 0 seconds psspy.run(0, 10,1,1,0) #Run until 50 seconds psspy.dist_branch_trip(323,325,r"""1""") #Open branch between main grid and microgrid psspy.change_channel_out_file(Out_File) #Resume our output file psspy.run(0, 10,1,1,0) #Run until 100 seconds psspy.dist_branch_trip(223,318,r"""1""") #Open branch between main grid and microgrid psspy.change_channel_out_file(Out_File) #Resume our output file psspy.run(0, 10,1,1,0) #Run until 100 seconds psspy.dist_branch_trip(121,325,r"""1""") #Open branch between main grid and microgrid psspy.change_channel_out_file(Out_File) #Resume our output file psspy.run(0, 10,1,1,0) #Run until 100 seconds
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 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 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 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])
print('Event: {}'.format(event)) # 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 output = StringIO.StringIO() with silence(output): # load the sav and snp file psspy.case(savFile) psspy.rstr(snpFile) #output = StringIO.StringIO() with silence(output): ierr = psspy.strt(0,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 ' + event + ':') print('Network did not converge between branch 1 trip and fault application, skipping...') continue ####### # check for convergence during fault
#print L1Bus1 #print L1Bus2 #print L1cktID # Line 2 params line2 = line2Elements.split(',') L2Bus1 = int(line2[0].strip()) L2Bus2 = int(line2[1].strip()) L2cktID = line2[2].strip("'").strip() #print L2Bus1 #print L2Bus2 #print L2cktID #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 ' + event + ':' print 'Network did not converge between branch 1 trip and fault application, skipping...' continue ####### # check for convergence during fault
# save converted case psspy.save(r'{0}\savnw_C.sav'.format(example_path)) # Load dynamics ierr = psspy.dyre_new([_i, _i, _i, _i], dyr_case, _s, _s, _s) # Set output channels psspy.chsb(sid=0, all=1, status=[-1, -1, -1, 1, 12, 0]) # # Save snapshot psspy.snap(sfile=r'{0}\PythonDynTest.snp'.format(example_path)) # Initialize and run the dynamic scenario psspy.strt(option=0, outfile=out_file) psspy.run(0, 1, 0, 0, 0) # 3-phase fault on bus 151 (default bus fault is a 3phase and there is no bus 151) psspy.dist_bus_fault(ibus=151) # Run to 3 cycles time = 3.0 / 60.0 psspy.run(0, 1 + time, 0, 0, 0) # Clear fault (assuming only part of bus faults) psspy.dist_clear_fault() psspy.dist_branch_trip(ibus=151, jbus=201, id='1') # Run to 10 seconds time = 10
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)
# Convert the loads for dynamic simulation psspy.cong(0) psspy.conl(0, 1, 1, [0, 0], [10.0, 10.0, 0.0, 100.0]) psspy.conl(0, 1, 2, [0, 0], [10.0, 10.0, 0.0, 100.0]) psspy.conl(0, 1, 3, [0, 0], [10.0, 10.0, 0.0, 100.0]) # Set the time step for the dynamic simulation psspy.dynamics_solution_params(realar=[_f, _f, 0.005, _f, _f, _f, _f, _f]) psspy.machine_array_channel([1, 2, 5500]) # Monitor Skien Power (as 5101 Hasle does not have any machine to measure frequency) psspy.machine_array_channel([2, 7, 5500]) # Monitor Skien Frequency (as 5101 Hasle does not have any machine to measure frequency) load = load_models.Load(3359) # Create a load consisting of Ringhals ierr = psspy.strt(outfile=outputfile) # Tell PSS/E to write to the output file # Simulation---------------------------------------------------------------------------------------------------------------------------------- if ierr == 0: # nprt: number of time steps between writing to screen # nplt: number of time steps between writing to output file psspy.run(tpause=0, nprt=0, nplt=0) # run the simulation load.step(1120) # Do a 1120MW load step in Ringhals psspy.run(tpause=120) # Pause the simulation after 120 seconds else: print(ierr) # Read the output file
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 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]) # 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 # fault + line trip psspy.strt(0,outfile1) psspy.chsb(0,1, [-1,-1,-1,1,13,0]) psspy.run(0, 1.0,1000,1,0)# start from 1 second, 1000 steps, and 1 writing for 1 output step psspy.dist_bus_fault(154,1, 230.0,[0.0,-0.2E+10]) # ibus, units, voltage kv psspy.run(0, 1.1,1000,1,0)# start from 1.1 second, 1000 steps, and 1 writing for 1 output step psspy.dist_clear_fault(1) psspy.dist_branch_trip(3005,3007,'1') psspy.run(0,1.2,1000,1,0) psspy.dist_machine_trip(3018,'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.chsb(0,1, [-1,-1,-1,1,13,0]) psspy.run(0, 1.0,1000,1,0) psspy.dist_bus_fault(3005,1,230.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(3018,'1') psspy.run(0, 5.0,1000,1,0) psspy.case(savfile) psspy.rstr(snpfile) psspy.strt(0,outfile3) psspy.chsb(0,1, [-1,-1,-1,1,13,0]) 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 runPSSESimBatches(simList, dyrFile, objName): import sys, os # add psspy to the system path sys.path.append(r"C:\Program Files (x86)\PTI\PSSE33\PSSBIN") os.environ['PATH'] = (r"C:\Program Files (x86)\PTI\PSSE33\PSSBIN;" + os.environ['PATH']) from contextlib import contextmanager import StringIO from getBusDataFn import getBusData @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 yield finally: sys.stdout = old_stdout if file_object is None: file_object.close() # Local imports 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 EventsDict = {} for event in simList: eventWords = event.split('/') RawFileIndicator = eventWords[0].strip() linesOutage = eventWords[1].strip() FaultBus = eventWords[2].strip()[ 1:] # exclude the 'F' at the beginning # get the raw file if RawFileIndicator == '100': rawFile = 'savnw_conp.raw' else: rawFile = 'savnw_conp{}.raw'.format(RawFileIndicator) #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 ] } output = StringIO.StringIO() with silence(output): 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 BusDataDict = getBusData(rawFile) # 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]) print 'Event: {}'.format(event) # 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 = {} # get the line params line1Elements = linesOutage.split(';')[0].strip() line2Elements = linesOutage.split(';')[1].strip() # Line 1 params line1 = line1Elements.split(',') L1Bus1 = int(line1[0].strip()) L1Bus2 = int(line1[1].strip()) L1cktID = line1[2].strip("'").strip() #print L1Bus1 #print L1Bus2 #print L1cktID # Line 2 params line2 = line2Elements.split(',') L2Bus1 = int(line2[0].strip()) L2Bus2 = int(line2[1].strip()) L2cktID = line2[2].strip("'").strip() #print L2Bus1 #print L2Bus2 #print L2cktID #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 ' + event + ':' 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(int(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 ' + event + ':' 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 ' + event + ':' 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 ' + event + ':' print 'Network did not converge sometime after 2nd branch trip, skipping...' continue # write to output file #with open('outputTmp.txt','w') as f: # f.write(outputStr) 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[event] = ResultsDict return EventsDict
def run_savnw_simulation(datapath, outfile1, outfile2, outfile3, prgfile): _F1_start=100 _F1_end=100+70*1/60.0; _F2_start = 300 _F2_end = 400; _runto=300; import psspy psspy.psseinit() savfile = 'IEEE 9 Bus_modifiedj4ab.sav' snpfile = 'IEEE 9 Bus_modifiedj4ab.snp' _i = psspy.getdefaultint() _f = psspy.getdefaultreal() _s = psspy.getdefaultchar() INTGAR = [_i] * 7 REALAR = [_f] * 8 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]) #Use this API to specify the progress output device. ierr = psspy.case(savfile) #Use this API to open a PSSE Saved Case file and transfers its data into the PSSE working case if ierr: psspy.progress_output(1,"",[0,0]) print(" psspy.case Error") return ierr = psspy.rstr(snpfile)#Use this API to read a dynamics Snapshot File into PSSE working memory (activity RSTR). if ierr: psspy.progress_output(1,"",[0,0]) print(" psspy.rstr Error") return psspy.strt(0,outfile1) #strt(option, outfile) #Use this API to initialize a PSSE dynamic simulation for state-space simulations (i.e., in preparation for activity RUN) and to specify the Channel Output File into which the output channel values are to be recorded during the dynamic simulation (activity STRT). psspy.run(0, _F1_start,5000,1,0) #Use this API to calculate PSSE state-space dynamic simulations (activity RUN). #psspy.dist_bus_fault(8,1, 230.0,[0.0,-0.2E+10]) #Use this API routine to apply a fault at a bus during dynamic simulations. (Note: use DIST_BUS_FAULT_2 if phase voltages are to be calculated during the simulation.) businfo = subsystem_info('bus', ['NUMBER', 'NAME', 'PU'], sid=-1) print businfo psspy.dist_branch_fault(8,9, '1',3,0.0,[0.0,0.000001]) ##psspy.dist_branch_trip(8, 7, '1') ##psspy.load_chng_5(11, r"""1""", [0, _i, _i, _i, _i, _i, _i], [_f, _f, _f, _f, _f, _f, _f, _f]) businfo = subsystem_info('bus', ['NUMBER', 'NAME', 'PU'], sid=-1) print businfo psspy.run(0, _F1_end+1.5*1/60,5000,1,0) businfo = subsystem_info('bus', ['NUMBER', 'NAME', 'PU'], sid=-1) print businfo #psspy.dist_branch_close(8,7,'1') ## psspy.load_chng_5(11, r"""1""", [1, _i, _i, _i, _i, _i, _i], [_f, _f, _f, _f, _f, _f, _f, _f]) psspy.dist_clear_fault(1) psspy.run(0, _F1_end+2.0, 5000, 1, 0) businfo = subsystem_info('bus', ['NUMBER', 'NAME', 'PU'], sid=-1) print businfo #psspy.dist_clear_fault(1) #Use this API to clear a fault during dynamic simulations. The fault must have previously been applied using one of the following APIs: psspy.run(0, _runto,5000,1,0) #trigger machine # psspy.case(savfile) #Use this API to open a PSSE Saved Case file and transfers its data into the PSSE working case # psspy.rstr(snpfile) #Use this API to read a dynamics Snapshot File into PSSE working memory (activity RSTR). # psspy.strt(0,outfile2) # psspy.run(0, 1.0,1000,1,0) # psspy.dist_machine_trip(2,'1') # psspy.run(0, 10.0,1000,1,0) #trigger line # psspy.case(savfile) # psspy.rstr(snpfile) # psspy.strt(0,outfile3) # psspy.run(0, 1.0,1000,1,0) # psspy.dist_branch_trip(7,8,'1') # psspy.run(0, 10.0,1000,1,0) psspy.lines_per_page_one_device(2,10000000) psspy.progress_output(1,"",[0,0])
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
psspy.voltage_and_angle_channel([-1, -1, -1, 14], ["", ""]) psspy.voltage_and_angle_channel([-1, -1, -1, 39], ["", ""]) psspy.branch_p_channel([-1, -1, -1, 6, 7], r"""1""", "") psspy.branch_p_channel([-1, -1, -1, 13, 14], r"""1""", "") psspy.branch_p_channel([-1, -1, -1, 39, 9], r"""1""", "") psspy.branch_mva_channel([-1, -1, -1, 5, 8], r"""1""", "") psspy.branch_mva_channel([-1, -1, -1, 6, 5], r"""1""", "") psspy.branch_mva_channel([-1, -1, -1, 4, 5], r"""1""", "") psspy.load_array_channel([-1, 1, 71], r"""1""", "") psspy.load_array_channel([-1, 2, 71], r"""1""", "") psspy.load_array_channel([-1, 1, 8], r"""1""", "") psspy.load_array_channel([-1, 2, 8], r"""1""", "") psspy.chsb(0, 1, [-1, -1, -1, 1, 5, 0]) psspy.chsb(0, 1, [-1, -1, -1, 1, 27, 0]) psspy.strt(0, out_file) # Run simulation DELTA = 0.005 psspy.dynamics_solution_param_2(realar3=DELTA) # set sample time, DELTA sec. # Simulation Procedure ##1. System initialization and run simulation to t = 1 s. psspy.run(0, 1, 0, 0, 0) ##2. Apply 3-phase fault at line B6 – B7 at t = 1s. psspy.dist_branch_fault(6, 7, '1', 3, 0.0, [75.625e-5, 0]) ##3. Continue simulation to t = 1.1s. psspy.run(0, 1.1, 0, 0, 0) ##4. Trip line B6 – B7 and clear fault at t = 1.1s. psspy.dist_clear_fault()