def _alt_init_psspy(psse_ver_req=0, control_psse=True \ , pti_path='C:\\Program Files (x86)\\PTI' \ , bug_prt=False): ''' # _alt_init_psspy is an alternative psse/python initializer in case pssepath # is not available. # alternatively, you can use just the commented out lines of code directly # below, but it is less robust than pssepath. # for PSSE 32 and Python 2.5 #import sys #sys.path.append(r'C:\Program Files (x86)\PTI\PSSE32.2.2\PSSBIN') # dbl-check path #import psspy #import redirect #redirect.psse2py() # for PSSE 34 and Python 2.7 #import sys #sys.path.append(r'C:\Program Files (x86)\PTI\PSSE34\PSSBIN') # dbl-check path #import psspy #import redirect #redirect.psse2py() # init_psspy() # 1. Confirms user has required PSS/e version installed. # 2. Confirms user is running version of Python # required # 3. Initializes Python for PSSE interaction. # Returns list of [code, remark] #code: # + value = success # - value = error #remark: informational remark such as failure reason. # Parameters (inputs) # psse_ver_req: PSSE version required for this # script to function properly. # valid values are integers: 31, 32, 33, 34. # control_psse: # True: issue command: redirect.redirect.psse2py(). # False: do not issue the psse2py() command. ''' import sys import os errs=[] # run compatibility check? check_result=[1,'PSS//e and Python versions are compatible. '] # check passed until proven to failed cont=True if psse_ver_req==0: check_result=[2,'Compatibility check declined. '] cont=False # skip compatibility check # ----- Start: Check user PSSE and PY versions for compatibility) ----- # initialize variables psse_py = [[31,2.5],[32,2.5],[33,2.7],[34,2.7]] # psse/py compatibility # validate psse_ver_req parameter: is it a number if cont: try: psse_ver_req=int(float(psse_ver_req)) type(psse_ver_req) except: cont=False check_result=[-1,'psse_ver_req must be a version number from 31 to 34. '] if bug_prt: print check_result # validate psse_ver_req parameter: is it in the psse_py compatability list if cont: cont=False # don't cont compatibility check for i in range(len(psse_py)): if psse_py[i][0]==psse_ver_req: cont=True if not cont: check_result=[-1,'psse_ver_req must be a version number from 31 to 34. '] if bug_prt: print check_result py_ver=0 # get version number for python instance running now (sys.version command) if cont: try: py_ver = str(sys.version).split(' ')[0].split('.') #extract version from beginning of string py_ver = float(str(py_ver[0])+'.'+str(py_ver[1])) # keep only 1 level of subversioning, e.g., keep 2.5 from 2.5.3 if bug_prt: print 'set py_ver:', py_ver except: print r'Warning: init_psspy() had trouble determining python version number.' cont = False for i in range(len(psse_py)): if py_ver==psse_py[i][1]: cont=True if not cont: check_result=[-1,'Python version ' + str(py_ver) +' not compatible. '] if bug_prt: print check_result if bug_prt: print 'py_ver', py_ver # Find PSS/e installations if cont: # pti_path folder exists? if bug_prt: print 'Checking pti_path:', pti_path if not os.path.isdir(pti_path): check_result=[-3,r'Unable to find PSS/e installation folder "' + pti_path + '" on this computer. '] if bug_prt: print check_result print check_result cont = False # Find PSS/e folder(s) if cont: try: psse_paths = os.listdir(pti_path) # get all psse installation paths if bug_prt: print 'Found', len(psse_paths), r'PSS/e install paths: ', psse_paths except: check_result=[-4,r'Unable to find PSS/e installation folder on this computer. '] if bug_prt: print check_result cont = False # Get installed PSS/e version numbers from path # (e.g. path, 'C:\Program Files (x86)\PTI\PSSE32.2.2') if cont: psse_vers=[] psse_path='' for i in range(len(psse_paths)): # check each path for psse_ver_req if bug_prt: print 'path',psse_paths[i] x=str(psse_paths[i])[4:6] if bug_prt: print 'path ver:', x,'; psse_ver_req:',str(psse_ver_req) try: x=int(x) except: x=0 if 31<=x<=34 and str(psse_ver_req)==str(x): psse_path=psse_paths[i] # used later to load psspy library if bug_prt: print 'Found psse_path:',psse_path else: if bug_prt: print 'Did not find a psse_path in psse_paths:',psse_paths, 'where version = ',x if psse_path=='': check_result=[-5,r'Unable to find PSS/e installation folder on this computer. '] if bug_prt: print check_result cont = False # is psse / py version pair in compatibility list. cont = False if bug_prt: print 'Checking psse and python version against compatibility list.' for i in range(len(psse_py)): if bug_prt: print ' ', psse_py[i][0], psse_ver_req, py_ver, psse_py[i][1] if psse_py[i][0]==psse_ver_req and py_ver==psse_py[i][1]: cont = True if bug_prt: print ' Winner - psse and python versions are compatible!' break if not cont: check_result=[-6,'Python version ' + str(py_ver) \ + r' not compatible with PSS/e version ' \ + str(psse_ver_req) + '. Compatibility list. '] # + str(psse_py)<-compaibility list # ----- Done: Check user PSSE and PY versions for compatibility) ----- # ----- Start: Initialize python to interact with PSSE ----- if bug_prt: print ' Starting: Initialize python to interact with PSSE' if check_result[0]<1: if bug_prt: print r'Python - PSS/e compatibility check: ', check_result else: #compatibility check passed or was skipped check_result=[-7,'Unexpected error initializing libraries (sys, psspy and redirect). '] try: import sys check_result=[-8,'Imported sys library. Failed to import psspy and redirect. '] s= pti_path+'\\'+psse_path+"\PSSBIN" sys.path.append(s) if bug_prt: print r'attempting to add to sys.path:', s if bug_prt: print r'sys.path:',sys.path if bug_prt: print r'attempting to load psspy.' import psspy check_result=[4,'Imported sys and psspy libraries. '] if control_psse: if bug_prt: print r'attempting to load redirect.' check_result=[-9,'Imported sys and psspy libraries. Failed to import redirect. '] import redirect if bug_prt: print r'attempting to execute: redirect.psse2py()' redirect.psse2py() check_result=[5,r'Successfully configured Python to control PSS/e. '] if bug_prt: print check_result if bug_prt: print 'init_psspy() completed successfully. ', check_result except: if bug_prt: print 'init_psspy() failed, Code:', check_result if psse_ver_req==0: print r'init_psspy() failed. For more info, run w/PSSE version like: init_psspy(32)' if not bug_prt: print 'Consider setting bug_prt=False for verbose debugging comments.' print r'If that doesn\'t solve your problem, check your PSSE and Pyton installations.' print r'Check out this onenote article for more information:' help_page = r'onenote:///\\corp\shares\TransmissionServices\TSD,%20Shared%20Interest\OneNote%20Notebooks\Software%20Development\Python.one#PSS/E%20library%20for%20Toad§ion-id={A3CDFF46-74C6-4A36-B5F7-805ECC3539D9}&page-id={185CE924-9A62-4B5D-9921-1D2E4A30F244}&end' print help_page import urllib urllib.urlopen(help_page) return check_result
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)
#!C:/Python25/python import os,sys sys.path.append(r"C:\Program Files (x86)\PTI\PSSE32\PSSBIN") os.environ['PATH'] = (r"C:\Program Files (x86)\PTI\PSSE32\PSSBIN;" + os.environ['PATH']) #add the the above line #Here is the macro script import psspy import redirect _i=psspy.getdefaultint() _f=psspy.getdefaultreal() _s=psspy.getdefaultchar() redirect.psse2py() import pssdb psspy.psseinit(80000) psspy.case(r"""psse.sav""") psspy.resq(r""" psse.seq""") psspy.lines_per_page_one_device(1,60) psspy.report_output(2,r"""report.txt""",[0,0]) psspy.flat([1,1,1,0],[0.0,0.0]) psspy.seqd([0,0]) psspy.sequence_network_setup(0) psspy.scmu(1,[0,0,0,0,0,0,0],[0.0,0.0,0.0,0.0,0.0],"") psspy.scmu(2,[7,1082,0,0,0,0,0],[0.0,0.0,0.0,0.0,0.0],"") psspy.scmu(3,[7,1082,0,0,0,0,0],[0.0,0.0,0.0,0.0,0.0],"") psspy.sequence_network_setup(0) #end of script
import csv import math PSSE_LOCATION = r"C:\Program Files (x86)\PTI\PSSE34\PSSPY27" sys.path.append(PSSE_LOCATION) os.environ['PATH'] = os.environ['PATH'] + ';' + PSSE_LOCATION import psse34 import psspy # importing python from psspy import _i,_f # importing the default integer and float values used by PSS\E(every API uses them) import redirect import PowerSystemPsseLibrary as pssepylib import random, pdb redirect.psse2py() # redirecting PSS\E output to python) import numpy import pdb import scipy from scipy import special,optimize from scipy.sparse import bsr_matrix from numpy import genfromtxt from numpy import max psspy.psseinit(80000) savecase = 'IEEE_118.sav' psspy.case(savecase) import StringIO
import psse34 import psspy import redirect import numpy import matplotlib as mpl import matplotlib.pyplot as plt import dyntools import csv from datetime import date import shutil # OPEN PSS _i = psspy.getdefaultint() _f = psspy.getdefaultreal() _s = psspy.getdefaultchar() redirect.psse2py() psspy.psseinit(50000) # if run on laptop LoadScenario = "SummerPeakLoad_No_WDSF" ClauseName = "5.2.5.12 Impact on Network Capability" ProgramPath = "C:/NEOEN/P_SimulationScripts/" GridInfoPath = "C:/NEOEN/NEM_files/" + LoadScenario + "/" HuaweiModelPath = "C:/NEOEN/Huawei_models/" OutputFilePath = ProgramPath + ClauseName + "_Simulation.outx" FigurePath = "C:/NEOEN/R_Results/" + ClauseName + "/" # if run ond desktop # Set Simulation Path. # CHANG: change path according to PC # today = date.today() # LoadScenario = "SummerPeakLoad_No_WDSF"
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
# File:"C:\Users\Duotong\Documents\DuotongYang\PSSE_simulation\ICSEG Power Case 1 - IEEE 14 Bus Systems\20150917_simulation.py", generated on THU, SEP 17 2015 10:10, release 32.00.03 from __future__ import with_statement from contextlib import contextmanager import os, sys PSSE_LOCATION = r"C:\Program Files (x86)\PTI\PSSE32\PSSBIN" sys.path.append(PSSE_LOCATION) os.environ['PATH'] = os.environ['PATH'] + ';' + PSSE_LOCATION import psspy # importing python from psspy import _i, _f # importing the default integer and float values used by PSS\E(every API uses them) import redirect redirect.psse2py() # redirecting PSS\E output to python) import numpy import scipy from scipy import special, optimize 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:
def changeLoad(raw, start, end, step, newdir): """ New raw files are created for each percentage step in [start,end]. The current step defines the percentage scaling up (or down) factor for load and generation """ rawBusDataDict = getBusData(raw) # create a new directory to put the files in currentdir = os.getcwd() if not os.path.exists(newdir): os.mkdir(newdir) output_dir = currentdir + '/' + newdir #genDiscount = 0.90 # ratio of the actual increase in generation genDiscount = 1.0 lossRatio = 0.0 # gen scale-up factor: (scalePercent + (scalePercent-100)*lossRatio)/100 ############################################ for scalePercent in range(start, end + step, step): scalePercent = float( scalePercent) # float is needed, otherwise 101/100 returns 1 scalePercentInt = int( scalePercent) # integer value needed to append to filename scalePercentStr = str(scalePercentInt) # variables to store load data loadBusList = [] # list of load buses (string) loadPList = [] # list of Pload values (string) loadQList = [] # list of Qload values (string) loadPListInt = [] # list of Pload values (float) loadQListInt = [] # list of Qload values (float) #loadBusListInt = [] # list of load buses (int) # variables to store gen data genBusList = [] #genBusListInt = [] genPList = [] genMVAList = [] genMVAListInt = [] genPListInt = [] raw_name = raw.replace('.raw', '') out_file = raw_name + scalePercentStr + '.raw' # output file out_path = output_dir + '/' + out_file impLoadBuses = [ ] # enter specified load buses to scale, if empty all loads are scaled incLoss = ( scalePercent - 100 ) * lossRatio # Additional percentage increase in Pgen (to account for losses) ############################################# #Read raw file with open(raw, 'r') as f: filecontent = f.read() filelines = filecontent.split('\n') ## Get start and end indices of load and gen info ######################################### loadStartIndex = filelines.index( '0 / END OF BUS DATA, BEGIN LOAD DATA') + 1 loadEndIndex = filelines.index( '0 / END OF LOAD DATA, BEGIN FIXED SHUNT DATA') genStartIndex = filelines.index( '0 / END OF FIXED SHUNT DATA, BEGIN GENERATOR DATA') + 1 genEndIndex = filelines.index( '0 / END OF GENERATOR DATA, BEGIN BRANCH DATA') ############################################################################## totalPincr = 0.0 totalQincr = 0.0 percentIncr = (scalePercent - 100.0) / 100 # increment in percentage newPConList = [] newQConList = [] newIPList = [] newIQList = [] newZPList = [] newZQList = [] # Extract load info for i in range(loadStartIndex, loadEndIndex): words = filelines[i].split(',') loadBus = words[0].strip() #loadBusList.append(words[0].strip()) loadPCon = float(words[5].strip()) loadQCon = float(words[6].strip()) loadIP = float(words[7].strip()) loadIQ = float(words[8].strip()) loadZP = float(words[9].strip()) loadZQ = float(words[10].strip()) # calculate the total MW (MVAr) increase in load loadBusVolt = float(rawBusDataDict[loadBus].voltpu) Pincr = percentIncr * ( loadPCon + loadIP * loadBusVolt + loadZP * loadBusVolt**2 ) # this equation is provided in PAGV1 page 293 Qincr = percentIncr * (loadQCon + loadIQ * loadBusVolt + loadZQ * loadBusVolt**2) totalPincr += Pincr totalQincr += Qincr ### # new load values newPConList.append(loadPCon * scalePercent / 100) newQConList.append(loadQCon * scalePercent / 100) newIPList.append(loadIP * scalePercent / 100) newIQList.append(loadIQ * scalePercent / 100) newZPList.append(loadZP * scalePercent / 100) newZQList.append(loadZQ * scalePercent / 100) """ loadPList.append(words[5].strip()) # adding P value (constant power) loadQList.append(words[6].strip()) # adding Q value (constant power) loadIPList.append(words[7].strip()) # constant current P loadIQList.append(words[7].strip()) # constant current Q loadZPList.append(words[9].strip()) # adding P value (constant admittance) loadZQList.append(words[10].strip()) # adding Q value (constant admittance) """ # get total MW gen totalGenMW = 0.0 for i in range(genStartIndex, genEndIndex): words = filelines[i].split(',') GenBus = words[0].strip() if rawBusDataDict[GenBus].type == '3': continue PGen = float(words[2].strip()) totalGenMW += PGen # get new MW Gen GenMWDict = {} # dictionary to hold new PGen values for i in range(genStartIndex, genEndIndex): words = filelines[i].split(',') Bus = words[0].strip() if rawBusDataDict[Bus].type == '3': continue macID = words[1].strip() key = Bus + macID PGen = float(words[2].strip()) genIncr = PGen / totalGenMW * totalPincr newPGen = (PGen + genIncr) * genDiscount GenMVA = float(words[8].strip()) if newPGen < GenMVA: GenMWDict[key] = newPGen else: GenMWDict[key] = GenMVA """ # scale loads by specified percentage for i in range(len(loadPListInt)): #if len(impLoadBuses) ==0: # empty list means that all loads need to be scaled up loadPListInt[i] *= scalePercent/100 loadQListInt[i] *= scalePercent/100 # else: # if loadBusListInt[i] in impLoadBuses: # loadPListInt[i] *= scalePercent/100 # loadQListInt[i] *= scalePercent/100 """ with open(out_path, 'w') as f: # copy everything before load data for i in range(loadStartIndex): f.write(filelines[i]) f.write('\n') # modify the load data j = 0 for i in range(loadStartIndex, loadEndIndex): words = filelines[i].split(',') # change the constant MVA values words[5] = '%.3f' % newPConList[j] words[6] = '%.3f' % newQConList[j] words[5] = words[5].rjust(10) words[6] = words[6].rjust(10) # change the constant current values words[7] = '%.3f' % newIPList[j] words[8] = '%.3f' % newIQList[j] words[7] = words[7].rjust(10) words[8] = words[8].rjust(10) # change the constant impedance values words[9] = '%.3f' % newZPList[j] words[10] = '%.3f' % newZQList[j] words[9] = words[9].rjust(10) words[10] = words[10].rjust(10) # construct a whole string by inserting commas between the words list filelines[i] = reconstructLine2(words) f.write(filelines[i]) f.write('\n') # increment the load list index j += 1 # copy the shunt data, which is in between the load and gen data for i in range(loadEndIndex, genStartIndex): f.write(filelines[i]) f.write('\n') # update and write the gen data for i in range(genStartIndex, genEndIndex): words = filelines[i].split(',') Bus = words[0].strip() if rawBusDataDict[Bus].type == '3': f.write(filelines[i]) f.write('\n') continue macID = words[1].strip() key = Bus + macID newPGen = GenMWDict[key] words[2] = '%.3f' % newPGen words[2] = words[2].rjust(10) # construct a whole string by inserting commas between the words list filelines[i] = reconstructLine2(words) f.write(filelines[i]) f.write('\n') # copy the rest of the raw data for i in range(genEndIndex, len(filelines)): f.write(filelines[i]) f.write('\n') #currentdir = os.getcwd() output_dir = currentdir + '/' + newdir NewRawFiles = os.listdir(output_dir) PathList = [(output_dir + '/' + f) for f in NewRawFiles] redirect.psse2py() psspy.psseinit(buses=80000) _i = psspy.getdefaultint() _f = psspy.getdefaultreal() _s = psspy.getdefaultchar() for i in range(len(PathList)): #Settings. CONFIGURE THIS settings = { # use the same raw data in PSS/E and TS3ph ##################################### 'filename': PathList[i], #use the same raw data in PSS/E and TS3ph ################################################################################ 'dyr_file': '', '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 ] } psse_log = output_dir + '/' + 'log' + NewRawFiles[i].replace( '.raw', '.txt') psspy.report_output(2, psse_log, [0, 0]) psspy.progress_output(2, psse_log, [0, 0]) psspy.alert_output(2, psse_log, [0, 0]) psspy.prompt_output(2, psse_log, [0, 0]) print "\n Reading raw file:", settings['filename'] ierr = psspy.read(0, settings['filename']) ierr = psspy.fnsl(settings['pf_options']) ierr = psspy.rawd_2(0, 1, [1, 1, 1, 0, 0, 0, 0], 0, PathList[i]) """