def Return_Load_Info(): ierr, Complex_Power = psspy.aloadcplx(-1, 4, 'MVANOM') #Obtain Complex Power of Loads ierr, Complex_Current = psspy.aloadcplx(-1, 4, 'ILNOM') #Obtain Complex Currents of Loads ierr, Complex_Impedance = psspy.aloadcplx(-1, 4, 'YLNOM') #Obtain Complex Impedances of Loads ierr, Load_Numbers = psspy.aloadint(-1, 4, 'NUMBER') #Obtain Load Numbers ierr, Load_Count = psspy.aloadcount(-1, 4) #Obtain Count of Loads return Load_Count, Load_Numbers, Complex_Power, Complex_Current, Complex_Impedance
def Return_Load_Info(): ierr, Complex_Power = psspy.aloadcplx(-1, 4, 'MVANOM') #Obtain Complex Power of Loads ierr, Complex_Current = psspy.aloadcplx(-1, 4, 'ILNOM') #Obtain Complex Currents of Loads ierr, Complex_Impedance = psspy.aloadcplx(-1, 4, 'YLNOM') #Obtain Complex Impedances of Loads ierr, Load_Numbers = psspy.aloadint(-1, 4, 'NUMBER') #Obtain Load Numbers ierr, Load_Count = psspy.aloadcount(-1, 4) #Obtain Count of Loads ierr, Load_Amount = psspy.aloadcplx(-1, 4, 'MVAACT') return Load_Count, Load_Numbers, Load_Amount, Complex_Power, Complex_Current, Complex_Impedance
def readLoadPowers(self): ''' Reads and stores active and reactive powers of each load ''' ierr1, [load] = psspy.aloadcplx(-1, 4, 'TOTALACT') self.loadPowerP = [] self.loadPowerQ = [] for cplxload in load: self.loadPowerP.append(cplxload.real) self.loadPowerQ.append(cplxload.imag) assert ierr1 == 0, 'Error with reading active and reactive powers' return self.loadPowerP, self.loadPowerQ
def readLoadPowers(self): ''' Reads and stores active and reactive powers of each load ''' ierr1, [load] = psspy.aloadcplx(-1, 4, 'TOTALACT') self.loadPowerP = [] self.loadPowerQ = [] for cplxload in load: self.loadPowerP.append(cplxload.real) self.loadPowerQ.append(cplxload.imag) assert ierr1 == 0, 'Error with reading active and reactive powers' return self.loadPowerP, self.loadPowerQ
def randdist(argin): filename=argin[0] percentage=argin[1] mode=argin[2] shuntctrlmode=0 if mode!='arbitrary': shuntctrlmode=argin[3] psspy.case(filename) ierr, Qload=psspy.aloadcplx(-1, string="MVAACT") Qload=[x.imag for x in Qload[0]] ierr, tlbuses = psspy.aloadint(string='NUMBER') nbus=len(tlbuses[0]) if mode=='random': zoseq=[0,1]*nbus sb=random.sample(zoseq,nbus) elif mode=='arbitrary': abus=argin[3] # argin[3] in this case is the arbitrary buses to apply the disturbance sb=[0]*nbus for i in range(len(abus)): sb[tlbuses[0].index(abus[i])]=1 else: sb=[1]*nbus for j in range(nbus): if sb[j]==1: Qd=Qload[j]+percentage/100.0*abs(Qload[j]) ierr=psspy.load_data_3(i=tlbuses[0][j],REALAR2=Qd) if shuntctrlmode==1: for i in tlbuses[0]: ierr = psspy.switched_shunt_data_3(i, intgar9=1) psspy.fnsl(options1=0,options5=0) ierr, voltd = psspy.abusreal(-1, string="PU") #voltage at buses after disturbance argout=[] argout.append(voltd) argout.append(Qload) argout.append(tlbuses) return argout;
def LoadIncreaseMW(load_bus, percentage): psspy.bsys(0, 0, [0.0, 0.0], 0, [], len(load_bus), load_bus, 0, [], 0, []) ierr, allBusLoad = psspy.aloadcplx(0, 1, ['MVAACT']) allBusLoad = allBusLoad[0] BusLoadReal = np.real(allBusLoad) return np.sum(BusLoadReal) * percentage / 100
def randdist(argin): filename = argin[0] # initializing input arguments maxdist = argin[1] mode = argin[2] shuntctrlmode = argin[3] capbus = argin[4] capstep = argin[5] capQ = argin[6] pilot = argin[7] ndist = argin[8] nswitch = argin[9] reloadfile = 1 # By default the network data file will be reloaded at each iteration if len(argin) == 11: reloadfile = argin[10] psspy.case(filename) ierr, Qload = psspy.aloadcplx( -1, string="MVAACT" ) # Qload is the amount of apparent power (P+jQ) for all loads Qload = [ x.imag for x in Qload[0] ] # We just need Reactive power (Q) so we find imaginary part of apparent power ierr, tlbuses = psspy.aloadint( string='NUMBER' ) # tlbuses is all loads' bus nomber, it includes also the compensators that we have added as loads to the network nbus = len(tlbuses[0]) # nbus is No. of all load buses ncap = len(capbus) ierr, busn = psspy.abusint(-1, string='NUMBER') npn = len(pilot) volt = [] voltd = [] vpn = [[0 for x in range(npn)] for y in range(ndist * nswitch)] vpnd = [[0 for x in range(npn)] for y in range(ndist * nswitch)] dvpn = [[0 for x in range(npn)] for y in range(ndist * nswitch)] switch = [[0 for x in range(ncap)] for y in range(ndist * nswitch)] for i in range( ndist ): # in this loop we generate ndist random distrurbane cases and apply nswitch control actions on each case if reloadfile == 1: psspy.case(filename) percentage = random.random( ) * maxdist # choose randomly the amount of disturbance with maximum of maxdist zoseq = [0, 1] * nbus if mode == 'random': sb = random.sample( zoseq, nbus) # choose randomly loads to apply the disturbance if mode == 'all': sb = [1] * nbus capQd = [0 for x in range(ncap)] for j in range(nbus): # applying the disturbance if sb[j] == 1: ## if not(tlbuses[0][j] in capbus): # we make sure that no dist. applied on capacitor buses (which are considered also as loads) Qd = Qload[j] + percentage / 100.0 * abs(Qload[j]) ierr = psspy.load_data_3(i=tlbuses[0][j], REALAR2=Qd) if tlbuses[0][j] in capbus: capidx = capbus.index(tlbuses[0][j]) if sb[j] == 1: capQd[capidx] = Qd else: capQd[capidx] = Qload[j] if shuntctrlmode == 1: # by this option we can unlock all compensators over the network for j in tlbuses[0]: ierr = psspy.switched_shunt_data_3(j, intgar9=1) print '###### DIST(' + str(i) + ') ########' psspy.fdns(OPTIONS1=0, OPTIONS5=0, OPTIONS6=1) # do power flow on the disturbed system ierr, v = psspy.abusreal( -1, string="PU" ) # and measure voltage at all buses after disturbance (there is no option in PSS to measure the voltage of just one bus) for j in range( nswitch): # now we apply random cap. switchings nswitch times [scb, ss, qss] = capselect(capbus, capstep, capQ) print '### ADD CAP ###' for k in range(len(scb)): scbidx = capbus.index(scb[k]) switch[i * nswitch + j][scbidx] = ss[k] capQd[scbidx] = capQd[scbidx] - ss[k] * qss[k] ierr = psspy.load_data_3(i=scb[k], REALAR2=capQd[scbidx]) print '###### DIST(' + str(i) + ') , ' + 'SWITCHCASE(' + str( i * nswitch + j) + ') ########' psspy.fdns(OPTIONS1=0, OPTIONS5=0, OPTIONS6=1) # do power flow on the disturbed system ierr, vd = psspy.abusreal( -1, string="PU" ) # and measure voltage at all buses after disturbance (there is no option in PSS to measure the voltage of just one bus) voltd.append(vd) volt.append(v) for k in range(npn): # measuring vpn, and vpnd as outputs pnidx = busn[0].index(pilot[k]) vpn[i * nswitch + j][k] = v[0][pnidx] vpnd[i * nswitch + j][k] = vd[0][pnidx] dvpn[i * nswitch + j][k] = vpnd[i * nswitch + j][k] - vpn[i * nswitch + j][k] print '### REMOVE CAP ###' for k in range( len(scb) ): # after cap switchings we remove their effect for next switching scbidx = capbus.index(scb[k]) capQd[scbidx] = capQd[scbidx] + ss[k] * qss[k] ierr = psspy.load_data_3(i=scb[k], REALAR2=capQd[scbidx]) return volt, voltd, vpn, vpnd, dvpn, switch
x2.show_alerts(False) r0 = 1 c0 = 1 x2.set_range(r0, c0, zip(*vpn)) x2.set_range(r0, c0 + 1, zip(*vpn1)) x2.save() ############################################################## ############################################################## ############################################################## ## STEP7- Apply the Control to the disturbed model in Python if flag7 == 1: ierr, Qload = psspy.aloadcplx( -1, string="MVAACT" ) # Qload is the amount of apparent power (P+jQ) for all loads Qload = [ x.imag for x in Qload[0] ] # We just need Reactive power (Q) so we find imaginary part of apparent power ierr, tlbuses = psspy.aloadint( string='NUMBER' ) # tlbuses is all loads' bus nomber, it includes also the compensators that we have added as loads to the network ctrl = [0, 1, -1, 0, 0, 0, 0, 2, -1, 1, 0, 2, 0, 1, 0, 1] Qctrl = [0 for x in range(ncap)] for k in range(len(ctrl)): Qctrl[k] = Qload[tlbuses[0].index(capbus[k])] - ctrl[k] * capQ[k] ierr = psspy.load_data_3(i=capbus[k], REALAR2=Qctrl[k]) psspy.fdns(OPTIONS1=0, OPTIONS5=0, OPTIONS6=1) # do power flow on the disturbed system
def read_raw(self): ''' Read the raw file.''' # Read bus numbers ierr, bus_numbers = psspy.abusint(-1, 2, 'NUMBER') assert ierr == 0, 'Error with reading bus numbers' # Reads voltage levels at buses stored in self.busNumbers ierr, voltage_levels = psspy.abusreal(-1, 2, 'PU') assert ierr == 0, 'Error reading voltage levels' # Reads voltage levels at buses stored in self.busNumbers ierr, voltage_angles = psspy.abusreal(-1, 2, 'ANGLED') assert ierr == 0, 'Error reading voltage angles' # Creates a Python dictionary containing bus numbers as keys and associates # a dictionary with voltage and angle to each of the keys for bus, voltage, angle in zip(bus_numbers[0], voltage_levels[0], voltage_angles[0]): self.buses[bus] = {'voltage': voltage, 'angle': angle} # Reads and stores bus numbers where generators are connected ierr, [machine_bus_numbers] = psspy.amachint(-1, 4, 'NUMBER') ierr, [machine_ids] = psspy.amachchar(-1, 4, 'ID') assert ierr == 0, 'Error reading generator bus numbers' # Reads and stores active and reactive powers of each generator ierr1, [machine_power_p] = psspy.amachreal(-1, 4, 'PGEN') ierr2, [machine_power_q] = psspy.amachreal(-1, 4, 'QGEN') assert ierr1 == 0 and ierr2 == 0, 'Error with reading active and reactive powers' # Creates a Python dictionary containing keys in form of # "BUSNUMBER_MACHINEID" and associates a dictionary with active and # reactive powers to each of the keys for k in range(0, len(machine_ids)): self.machines[(str(machine_bus_numbers[k]) + '_' + machine_ids[k][:-1])] = { 'bus': machine_bus_numbers[k], 'P': machine_power_p[k], 'Q': machine_power_q[k] } # Reads and stores bus numbers where loads are connected ierr, [load_bus_numbers] = psspy.aloadint(-1, 4, 'NUMBER') ierr, [load_ids] = psspy.aloadchar(-1, 4, 'ID') assert ierr == 0, 'Error reading load bus numbers' # Reads and stores active and reactive powers of each load ierr1, [load] = psspy.aloadcplx(-1, 4, 'TOTALACT') load_power_p = [] load_power_q = [] for cplxload in load: load_power_p.append(cplxload.real) load_power_q.append(cplxload.imag) assert ierr1 == 0, 'Error with reading active and reactive powers' # Creates a Python dictionary containing keys in form of # "BUSNUMBER_LOADID" and associates a dictionary with active and # reactive powers to each of the keys for load, bus, active, reactive in zip(load_ids, load_bus_numbers, load_power_p, load_power_q): self.loads[(str(bus) + '_' + load[:-1])] = { 'bus': bus, 'P': active, 'Q': reactive } # Reads and stores bus numbers where 2WindingTrafos are connected ierr1, [two_w_trafo_from] = psspy.atrnint(-1, 1, 1, 2, 1, 'FROMNUMBER') ierr2, [two_w_trafo_to] = psspy.atrnint(-1, 1, 1, 2, 1, 'TONUMBER') assert ierr1 == 0 and ierr2 == 0, 'Error reading trafo bus numbers' # Reads and stores 2WindingTrafo ratios taking into account the primary side ierr1, [two_w_trafo_ratio1] = psspy.atrnreal(-1, 1, 1, 2, 1, 'RATIO') ierr2, [two_w_trafo_ratio2] = psspy.atrnreal(-1, 1, 1, 2, 1, 'RATIO2') assert ierr1 == 0 and ierr2 == 0, 'Error reading trafo bus numbers' # Creates a Python dictionary containing keys in form of # "BUSNUMBER_LOADID" and associates a dictionary with active and # reactive powers to each of the keys for f_bus, to_bus, ratio1, ratio2 in zip(two_w_trafo_from, two_w_trafo_to, two_w_trafo_ratio1, two_w_trafo_ratio2): self.trafos[(str(f_bus) + '_' + str(to_bus))] = { 'fromBus': f_bus, 'toBus': to_bus, 't1': ratio1, 't2': ratio2 }
def pout_excel(savfile='savnw.sav', outpath=None, show=True): '''Exports power flow results to Excel Spreadsheet. When 'savfile' is not provided, it uses Network Data from PSS(R)E memory. When 'xlsfile' is provided and exists, power flow results are saved in 'next sheet#' of 'xlsfile'. When 'xlsfile' is provided and does not exists, power flow results are saved in 'Sheet1' of 'xlsfile'. When 'xlsfile' is not provided, power flow results are saved in 'Sheet1' of 'Book#.xls' file. ''' import psspy psspy.psseinit() if savfile: ierr = psspy.case(savfile) if ierr != 0: return fpath, fext = os.path.splitext(savfile) if not fext: savfile = fpath + '.sav' #ierr = psspy.fnsl([0,0,0,1,1,0,0,0]) #if ierr != 0: return else: # saved case file not provided, check if working case is in memory ierr, nbuses = psspy.abuscount(-1, 2) if ierr != 0: print '\n No working case in memory.' print ' Either provide a Saved case file name or open Saved case in PSS(R)E.' return savfile, snapfile = psspy.sfiles() # ================================================================================================ # PART 1: Get the required results data # ================================================================================================ # Select what to report if psspy.bsysisdef(0): sid = 0 else: # Select subsytem with all buses sid = -1 flag_bus = 1 # in-service flag_plant = 1 # in-service flag_load = 1 # in-service flag_swsh = 1 # in-service flag_brflow = 1 # in-service owner_brflow = 1 # bus, ignored if sid is -ve ties_brflow = 5 # ignored if sid is -ve # ------------------------------------------------------------------------------------------------ # Case Title titleline1, titleline2 = psspy.titldt() # ------------------------------------------------------------------------------------------------ # Bus Data # Bus Data - Integer istrings = ['number', 'type', 'area', 'zone', 'owner', 'dummy'] ierr, idata = psspy.abusint(sid, flag_bus, istrings) if ierr: print '(1) psspy.abusint error = %d' % ierr return ibuses = array2dict(istrings, idata) # Bus Data - Real rstrings = [ 'base', 'pu', 'kv', 'angle', 'angled', 'mismatch', 'o_mismatch' ] ierr, rdata = psspy.abusreal(sid, flag_bus, rstrings) if ierr: print '(1) psspy.abusreal error = %d' % ierr return rbuses = array2dict(rstrings, rdata) # Bus Data - Complex xstrings = [ 'voltage', 'shuntact', 'o_shuntact', 'shuntnom', 'o_shuntnom', 'mismatch', 'o_mismatch' ] ierr, xdata = psspy.abuscplx(sid, flag_bus, xstrings) if ierr: print '(1) psspy.abuscplx error = %d' % ierr return xbuses = array2dict(xstrings, xdata) # Bus Data - Character cstrings = ['name', 'exname'] ierr, cdata = psspy.abuschar(sid, flag_bus, cstrings) if ierr: print '(1) psspy.abuschar error = %d' % ierr return cbuses = array2dict(cstrings, cdata) # Store bus data for all buses ibusesall = {} rbusesall = {} xbusesall = {} cbusesall = {} if sid == -1: ibusesall = ibuses rbusesall = rbuses xbusesall = xbuses cbusesall = cbuses else: ierr, idata = psspy.abusint(-1, flag_bus, istrings) if ierr: print '(2) psspy.abusint error = %d' % ierr return ibusesall = array2dict(istrings, idata) ierr, rdata = psspy.abusreal(-1, flag_bus, rstrings) if ierr: print '(2) psspy.abusreal error = %d' % ierr return rbusesall = array2dict(rstrings, rdata) ierr, xdata = psspy.abuscplx(-1, flag_bus, xstrings) if ierr: print '(2) psspy.abuscplx error = %d' % ierr return xbusesall = array2dict(xstrings, xdata) ierr, cdata = psspy.abuschar(-1, flag_bus, cstrings) if ierr: print '(2) psspy.abuschar error = %d' % ierr return cbusesall = array2dict(cstrings, cdata) # ------------------------------------------------------------------------------------------------ # Plant Bus Data # Plant Bus Data - Integer istrings = [ 'number', 'type', 'area', 'zone', 'owner', 'dummy', 'status', 'ireg' ] ierr, idata = psspy.agenbusint(sid, flag_plant, istrings) if ierr: print 'psspy.agenbusint error = %d' % ierr return iplants = array2dict(istrings, idata) # Plant Bus Data - Real rstrings = [ 'base', 'pu', 'kv', 'angle', 'angled', 'iregbase', 'iregpu', 'iregkv', 'vspu', 'vskv', 'rmpct', 'pgen', 'qgen', 'mva', 'percent', 'pmax', 'pmin', 'qmax', 'qmin', 'mismatch', 'o_pgen', 'o_qgen', 'o_mva', 'o_pmax', 'o_pmin', 'o_qmax', 'o_qmin', 'o_mismatch' ] ierr, rdata = psspy.agenbusreal(sid, flag_plant, rstrings) if ierr: print 'psspy.agenbusreal error = %d' % ierr return rplants = array2dict(rstrings, rdata) # Plant Bus Data - Complex xstrings = ['voltage', 'pqgen', 'mismatch', 'o_pqgen', 'o_mismatch'] ierr, xdata = psspy.agenbuscplx(sid, flag_plant, xstrings) if ierr: print 'psspy.agenbusreal error = %d' % ierr return xplants = array2dict(xstrings, xdata) # Plant Bus Data - Character cstrings = ['name', 'exname', 'iregname', 'iregexname'] ierr, cdata = psspy.agenbuschar(sid, flag_plant, cstrings) if ierr: print 'psspy.agenbuschar error = %d' % ierr return cplants = array2dict(cstrings, cdata) # ------------------------------------------------------------------------------------------------ # Load Data - based on Individual Loads Zone/Area/Owner subsystem # Load Data - Integer istrings = ['number', 'area', 'zone', 'owner', 'status'] ierr, idata = psspy.aloadint(sid, flag_load, istrings) if ierr: print 'psspy.aloadint error = %d' % ierr return iloads = array2dict(istrings, idata) # Load Data - Real rstrings = [ 'mvaact', 'mvanom', 'ilact', 'ilnom', 'ylact', 'ylnom', 'totalact', 'totalnom', 'o_mvaact', 'o_mvanom', 'o_ilact', 'o_ilnom', 'o_ylact', 'o_ylnom', 'o_totalact', 'o_totalnom' ] ierr, rdata = psspy.aloadreal(sid, flag_load, rstrings) if ierr: print 'psspy.aloadreal error = %d' % ierr return rloads = array2dict(rstrings, rdata) # Load Data - Complex xstrings = rstrings ierr, xdata = psspy.aloadcplx(sid, flag_load, xstrings) if ierr: print 'psspy.aloadcplx error = %d' % ierr return xloads = array2dict(xstrings, xdata) # Load Data - Character cstrings = ['id', 'name', 'exname'] ierr, cdata = psspy.aloadchar(sid, flag_load, cstrings) if ierr: print 'psspy.aloadchar error = %d' % ierr return cloads = array2dict(cstrings, cdata) # ------------------------------------------------------------------------------------------------ # Total load on a bus totalmva = {} totalil = {} totalyl = {} totalys = {} totalysw = {} totalload = {} busmsm = {} for b in ibuses['number']: ierr, ctmva = psspy.busdt2(b, 'MVA', 'ACT') if ierr == 0: totalmva[b] = ctmva ierr, ctil = psspy.busdt2(b, 'IL', 'ACT') if ierr == 0: totalil[b] = ctil ierr, ctyl = psspy.busdt2(b, 'YL', 'ACT') if ierr == 0: totalyl[b] = ctyl ierr, ctys = psspy.busdt2(b, 'YS', 'ACT') if ierr == 0: totalys[b] = ctys ierr, ctysw = psspy.busdt2(b, 'YSW', 'ACT') if ierr == 0: totalysw[b] = ctysw ierr, ctld = psspy.busdt2(b, 'TOTAL', 'ACT') if ierr == 0: totalload[b] = ctld #Bus mismstch ierr, msm = psspy.busmsm(b) if ierr != 1: busmsm[b] = msm # ------------------------------------------------------------------------------------------------ # Switched Shunt Data # Switched Shunt Data - Integer istrings = [ 'number', 'type', 'area', 'zone', 'owner', 'dummy', 'mode', 'ireg', 'blocks', 'stepsblock1', 'stepsblock2', 'stepsblock3', 'stepsblock4', 'stepsblock5', 'stepsblock6', 'stepsblock7', 'stepsblock8' ] ierr, idata = psspy.aswshint(sid, flag_swsh, istrings) if ierr: print 'psspy.aswshint error = %d' % ierr return iswsh = array2dict(istrings, idata) # Switched Shunt Data - Real (Note: Maximum allowed NSTR are 50. So they are split into 2) rstrings = [ 'base', 'pu', 'kv', 'angle', 'angled', 'vswhi', 'vswlo', 'rmpct', 'bswnom', 'bswmax', 'bswmin', 'bswact', 'bstpblock1', 'bstpblock2', 'bstpblock3', 'bstpblock4', 'bstpblock5', 'bstpblock6', 'bstpblock7', 'bstpblock8', 'mismatch' ] rstrings1 = [ 'o_bswnom', 'o_bswmax', 'o_bswmin', 'o_bswact', 'o_bstpblock1', 'o_bstpblock2', 'o_bstpblock3', 'o_bstpblock4', 'o_bstpblock5', 'o_bstpblock6', 'o_bstpblock7', 'o_bstpblock8', 'o_mismatch' ] ierr, rdata = psspy.aswshreal(sid, flag_swsh, rstrings) if ierr: print '(1) psspy.aswshreal error = %d' % ierr return rswsh = array2dict(rstrings, rdata) ierr, rdata1 = psspy.aswshreal(sid, flag_swsh, rstrings1) if ierr: print '(2) psspy.aswshreal error = %d' % ierr return rswsh1 = array2dict(rstrings1, rdata1) for k, v in rswsh1.iteritems(): rswsh[k] = v # Switched Shunt Data - Complex xstrings = ['voltage', 'yswact', 'mismatch', 'o_yswact', 'o_mismatch'] ierr, xdata = psspy.aswshcplx(sid, flag_swsh, xstrings) if ierr: print 'psspy.aswshcplx error = %d' % ierr return xswsh = array2dict(xstrings, xdata) # Switched Shunt Data - Character cstrings = ['vscname', 'name', 'exname', 'iregname', 'iregexname'] ierr, cdata = psspy.aswshchar(sid, flag_swsh, cstrings) if ierr: print 'psspy.aswshchar error = %d' % ierr return cswsh = array2dict(cstrings, cdata) # ------------------------------------------------------------------------------------------------ # Branch Flow Data # Branch Flow Data - Integer istrings = [ 'fromnumber', 'tonumber', 'status', 'nmeternumber', 'owners', 'own1', 'own2', 'own3', 'own4' ] ierr, idata = psspy.aflowint(sid, owner_brflow, ties_brflow, flag_brflow, istrings) if ierr: print 'psspy.aflowint error = %d' % ierr return iflow = array2dict(istrings, idata) # Branch Flow Data - Real rstrings = [ 'amps', 'pucur', 'pctrate', 'pctratea', 'pctrateb', 'pctratec', 'pctmvarate', 'pctmvaratea', 'pctmvarateb', #'pctmvaratec','fract1','fract2','fract3', 'fract4', 'rate', 'ratea', 'rateb', 'ratec', 'p', 'q', 'mva', 'ploss', 'qloss', 'o_p', 'o_q', 'o_mva', 'o_ploss', 'o_qloss' ] ierr, rdata = psspy.aflowreal(sid, owner_brflow, ties_brflow, flag_brflow, rstrings) if ierr: print 'psspy.aflowreal error = %d' % ierr return rflow = array2dict(rstrings, rdata) # Branch Flow Data - Complex xstrings = ['pq', 'pqloss', 'o_pq', 'o_pqloss'] ierr, xdata = psspy.aflowcplx(sid, owner_brflow, ties_brflow, flag_brflow, xstrings) if ierr: print 'psspy.aflowcplx error = %d' % ierr return xflow = array2dict(xstrings, xdata) # Branch Flow Data - Character cstrings = [ 'id', 'fromname', 'fromexname', 'toname', 'toexname', 'nmetername', 'nmeterexname' ] ierr, cdata = psspy.aflowchar(sid, owner_brflow, ties_brflow, flag_brflow, cstrings) if ierr: print 'psspy.aflowchar error = %d' % ierr return cflow = array2dict(cstrings, cdata) # ================================================================================================ # PART 2: Export acquired results to Excel # ================================================================================================ p, nx = os.path.split(savfile) n, x = os.path.splitext(nx) # Require path otherwise Excel stores file in My Documents directory xlsfile = get_output_filename(outpath, 'pout_' + n + '.xlsx') if os.path.exists(xlsfile): xlsfileExists = True else: xlsfileExists = False # Excel Specifications, Worksheet Size: 65,536 rows by 256 columns # Limit maximum data that can be exported to meet above Worksheet Size. maxrows, maxcols = 65530, 256 # if required, validate number of rows and columns against these values # Start Excel, add a new workbook, fill it with acquired data xlApp = win32com.client.Dispatch("Excel.Application") # DisplayAlerts = True is important in order to save changed data. # DisplayAlerts = False suppresses all POP-UP windows, like File Overwrite Yes/No/Cancel. xlApp.DisplayAlerts = False # set this to True if want see Excel file, False if just want to save xlApp.Visible = show if xlsfileExists: # file exist, open it and add worksheet xlApp.Workbooks.Open(xlsfile) xlBook = xlApp.ActiveWorkbook xlSheet = xlBook.Worksheets.Add() else: # file does not exist, add workbook and select sheet (=1, default) xlApp.Workbooks.Add() xlBook = xlApp.ActiveWorkbook xlSheet = xlBook.ActiveSheet try: xlBook.Sheets("Sheet2").Delete() xlBook.Sheets("Sheet3").Delete() except: pass # Format Excel Sheet xlSheet.Columns.WrapText = False xlSheet.Columns.Font.Name = 'Courier New' xlSheet.Columns.Font.Size = 10 nclns, rowvars, xlsclnsdict = exportedvalues() xlSheet.Columns( eval('"' + xlsclnsdict['DESC'] + ':' + xlsclnsdict['BUS'] + '"')).ColumnWidth = 6 xlSheet.Columns( eval('"' + xlsclnsdict['BUSNAME'] + ':' + xlsclnsdict['BUSNAME'] + '"')).ColumnWidth = 18 xlSheet.Columns( eval('"' + xlsclnsdict['CKT'] + ':' + xlsclnsdict['CKT'] + '"')).ColumnWidth = 3 xlSheet.Columns( eval('"' + xlsclnsdict['MW'] + ':' + xlsclnsdict['MVA'] + '"')).ColumnWidth = 10 xlSheet.Columns( eval('"' + xlsclnsdict['%I'] + ':' + xlsclnsdict['%I'] + '"')).ColumnWidth = 6 xlSheet.Columns( eval('"' + xlsclnsdict['VOLTAGE'] + ':' + xlsclnsdict['MVARLOSS'] + '"')).ColumnWidth = 10 xlSheet.Columns( eval('"' + xlsclnsdict['AREA'] + ':' + xlsclnsdict['ZONE'] + '"')).ColumnWidth = 4 xlSheet.Columns( eval('"' + xlsclnsdict['MW'] + ':' + xlsclnsdict['MVA'] + '"')).NumberFormat = "0.00" xlSheet.Columns( eval('"' + xlsclnsdict['%I'] + ':' + xlsclnsdict['%I'] + '"')).NumberFormat = "0.00" xlSheet.Columns( eval('"' + xlsclnsdict['VOLTAGE'] + ':' + xlsclnsdict['MVARLOSS'] + '"')).NumberFormat = "0.00" xlSheet.Columns( eval('"' + xlsclnsdict['CKT'] + ':' + xlsclnsdict['CKT'] + '"')).HorizontalAlignment = -4108 xlSheet.Columns( eval('"' + xlsclnsdict['AREA'] + ':' + xlsclnsdict['ZONE'] + '"')).HorizontalAlignment = -4108 # Integer value -4108 is for setting alignment to "center" # Page steup xlSheet.PageSetup.Orientation = 2 #1: Portrait, 2:landscape xlSheet.PageSetup.LeftMargin = xlApp.InchesToPoints(0.5) xlSheet.PageSetup.RightMargin = xlApp.InchesToPoints(0.5) xlSheet.PageSetup.TopMargin = xlApp.InchesToPoints(0.25) xlSheet.PageSetup.BottomMargin = xlApp.InchesToPoints(0.5) xlSheet.PageSetup.HeaderMargin = xlApp.InchesToPoints(0.25) xlSheet.PageSetup.FooterMargin = xlApp.InchesToPoints(0.25) # ColorIndex Constants # BLACK --> ColorIndex = 1 # WHITE --> ColorIndex = 2 # RED --> ColorIndex = 3 # GREEN --> ColorIndex = 4 # BLUE --> ColorIndex = 5 # PURPLE --> ColorIndex = 7 # LIGHT GREEN --> ColorIndex = 43 # ------------------------------------------------------------------------------------------------ # Report Title colstart = 1 row = 1 col = colstart xlSheet.Cells(row, col).Value = "POWER FLOW OUTPUT REPORT" xlSheet.Cells(row, col).Font.Bold = True xlSheet.Cells(row, col).Font.Size = 14 xlSheet.Cells(row, col).Font.ColorIndex = 7 row += 1 xlSheet.Cells(row, col).Value = savfile row += 1 xlSheet.Cells(row, col).Value = titleline1 row += 1 xlSheet.Cells(row, col).Value = titleline2 row += 2 tr, lc, br, rc = row, 1, row, nclns #toprow, leftcolumn, bottomrow, rightcolumn xlSheet.Range(xlSheet.Cells(tr, lc + 1), xlSheet.Cells(br, rc)).Value = rowvars[1:] xlSheet.Range(xlSheet.Cells(tr, lc), xlSheet.Cells(br, rc)).Font.Bold = True xlSheet.Range(xlSheet.Cells(tr, lc), xlSheet.Cells(br, rc)).Font.ColorIndex = 3 xlSheet.Range(xlSheet.Cells(tr, lc), xlSheet.Cells(br, rc)).VerticalAlignment = -4108 xlSheet.Range(xlSheet.Cells(tr, lc), xlSheet.Cells(br, rc)).HorizontalAlignment = -4108 clnlabelrow = row row += 1 # add blank row after lables # Worksheet Headers and Footer # Put Title and ColumnHeads on top of each page rows2repeat = "$" + str(1) + ":$" + str(row) xlSheet.PageSetup.PrintTitleRows = rows2repeat xlSheet.PageSetup.LeftFooter = "PF Results: " + savfile xlSheet.PageSetup.RightFooter = "&P of &N" # ------------------------------------------------------------------------------------------------ for i, bus in enumerate(ibuses['number']): # select bus and put bus data in a row rd = initdict(rowvars) rd['BUS'] = bus rd['BUSNAME'] = cbuses['exname'][i] rd['VOLTAGE'] = rbuses['pu'][i] rd['AREA'] = ibuses['area'][i] rd['ZONE'] = ibuses['zone'][i] row += 1 rowvalues = [rd[each] for each in rowvars] xlSheet.Range(xlSheet.Cells(row, col), xlSheet.Cells(row, nclns)).Value = rowvalues xlSheet.Range(xlSheet.Cells(row, col), xlSheet.Cells(row, nclns)).Font.Bold = True xlSheet.Range(xlSheet.Cells(row, col), xlSheet.Cells(row, nclns)).Font.ColorIndex = 5 # check generation on selected bus plantbusidxes = busindexes(bus, iplants['number']) for idx in plantbusidxes: pcti = rplants['percent'][idx] if pcti == 0.0: pcti = '' rd = initdict(rowvars) rd['DESC'] = 'FROM' rd['BUSNAME'] = 'GENERATION' rd['MW'] = rplants['pgen'][idx] rd['MVAR'] = rplants['qgen'][idx] rd['MVA'] = rplants['mva'][idx] rd['%I'] = pcti rd['VOLTAGE'] = rplants['kv'][idx] row += 1 rowvalues = [rd[each] for each in rowvars] xlSheet.Range(xlSheet.Cells(row, col), xlSheet.Cells(row, nclns)).Value = rowvalues # check total load on selected bus if bus in totalmva: rd = initdict(rowvars) rd['DESC'] = 'TO' rd['BUSNAME'] = 'LOAD-PQ' rd['MW'] = totalmva[bus].real rd['MVAR'] = totalmva[bus].imag rd['MVA'] = abs(totalmva[bus]) row += 1 rowvalues = [rd[each] for each in rowvars] xlSheet.Range(xlSheet.Cells(row, col), xlSheet.Cells(row, nclns)).Value = rowvalues if bus in totalil: rd = initdict(rowvars) rd['DESC'] = 'TO' rd['BUSNAME'] = 'LOAD-I' rd['MW'] = totalil[bus].real rd['MVAR'] = totalil[bus].imag rd['MVA'] = abs(totalil[bus]) row += 1 rowvalues = [rd[each] for each in rowvars] xlSheet.Range(xlSheet.Cells(row, col), xlSheet.Cells(row, nclns)).Value = rowvalues if bus in totalyl: rd = initdict(rowvars) rd['DESC'] = 'TO' rd['BUSNAME'] = 'LOAD-Y' rd['MW'] = totalyl[bus].real rd['MVAR'] = totalyl[bus].imag rd['MVA'] = abs(totalyl[bus]) row += 1 rowvalues = [rd[each] for each in rowvars] xlSheet.Range(xlSheet.Cells(row, col), xlSheet.Cells(row, nclns)).Value = rowvalues ''' if bus in totalload: rd = initdict(rowvars) rd['DESC'] = 'TO' rd['BUSNAME'] = 'LOAD-TOTAL' rd['MW'] = totalload[bus].real rd['MVAR'] = totalload[bus].imag rd['MVA'] = abs(totalload[bus]) row += 1 rowvalues = [rd[each] for each in rowvars] xlSheet.Range(xlSheet.Cells(row,col),xlSheet.Cells(row,nclns)).Value = rowvalues ''' if bus in totalys: rd = initdict(rowvars) rd['DESC'] = 'TO' rd['BUSNAME'] = 'SHUNT' rd['MW'] = totalys[bus].real rd['MVAR'] = totalys[bus].imag rd['MVA'] = abs(totalys[bus]) row += 1 rowvalues = [rd[each] for each in rowvars] xlSheet.Range(xlSheet.Cells(row, col), xlSheet.Cells(row, nclns)).Value = rowvalues if bus in totalysw: rd = initdict(rowvars) rd['DESC'] = 'TO' rd['BUSNAME'] = 'SWITCHED SHUNT' rd['MW'] = totalysw[bus].real rd['MVAR'] = totalysw[bus].imag rd['MVA'] = abs(totalysw[bus]) row += 1 rowvalues = [rd[each] for each in rowvars] xlSheet.Range(xlSheet.Cells(row, col), xlSheet.Cells(row, nclns)).Value = rowvalues """ # Sometimes load/shunt/switch shunt area/owner/zone's could be different than the bus # to which it is connected. So when producing subsystem based reports, these equipment # might get excluded. # check loads on selected bus loadbusidxes=busindexes(bus,iloads['number']) pq_p = 0; pq_q = 0 il_p = 0; il_q = 0 yl_p = 0; yl_q = 0 for idx in loadbusidxes: pq_p += xloads['mvaact'][idx].real pq_q += xloads['mvaact'][idx].imag il_p += xloads['ilact'][idx].real il_q += xloads['ilact'][idx].imag yl_p += xloads['ylact'][idx].real yl_q += xloads['ylact'][idx].imag pq_mva = abs(complex(pq_p,pq_q)) il_mva = abs(complex(il_p,il_q)) yl_mva = abs(complex(yl_p,yl_q)) if pq_mva: #PQ Loads rd = initdict(rowvars) rd['DESC'] = 'TO' rd['BUSNAME'] = 'LOAD-PQ' rd['MW'] = pq_p rd['MVAR'] = pq_q rd['MVA'] = pq_mva row += 1 rowvalues = [rd[each] for each in rowvars] xlSheet.Range(xlSheet.Cells(row,col),xlSheet.Cells(row,nclns)).Value = rowvalues if il_mva: #I Loads rd = initdict(rowvars) rd['DESC'] = 'TO' rd['BUSNAME'] = 'LOAD-I' rd['MW'] = il_p rd['MVAR'] = il_q rd['MVA'] = il_mva row += 1 rowvalues = [rd[each] for each in rowvars] xlSheet.Range(xlSheet.Cells(row,col),xlSheet.Cells(row,nclns)).Value = rowvalues if yl_mva: #Y Loads rd = initdict(rowvars) rd['DESC'] = 'TO' rd['BUSNAME'] = 'LOAD-Y' rd['MW'] = yl_p rd['MVAR'] = yl_q rd['MVA'] = yl_mva row += 1 rowvalues = [rd[each] for each in rowvars] xlSheet.Range(xlSheet.Cells(row,col),xlSheet.Cells(row,nclns)).Value = rowvalues # check shunts on selected bus if abs(xbuses['shuntact'][i]): rd = initdict(rowvars) rd['DESC'] = 'TO' rd['BUSNAME'] = 'SHUNT' rd['MW'] = xbuses['shuntact'][i].real rd['MVAR'] = xbuses['shuntact'][i].imag rd['MVA'] = abs(xbuses['shuntact'][i]) row += 1 rowvalues = [rd[each] for each in rowvars] xlSheet.Range(xlSheet.Cells(row,col),xlSheet.Cells(row,nclns)).Value = rowvalues # check switched shunts on selected bus swshbusidxes=busindexes(bus,iswsh['number']) pswsh = 0; qswsh = 0 for idx in swshbusidxes: pswsh += xswsh['yswact'][idx].real qswsh += xswsh['yswact'][idx].imag mvaswsh = abs(complex(pswsh,qswsh)) if mvaswsh: rd = initdict(rowvars) rd['DESC'] = 'TO' rd['BUSNAME'] = 'SWITCHED SHUNT' rd['MW'] = pswsh rd['MVAR'] = qswsh rd['MVA'] = mvaswsh row += 1 rowvalues = [rd[each] for each in rowvars] xlSheet.Range(xlSheet.Cells(row,col),xlSheet.Cells(row,nclns)).Value = rowvalues """ # check connected branches to selected bus flowfrombusidxes = busindexes(bus, iflow['fromnumber']) for idx in flowfrombusidxes: if iflow['tonumber'][ idx] < 10000000: #don't process 3-wdg xmer star-point buses tobusidx = busindexes(iflow['tonumber'][idx], ibusesall['number']) tobusVpu = rbusesall['pu'][tobusidx[0]] tobusarea = ibusesall['area'][tobusidx[0]] tobuszone = ibusesall['zone'][tobusidx[0]] pcti = rflow['pctrate'][idx] if pcti == 0.0: pcti = '' rd = initdict(rowvars) rd['DESC'] = 'TO' rd['BUS'] = iflow['tonumber'][idx] rd['BUSNAME'] = cflow['toexname'][idx] rd['CKT'] = cflow['id'][idx] rd['MW'] = rflow['p'][idx] rd['MVAR'] = rflow['q'][idx] rd['MVA'] = rflow['mva'][idx] rd['%I'] = pcti rd['VOLTAGE'] = tobusVpu rd['MWLOSS'] = rflow['ploss'][idx] rd['MVARLOSS'] = rflow['qloss'][idx] rd['AREA'] = tobusarea rd['ZONE'] = tobuszone row += 1 rowvalues = [rd[each] for each in rowvars] xlSheet.Range(xlSheet.Cells(row, col), xlSheet.Cells(row, nclns)).Value = rowvalues # Bus Mismatch if bus in busmsm: rd = initdict(rowvars) rd['BUSNAME'] = 'BUS MISMATCH' rd['MW'] = busmsm[bus].real rd['MVAR'] = busmsm[bus].imag rd['MVA'] = abs(busmsm[bus]) row += 1 rowvalues = [rd[each] for each in rowvars] xlSheet.Range(xlSheet.Cells(row, col), xlSheet.Cells(row, nclns)).Value = rowvalues xlSheet.Range(xlSheet.Cells(row, col), xlSheet.Cells(row, nclns)).Font.ColorIndex = 10 xlSheet.Range(xlSheet.Cells(row, col), xlSheet.Cells(row, nclns)).Font.Bold = True # xlEdgeTop border set to xlThin xlSheet.Range(xlSheet.Cells(row, col + 4), xlSheet.Cells(row, col + 6)).Borders(8).Weight = 2 # Insert EdgeBottom border(Borders(9)) with xlThin weight(2) xlSheet.Range(xlSheet.Cells(row, col), xlSheet.Cells(row, nclns)).Borders(9).Weight = 2 # Insert blank row row += 1 # ------------------------------------------------------------------------------------------------ # Draw borders # Column Lable Row # xlEdgeTop border set to xlThin xlSheet.Range(xlSheet.Cells(clnlabelrow, 1), xlSheet.Cells(clnlabelrow, nclns)).Borders(8).Weight = 2 # xlEdgeBottom border set to xlThin xlSheet.Range(xlSheet.Cells(clnlabelrow, 2), xlSheet.Cells(clnlabelrow, nclns)).Borders(9).Weight = 2 # Remaining WorkSheet # xlEdgeLeft border set to xlThinline xlSheet.Range(xlSheet.Cells(clnlabelrow, 1), xlSheet.Cells(row - 1, nclns)).Borders(7).Weight = 2 # xlEdgeRight border set to xlThinline xlSheet.Range(xlSheet.Cells(clnlabelrow, 1), xlSheet.Cells(row - 1, nclns)).Borders(10).Weight = 2 # xlInsideVertical border set to xlHairline xlSheet.Range(xlSheet.Cells(clnlabelrow, 1), xlSheet.Cells(row - 1, nclns)).Borders(11).Weight = 1 # ------------------------------------------------------------------------------------------------ # Save the workbook and close the Excel application if xlsfile: # xls file provided xlBook.SaveAs(Filename=xlsfile) else: xlsbookfilename = os.path.join( os.getcwd(), xlBook.Name) # xlBook.Name returns without '.xls' xlBook.SaveAs(Filename=xlsbookfilename) xlsbookfilename = os.path.join( os.getcwd(), xlBook.Name) # xlBook.Name returns '.xls' extn. if not show: xlBook.Close() xlApp.Quit() txt = '\n Power Flow Results saved to file %s' % xlsfile sys.stdout.write(txt)