def calcSCR(sizes, ret_params=False): ''' ARGS: sizes : list of sizes of Sync. Conds RETURNS: scr : list of short circuit ratios Calculation: scr=sqrt(3)*i_sym*v_pu*v_kv*_UNIT_FACTOR/pmax _UNIT_FACTOR=1e-3 ''' # params pmax = [] i_sym = [] v_kv = [] v_pu = [] # non-verbose execution with silence(): for idx in range(len(SC_IDS)): psspy.machine_data_2(i=SC_IDS[idx], id='1', intgar=[1, 0, 0, 0, 0, 0], realar=[ 0, 0, 500, -200, 0, 0, sizes[idx], 0, 0.17, 0, 0, 1, 1, 1, 1, 1, 1 ]) # full newton-rafsan psspy.fnsl(options4=1, options5=1, options6=1) # get symmetric 3-phase fault currents all_currents = pssarrays.iecs_currents(all=1, flt3ph=1, optnftrc=2, vfactorc=1.0) # all bus pu voltage _, (__v_pu, ) = psspy.abusreal(sid=-1, string=["PU"]) # all bus kv voltage _, (__v_kv, ) = psspy.abusreal(sid=-1, string=["BASE"]) # get pmax for _id in MACHINE_IDS: _, _pmax = psspy.macdat(ibus=_id, id='1', string='PMAX') # find power of machine pmax.append(_pmax) # get v_pu,v_kv,i_sym for _id in BUS_IDS: v_pu.append(__v_pu[_id - 1]) v_kv.append(__v_kv[_id - 1]) i_sym.append(all_currents.flt3ph[_id - 1].ibsym.real) total_bus = len(pmax) scr = [] _UNIT_FACTOR = 1e-3 #LOG_INFO('Calculating SCR') for idx in range(total_bus): scr.append( math.sqrt(3) * i_sym[idx] * v_pu[idx] * v_kv[idx] * _UNIT_FACTOR / pmax[idx]) if ret_params: return pmax, i_sym, v_kv, v_pu, scr else: return scr
def getMeasurements(response_buses): psspy.bsys(sid=1, numbus=len(response_buses), buses=response_buses) ierr, bus_voltage = psspy.abusreal(1, 1, ['PU']) bus_voltage = bus_voltage[0] ierr, bus_angle = psspy.abusreal(1, 1, ['ANGLE']) bus_angle = bus_angle[0] return bus_voltage, bus_angle
def get_shunt_voltage(bus_num): psspy.bsys(sid=1, numbus=1, buses=bus_num[0]) ierr, shunt_Pamplin_voltage = psspy.abusreal(1, 1, ['PU']) shunt_Pamplin_voltage = shunt_Pamplin_voltage[0][0] psspy.bsys(sid=1, numbus=1, buses=bus_num[1]) ierr, shunt_Crewe_voltage = psspy.abusreal(1, 1, ['PU']) shunt_Crewe_voltage = shunt_Crewe_voltage[0][0] shunt_bus_voltage = [shunt_Pamplin_voltage, shunt_Crewe_voltage] return shunt_bus_voltage
def evalOneMax(individual): # defining the objective function psspy.case(casestudy) for i in range(len(busidx0)): ierr = psspy.shunt_data(busidx0[i], ID=1, INTGAR=1, REALAR1=0, REALAR2=individual[i]) psspy.fdns(OPTIONS1=0, OPTIONS5=0, OPTIONS6=1) PLOSS = 0 for i in areas[0]: # evaluating sum of losses in all areas ierr, area_loss = psspy.ardat(iar=i, string='LOSS') PLOSS = PLOSS + area_loss.real ierr, vpu = psspy.abusreal(-1, string="PU") vpu0 = vpu[0] JV = 0 for i in range(nbus): if busidx[0][i] in busidx0: JV = JV + min(0, Vmin - vpu0[i])**2 + max( 0, vpu0[i] - Vmax )**2 # Adding voltage limit, Vmin < V < Vmax, as a part of objective function W1, W2 = 1, 10 J = W1 * PLOSS + W2 * JV # Objective function # print(" Loss %s" % PLOSS) return J,
def readVoltageAngles(self): ''' Reads voltage levels at buses stored in self.busNumbers ''' ierr, self.voltageAngles = psspy.abusreal(-1, 2, 'ANGLED') assert ierr == 0, 'Error with reading voltage levels' return self.voltageAngles
def Solve_Steady(): Ok_Solution = 1 psspy.fnsl([0,0,0,1,1,0,99,0]) #Full newton solution ierr, rarray = psspy.abusreal(-1, 2, 'PU') #Get all bus voltages #Check if voltage is above/below a threshold if min(rarray[0]) < 0.95 or max(rarray[0]) > 1.05: Ok_Solution = 0 return rarray, Ok_Solution
def Solve_Steady(): Ok_Solution = 1 psspy.fnsl([0,0,0,1,1,0,99,0]) #Perform Solution ierr, rarray = psspy.abusreal(-1, 2, 'PU') #Returm P.U. voltages of buses after solution #print rarray if min(rarray[0]) < 0.95 or max(rarray[0]) > 1.051: #Find if voltages fall within OK operating ranges (1.051 due to some voltage held buses being specified to 1.05) Ok_Solution = 0 return rarray, Ok_Solution, min(rarray[0]), max(rarray[0])
def loadBusesVA(self, ibus, flag): ierr, buses = psspy.abuscount(ibus, flag) ierr, ( voltages, angle, ) = psspy.abusreal(ibus, flag, ['PU', 'ANGLE']) # print 'voltages: ', voltages # print 'angle: ', angle index = 1 while index <= buses: bus = [voltages[index - 1], angle[index - 1]] self.busVoltAngle[index] = bus index += 1 print 'busVoltAngle', self.busVoltAngle
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;
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 ierr, voltdc = 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) x2 = excelpy.workbook( r'C:\Documents and Settings\xw0419\Mes documents\Mon Projet\Simulation\IREQ\PythonProgs\final_result.xls', sheet="Feuil1", overwritesheet=True, mode='w') x2.show() x2.show_alerts(False) x2.set_range(2, 1, zip(*volt[0])) x2.set_range(2, 2, zip(*volt1[0])) x2.set_range(2, 3, zip(*[voltdc[0]])) ################################################################################################################
# write down the new tap ratio into csv files TransformersRatioFiles = inputDataFolder + "\\transformerRatio" + ".csv" WriteFile = open(TransformersRatioFiles, 'a') writeRatio = csv.writer(WriteFile, delimiter=',', lineterminator='\n') writeRatio.writerow(ratio) WriteFile.close() # run load flow psspy.fdns() N = psspy.solved() if N == 0: # measure the voltage at Farm bus psspy.bsys(sid=1, numbus=len(bus_num), buses=bus_num) ierr, bus_voltage = psspy.abusreal(1, 1, ['PU']) bus_voltage = bus_voltage[0] # measure the voltage at Pamp and Crew buses psspy.bsys(sid=1, numbus=1, buses=shunt_bus[0]) ierr, shunt_Pamp_voltage = psspy.abusreal(1, 1, ['PU']) shunt_Pamp_voltage = shunt_Pamp_voltage[0][0] psspy.bsys(sid=1, numbus=1, buses=shunt_bus[1]) ierr, shunt_Crew_voltage = psspy.abusreal(1, 1, ['PU']) shunt_Crew_voltage = shunt_Crew_voltage[0][0] shunt_bus_voltage = [shunt_Pamp_voltage, shunt_Crew_voltage] # measure the Gen output psspy.bsys(sid=2, numbus=len(gen_bus), buses=gen_bus)
ierr_bus_number, bus_number = psspy.abusint(1, 2, ['NUMBER']) bus_number = bus_number[0] # record the bus number in first row of each file if bus_number_recorded_flag == 0: bus_number_recorded_flag = 1 bus_number_row = [] bus_number_row.extend(bus_number) writer = csv.writer(f1, delimiter=',', lineterminator='\n') writer.writerow(bus_number_row) # measure the voltage at each bus # choose 500KV buses in DVP system # record bus voltage magnitudes ierr, bus_voltage_m = psspy.abusreal(1, 1, ['PU']) bus_voltage_m = bus_voltage_m[0] # record bus voltage phase imags ierr, bus_voltage_a = psspy.abusreal(1, 1, ['ANGLE']) bus_voltage_a = bus_voltage_a[0] # In radians ierr, bus_voltage_complex = psspy.abuscplx(1, 1, ['VOLTAGE']) bus_voltage_complex = bus_voltage_complex[0] bus_voltage = list() for i in range(len(bus_voltage_m)): current_m = bus_voltage_m[i] * baseKV current_a = bus_voltage_a[i] bus_voltage.append(current_m) bus_voltage.append(current_a)
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 }
# Scale up the load at certain percentage change_load(ScaleLoadAtBuses, percentage) load = aloadreal(0, 1, 'TOTALACT') load = load[0] ## #switch off the capbank ## for shunt_bus_num in shunt_bus: ## switchOffCap(shunt_bus_num) # run load flow psspy.fdns() N = psspy.solved() if N == 0: # measure the voltage at each bus psspy.bsys(sid=1, numbus=len(bus_num), buses=bus_num) ierr, bus_voltage = psspy.abusreal(1, 1, ['PU']) bus_voltage = bus_voltage[0] psspy.save(savecase) else: print '### system collapses ###' #endregion print 'Farmville voltage : ' print bus_voltage[0] * 115 print bus_voltage[1] * 230
import os, sys psspath = r'c:\program files\pti\psse32\pssbin' sys.path.append(psspath) os.environ['PATH'] += ';' + psspath import psspy import redirect redirect.psse2py() psspy.psseinit(10000) psspy.case( r'C:\Documents and Settings\xw0419\Mes documents\Mon Projet\Simulation\HQ_PSSmodel\nseieee_jan_23_13_0714.sav' ) psspy.fnsl(options1=0, options5=0) ierr, volt = psspy.abusreal(-1, string="PU") ierr = psspy.load_data_3(i=1020, intgar1=0) ierr, buses = psspy.abusint(-1, string="NUMBER") psspy.fnsl(options1=0, options5=0) ierr, voltd = psspy.abusreal(-1, string="PU") n = len(volt[0][:]) dv = [[0] * n] for i in range(0, n - 1): dv[0][i] = voltd[0][i] - volt[0][i] import excelpy x1 = excelpy.workbook( r'C:\Documents and Settings\xw0419\Mes documents\Mon Projet\Simulation\IREQ\PythonProgs\outdata1.xls', sheet="Feuil1", overwritesheet=False, mode='w') x1.show() x1.show_alerts(False)
change_load(ScaleLoadAtBuses,percentage) load = aloadreal(0,1,'TOTALACT') load = load[0] ## #switch off the capbank ## for shunt_bus_num in shunt_bus: ## switchOffCap(shunt_bus_num) # run load flow psspy.fdns() N = psspy.solved() if N == 0: # measure the voltage at each bus psspy.bsys(sid = 1,numbus = len(bus_num), buses = bus_num) ierr,bus_voltage = psspy.abusreal(1,1,['PU']) bus_voltage = bus_voltage[0] psspy.save(savecase) else: print '### system collapses ###' #endregion print 'Farmville voltage : ' print bus_voltage[0]*115 print bus_voltage[1]*230
import os,sys psspath=r'c:\program files\pti\psse32\pssbin' sys.path.append(psspath) os.environ['PATH'] += ';' + psspath import psspy import redirect redirect.psse2py() psspy.psseinit(10000) psspy.case(r'C:\Documents and Settings\xw0419\Mes documents\Mon Projet\Simulation\HQ_PSSmodel\HQ1_shuntadded.sav') psspy.fnsl( options1=0, options5=0 ) ierr, volt = psspy.abusreal(-1, string="PU") #voltage at buses in normal condition ierr=psspy.load_data_3(i=303, REALAR2=600 ) ierr, buses = psspy.abusint(-1, string="NUMBER") psspy.fnsl( options1=0, options5=0 ) ierr, voltd = psspy.abusreal(-1, string="PU") n=len(volt[0][:]) dv=[[0]*n] for i in range(0,n-1): dv[0][i]=voltd[0][i]-volt[0][i] import excelpy
def update_raw_files(self, to_excel=True, out_dir=None): """Function for updating the psse case file. Args: to_excel(default=True): If a summary should be written to excel out_dir: The directory where the results are stored """ if not out_dir: out_dir = os.getcwd() redirect.psse2py() psspy.throwPsseExceptions = True nbuses = 50000 # max no of buses ierr = psspy.psseinit(nbuses) psspy.case(self.basecase) if to_excel: self.create_excel_sheet() self.to_excel = True else: self.sheet = None for i, col in zip(range(0, 24), range(2, 2 + 24 * 3, 3)): # Represent HVDC links as load and some other exchanges as well print('Changing additional loads...') row = 15 for load in self.ex_as_load: self.load_change(load, i, to_excel, row, col) row = row + 1 print('Changing interarea exchanges...') row = 3 for area, info in self.area_info.items(): country = area[0:2] # Changing interarea exchanges exchange = self.calculate_exchange(info, area, i) self.area_data(info.number, info.bus, exchange, area, row, col + 2) # Changing areas production and consumption self.change_prod_con(info.number, self.data[country]["PS"][area][i], self.data[country]["FB"][area][i], info.pf, tol=4, row=row, column=col) row = row + 1 print('Changes completed...') # Save the raw file to convert to CIM psspy.rawd_2(0, 1, [0, 0, 1, 0, 0, 0, 0], 0, "Snap_before_PF.raw") b = os.path.join(out_dir, 'h' + str( (col - 1) / 3) + '_before_PF.raw') os.rename("Snap_before_PF.raw", b) # Solve the power flow psspy.fnsl([1, 2, 0, 0, 1, 0, 0, 0]) ival = psspy.solved() # flag to check power flow convergence if ival == 0: print('Convergence') if self.to_excel: self.sheet.cell(row=42, column=col).value = 'Convergence' temp_fname = os.path.join(out_dir, "temp.sav") print(temp_fname) psspy.save(temp_fname) # save temporarily the solved case psspy.case(temp_fname) # set the saved case as current case # save the raw file to convert to CIM raw_fname = os.path.join(out_dir, "Snap_after_PF.raw") psspy.rawd_2(0, 1, [0, 0, 1, 0, 0, 0, 0], 0, raw_fname) b = os.path.join(out_dir, 'h' + str(i) + '_after_PF.raw') os.rename(raw_fname, b) if self.to_excel: # Merge cells self.sheet.merge_cells(start_row=1, start_column=col, end_row=1, end_column=col + 2) self.sheet.cell( row=2, column=col).alignment = (Alignment(wrapText=True)) self.sheet.cell(row=2, column=col + 1).alignment = (Alignment(wrapText=True)) self.sheet.cell(row=2, column=col + 2).alignment = (Alignment(wrapText=True)) self.sheet.cell( row=14, column=col).alignment = (Alignment(wrapText=True)) self.sheet.cell(row=14, column=col + 1).alignment = (Alignment(wrapText=True)) self.sheet.cell( row=30, column=col).alignment = (Alignment(wrapText=True)) self.sheet.cell(row=30, column=col + 1).alignment = (Alignment(wrapText=True)) # Headers for data from nordpool self.sheet.cell(row=1, column=col).value = ('hour ' + str(i)) self.sheet.cell( row=2, column=col).value = ('Scheduled\nProduction\n[MWh]') self.sheet.cell( row=2, column=col + 1).value = ('Scheduled\nConsumption\n[MWh]') self.sheet.cell(row=2, column=col + 2).value = ('Scheduled\nExchange\n[MWh]') # Headers for exchanges represented as loads self.sheet.cell(row=14, column=col).value = ('Active Power\n[MW]') self.sheet.cell(row=14, column=col + 1).value = ('Reactive Power\n[MW]') # Headers for results after PSS/E self.sheet.cell( row=30, column=col).value = ('PSSE\nProduction\n[MWh]') self.sheet.cell(row=30, column=col + 1).value = ('PSSE\nConsumption\n[MWh]') self.sheet.cell(row=30, column=col + 2).value = ('PSSE\nExchange\n[MWh]') row = 31 for _, info in self.area_info.items(): # to get the area production complex power ierr = psspy.ardat(info.number, 'GEN') self.sheet.cell(row=row, column=col).value = (round( ierr[1].real, 0)) # to get the area consumption complex power ierr = psspy.ardat(info.number, 'LOAD') self.sheet.cell(row=row, column=col + 1).value = (round( ierr[1].real, 0)) row += 1 # to get the value of the areas active power interchange ierr, intch = psspy.aareareal(-1, 1, 'PINT') for r in range(0, len(intch[0])): self.sheet.cell(row=31 + r, column=col + 2).value = round( intch[0][r].real, 0) # limits check ierr, busvoltages = psspy.abusreal(sid=-1, string="PU") if any(x < 0.95 or x > 1.05 for x in busvoltages[0]): self.sheet.cell( row=43, column=col).value = ('Bus voltage problem') ierr, machPGen = psspy.amachreal(sid=-1, string="PGEN") ierr, machPMax = psspy.amachreal(sid=-1, string="PMAX") ierr, machPMin = psspy.amachreal(sid=-1, string="PMIN") ierr, machQGen = psspy.amachreal(sid=-1, string="QGEN") ierr, machQMax = psspy.amachreal(sid=-1, string="QMAX") ierr, machQMin = psspy.amachreal(sid=-1, string="QMIN") ierr, machS = psspy.amachreal(sid=-1, string="MVA") ierr, machMbase = psspy.amachreal(sid=-1, string="MBASE") for l in range(0, len(machPGen[0])): if (machPGen[0][l] <= machPMin[0][l] or machPGen[0][l] >= machPMax[0][l]): self.sheet.cell(row=45, column=col).value = ( 'Generator active power output problem') for m in range(0, len(machQGen[0])): if (machQGen[0][m] <= machQMin[0][m] or machQGen[0][m] >= machQMax[0][m]): self.sheet.cell(row=46, column=col).value = ( 'Generator reactive power output problem') break for n in range(0, len(machS[0])): if machS[0][n] >= machMbase[0][n]: self.sheet.cell(row=47, column=col).value = ( 'Generator overloading problem') break ierr, brflowA = psspy.aflowreal(sid=-1, string="PCTCORPRATEA") if any(x >= 100 for x in brflowA[0]): self.sheet.cell(row=48, column=col).value = ( 'Branch overloading problem (Rate A)') ierr, brflowB = psspy.aflowreal(sid=-1, string="PCTCORPRATEB") if any(x >= 100 for x in brflowB[0]): self.sheet.cell(row=48, column=col).value = ( 'Branch overloading problem (Rate B)') ierr, brflowC = psspy.aflowreal(sid=-1, string="PCTCORPRATEC") if any(x >= 100 for x in brflowC[0]): self.sheet.cell(row=48, column=col).value = ( 'Branch overloading problem (Rate C)') else: print('No convergence') self.sheet.cell(row=43, column=col).value = 'No convergence' psspy.close_powerflow() # save the Excel file with all data self.wb.save(os.path.join(out_dir, 'PSSE_in_out.xlsx')) os.remove(temp_fname)
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)
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
def get_bus_voltage(bus_num): psspy.bsys(sid=1, numbus=len(bus_num), buses=bus_num) ierr, bus_voltage = psspy.abusreal(1, 1, ['PU']) bus_voltage = bus_voltage[0] return bus_voltage
#psspy.save(CASOsav) #Volvemos a simular psspy.fdns([0, 0, 0, 1, 1, 1, 99, 0]) U = psspy.solv() #bus_i = 798 #bus_f = 734 #ierr, line_rx = psspy.brndt2( bus_i, bus_f, '1', 'RXZ') ############################################################################## ## Lee los buses del modelo ############################################################################## ierr, busnumbers = psspy.abusint(sid=-1, string="NUMBER") ierr, busnames = psspy.abuschar(sid=-1, string="NAME") ierr, busvoltages = psspy.abusreal(sid=-1, string="BASE") #ierr, bus_shunts = psspy.abuscplx(sid=-1, string="SHUNTACT") ############################################################################## ## Instrucciones para recorrer todos los buses y almacenar aquellos que ## verifiquen el criterio de tension base = 132 kV ############################################################################## BUSLIST = [] BUSNAME = [] #Nbus = len( busnumbers[0]) for nb in busnumbers[0]: bus_index = busnumbers[0].index(nb) voltage = busvoltages[0][bus_index] name = busnames[0][bus_index] if voltage == 132.0: print(busnames[0][bus_index])
Bus1, Bus2, cktID, [0, _i, _i, _i, _i, _i], [_f, _f, _f, _f, _f, _f, _f, _f, _f, _f, _f, _f, _f, _f, _f ]) # disconnect branch 1 #ierr = psspy.branch_chng(Bus2,toBus2,cktID2,[0,_i,_i,_i,_i,_i],[_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f]) # disconnect branch 2 ierr = psspy.fnsl(settings['pf_options']) # solve power flow # check for topology inconsistencies converge = psspy.solved() if converge != 0: # topology inconsistencies, skip continue # get the buses and voltages from psse itself ierr, buslist = psspy.abusint( -1, 1, 'NUMBER') # getting bus numbers from raw file buslist = buslist[0] ierr, vpulist = psspy.abusreal(-1, 1, 'PU') vpulist = vpulist[0] # gather the voltage data in a dictionary after the event is applied VoltageDict = { } # key: Bus, value: per unit voltage after the event has been applied and power flow solved for i in range(len(buslist)): Bus = buslist[i] vpu = float(vpulist[i]) VoltageDict[str(Bus)] = vpu # get all the important buses to analyze (within depth 2 of the either end of the branch) Bus1Depth2Dict = getMultDepthNeighbours(str(Bus1), NeighbourDict, 2) Bus2Depth2Dict = getMultDepthNeighbours(str(Bus2), NeighbourDict, 2) B1Depth2N = Bus1Depth2Dict[str( Bus1 )] # the buses (at the end of the line outaged) are included in these sets
# write down the new tap ratio into csv files TransformersRatioFiles = inputDataFolder +"\\transformerRatio" + ".csv" WriteFile = open(TransformersRatioFiles,'a') writeRatio = csv.writer(WriteFile,delimiter = ',',lineterminator = '\n') writeRatio.writerow(ratio) WriteFile.close() # run load flow psspy.fdns() N = psspy.solved() if N == 0: # measure the voltage at Farm bus psspy.bsys(sid = 1,numbus = len(bus_num), buses = bus_num) ierr,bus_voltage = psspy.abusreal(1,1,['PU']) bus_voltage = bus_voltage[0] # measure the voltage at Pamp and Crew buses psspy.bsys(sid = 1,numbus = 1, buses = shunt_bus[0]) ierr,shunt_Pamp_voltage = psspy.abusreal(1,1,['PU']) shunt_Pamp_voltage = shunt_Pamp_voltage[0][0] psspy.bsys(sid = 1,numbus = 1, buses = shunt_bus[1]) ierr,shunt_Crew_voltage = psspy.abusreal(1,1,['PU']) shunt_Crew_voltage = shunt_Crew_voltage[0][0] shunt_bus_voltage = [shunt_Pamp_voltage,shunt_Crew_voltage] # measure the Gen output psspy.bsys(sid = 2,numbus = len(gen_bus), buses = gen_bus)
cont = sheet_bf.cell_value(row, 0) # remove cont contingency in the cont_con_array, to check at the end whether all the contingencies are processed if cont in cont_con_array: cont_con_array.remove(cont) else: cont = 'InitCase' ierr = psspy.getcontingencysavedcase(Zip, isvfile) # extract data for solution 1 and solution 2 # bus section ierr, iarray = psspy.abusint(-1, 1, 'NUMBER') vbusno = iarray[0] # this array has all the bus number print "type:", type(vbusno) ierr, rarray = psspy.abusreal(-1, 1, 'PU') vbusmag = rarray[0] # this array has all the bus voltage magnitude ierr, rarray = psspy.abusreal(-1, 1, 'ANGLE') vbusangle = rarray[ 0] # this array has all the bus voltage angle, in ardians # generator section ierr, iarray = psspy.amachint(-1, 4, 'NUMBER') vgenbusno = iarray[ 0] # this array has all the generator's bus number, including both in-service and out-service ierr, iarray = psspy.amachint(-1, 4, 'STATUS') vgenstatus = iarray[ 0] # this array has all the generator's status: in-service (1) and out-service (0) ierr, carray = psspy.amachchar(-1, 4, 'ID') vgenid = carray[0] # this array has all the generator's ID, string ierr, rarray = psspy.amachreal(-1, 4, 'PGEN')
r'network.sav' ) # change the address and filename to the network that you want to apply the algorithm psspy.case( casestudy ) # load psse model defined by casestudy. since ardat function give areal losses we need these IDs to sum up all areal losses to find overall network loss ierr, areas = psspy.aareaint(-1, 1, 'NUMBER') # id of areas in the network. psspy.fdns( OPTIONS1=0, OPTIONS5=0, OPTIONS6=1) # run power flow in psse model using decoupled newton method PLOSS1 = 0 for i in areas[ 0]: # evaluating sum of losses in all areas, before compensation ierr, area_loss = psspy.ardat(iar=i, string='LOSS') PLOSS1 = PLOSS1 + area_loss.real ierr, vpu1 = psspy.abusreal( -1, string="PU") # voltage at all buses, before compensation vpu01 = vpu1[0] ierr, busidx = psspy.abusint(-1, string='NUMBER') # find All buses busidx0 = [] nbus = len(busidx0) # No. of all buses ierr, PVidx = psspy.agenbusint(-1, 1, 'NUMBER') # find PV buses for idx in busidx[0]: # find PQ buses by removing PV buses from All buses if idx not in PVidx[0]: busidx0.append(idx) Vmin = 0.98 # here you can define your desired Vmin and Vmax Vmax = 1.02 # next three line import methods from deap class to define genetic algorithm. to find out more go to deap library documentation from deap import base
voltd=argout[0] Qload=argout[1] tlbuses=argout[2] vd.append(voltd) ##for i in range(ndist): ## argout=randdist([filename,distpercent[i],'all',1]) ## voltd=argout[0] ## Qload=argout[1] ## tlbuses=argout[2] ## vd.append(voltd) x1=excelpy.workbook(r'C:\Documents and Settings\xw0419\Mes documents\Mon Projet\Simulation\IREQ\PythonProgs\inoutdata.xls',sheet="Feuil1",overwritesheet=True, mode='w') x1.show() x1.show_alerts(False) ierr, baseV = psspy.abusreal(-1, string='BASE') ierr, buses = psspy.abusint(-1, string="NUMBER") x1.set_cell('a1','Bus No.') x1.set_range(2, 'a', zip(*buses)) x1.set_cell('b1','Base Voltage(kv)') x1.set_range(2, 'b', zip(*baseV)) ##distpercent=distpercent*2 ##ndist=ndist*2 for i in range(ndist): x1.set_cell((1,i+3),'dist '+ str(distpercent[i])+' %') x1.set_range(2, i+3, zip(*vd[i])) # the following code shows the effect of capacitor swithching on the disturbed system C=308 capidx=tlbuses[0].index(C)