/* * @(#)BPAXfrBranchRecord.java * * Copyright (C) 2006-2011 www.interpss.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE * as published by the Free Software Foundation; either version 2.1 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * @Author Stephen Hau, Mike Zhou * @Version 1.0 * @Date 02/11/2008 * * Revision History * ================ * */ package org.ieee.odm.adapter.bpa.lf; import static org.ieee.odm.ODMObjectFactory.OdmObjFactory; import java.text.NumberFormat; import org.ieee.odm.common.ODMBranchDuplicationException; import org.ieee.odm.common.ODMException; import org.ieee.odm.common.ODMLogger; import org.ieee.odm.model.aclf.AclfDataSetter; import org.ieee.odm.model.aclf.AclfModelParser; import org.ieee.odm.model.aclf.BaseAclfModelParser; import org.ieee.odm.model.base.BaseDataSetter; import org.ieee.odm.model.base.ODMModelStringUtil; import org.ieee.odm.schema.AdjustmentModeEnumType; import org.ieee.odm.schema.AngleAdjustmentXmlType; import org.ieee.odm.schema.AngleUnitType; import org.ieee.odm.schema.ApparentPowerUnitType; import org.ieee.odm.schema.BranchXmlType; import org.ieee.odm.schema.BusXmlType; import org.ieee.odm.schema.MvarFlowAdjustmentDataXmlType; import org.ieee.odm.schema.NetworkXmlType; import org.ieee.odm.schema.PSXfrBranchXmlType; import org.ieee.odm.schema.TapAdjustBusLocationEnumType; import org.ieee.odm.schema.TapAdjustmentXmlType; import org.ieee.odm.schema.VoltageAdjustmentDataXmlType; import org.ieee.odm.schema.VoltageUnitType; import org.ieee.odm.schema.XfrBranchXmlType; import org.ieee.odm.schema.YUnitType; import org.ieee.odm.schema.ZUnitType; public class BPAXfrBranchRecord { static final int transformer=1; static final int phaseShiftXfr=2; static final int transformerAndPhaseShiftXfr=3; public void processXfrData(final String str, BaseAclfModelParser<? extends NetworkXmlType> parser) throws ODMException { int dataType=0; final String[] strAry = getXformerDataFields(str); if(strAry[0].startsWith("T")){ dataType=transformer; } else if(strAry[0].startsWith("TP")){ dataType=phaseShiftXfr; } final String modCode =strAry[1]; final String owner=strAry[2]; final String fname = strAry[3]; final String tname = strAry[6]; final String fid = BPABusRecord.getBusId(fname); final String tid = BPABusRecord.getBusId(tname); ODMLogger.getLogger().fine("Branch data loaded, from-bus, to-bus: " + fid + ", " + tid); //TODO change 1->0, since one uses "1" while CirId for the other is missing for some parallel branches in BPA String cirId="1"; if(!strAry[8].equals("")){ cirId = strAry[8]; } XfrBranchXmlType branchRec = null; try { branchRec = (XfrBranchXmlType) (dataType == transformer ? parser.createXfrBranch(fid, tid, cirId) : parser.createPSXfrBranch(fid, tid, cirId)); } catch (ODMBranchDuplicationException e) { ODMLogger.getLogger().severe("branch data error, " + e.toString()+ " " + fname + "->" + tname + "_" + cirId); return; } branchRec.setId(ODMModelStringUtil.formBranchId(fid, tid, cirId)); final double fVbase= new Double(strAry[4]).doubleValue(); final double tVbase= new Double(strAry[7]).doubleValue(); // set tieline data, measure location for power interchange, 1--from side, 2- to side // int measureLocation=0; // if(!strAry[5].equals("")){ // measureLocation= new Integer(strAry[5]).intValue(); // try{ // if(measureLocation==1){ // PSSNetworkXmlType.TieLineList.Tieline tieLine=parser.addNewBaseCaseTieline(); // // tieLine.addNewMeteredBus().setName(fid); // tieLine.addNewNonMeteredBus().setName(tid); // // BusRecordXmlType busRecFrom=XBeanParserHelper.findBusRecord(fid, baseCaseNet); // NetAreaXmlType areaFrom=XBeanParserHelper. // getAreaRecordByZone(busRecFrom.getZoneNumber(), baseCaseNet); // tieLine.setMeteredArea(areaFrom.getName()); // // BusRecordXmlType busRecTo=XBeanParserHelper.findBusRecord(tid, baseCaseNet); // NetAreaXmlType areaTo=XBeanParserHelper. // getAreaRecordByZone(busRecTo.getZoneNumber(), baseCaseNet); // tieLine.setNonMeteredArea(areaTo.getName()); // }else{ // PSSNetworkXmlType.TieLineList.Tieline tieLine=parser.addNewBaseCaseTieline(); // // tieLine.addNewMeteredBus().setName(tid); // tieLine.addNewNonMeteredBus().setName(fid); // XBeanParserHelper.findBusRecord(fid, baseCaseNet).getZoneNumber(); // // BusRecordXmlType busRecFrom=XBeanParserHelper.findBusRecord(tid, baseCaseNet); // busRecFrom.getZoneNumber(); // NetAreaXmlType areaFrom=XBeanParserHelper. // getAreaRecordByZone(busRecFrom.getZoneNumber(), baseCaseNet); // tieLine.setMeteredArea(areaFrom.getName()); // // BusRecordXmlType busRecTo=XBeanParserHelper.findBusRecord(fid, baseCaseNet); // busRecTo.getZoneNumber(); // NetAreaXmlType areaTo=XBeanParserHelper. // getAreaRecordByZone(busRecTo.getZoneNumber(), baseCaseNet); // tieLine.setNonMeteredArea(areaTo.getName()); // } // }catch (final Exception e) { // e.printStackTrace(); // } // } final String multiSectionId = strAry[9]; //set rated current double MwRating=0.0; if(!strAry[11].equals("")){ //MwRating = new Integer(strAry[11]).intValue(); } // set xfr rating data AclfDataSetter.setXfrRatingData(branchRec, fVbase, tVbase,VoltageUnitType.KV, MwRating, ApparentPowerUnitType.MVA); double rpu=0.0, xpu=0.0001, Gpu=0.0, Bpu=0.0; if(!strAry[12].equals("")){ rpu = new Double(strAry[12]).doubleValue(); if(Math.abs(rpu)>=1.0&&!strAry[12].contains(".")){ rpu=rpu*0.00001; //F6.5 } rpu=ODMModelStringUtil.getNumberFormat(rpu); if(Math.abs(rpu)>0.1) ODMLogger.getLogger().warning("Tranformer#"+fname+"-to-"+tname + ", the Resistance(R) now is"+rpu+" ,seems to be out of normal range[0~0.1]pu, please check!"); } if(!strAry[13].equals("")){ xpu = new Double(strAry[13]).doubleValue(); if(Math.abs(xpu)>=1&&!strAry[13].contains(".")){ xpu=xpu*0.00001; //F6.5 } xpu=ODMModelStringUtil.getNumberFormat(xpu); if(Math.abs(xpu)>0.5) ODMLogger.getLogger().warning("Tranformer#"+fname+"-to-"+tname+",the Reactance(X) now is" +xpu+" ,seems to be out of normal range[0~0.5]pu, please check!"); } if(!strAry[14].equals("")){ Gpu = new Double(strAry[14]).doubleValue(); if(Math.abs(Gpu)>=1.0&&!strAry[14].contains(".")){ Gpu=Gpu*1e-5; //F6.5 } } if(!strAry[15].equals("")){ Bpu = new Double(strAry[15]).doubleValue(); if(Math.abs(Bpu)>=1.0&&!strAry[15].contains(".")){ Bpu=Bpu*1e-5; //F6.5 } } // set r x if(rpu!=0.0||xpu!=0.0){ branchRec.setZ(BaseDataSetter.createZValue(rpu, xpu, ZUnitType.PU)); } //set g b, g, b---> from side if(Gpu!=0.0||Bpu!=0.0){ branchRec.setMagnitizingY(BaseDataSetter.createYValue(Gpu, Bpu, YUnitType.PU)); } // tap1 or angle for phase shift double fromTurnRatedVolOrAngDeg=0.0, toTurnRatedVolOrZero=0.0; if(!strAry[16].equals("")){ fromTurnRatedVolOrAngDeg = new Double(strAry[16]).doubleValue(); } //tap2 if(strAry[17]!=null&&!strAry[17].equals("")){ toTurnRatedVolOrZero = new Double(strAry[17]).doubleValue(); } double fRatio=1.0, tRatio=1.0; // set transformer ratio and phaseshiftxfr angle if (dataType==transformer){ //to see what is the input data format, specified or not. if(fromTurnRatedVolOrAngDeg>=2*fVbase){ fromTurnRatedVolOrAngDeg=fromTurnRatedVolOrAngDeg/100.0; //F5.2 } fRatio=fromTurnRatedVolOrAngDeg/fVbase; branchRec.setFromTurnRatio(BaseDataSetter.createTurnRatioPU(fRatio)); if(toTurnRatedVolOrZero>=2*tVbase){ toTurnRatedVolOrZero=toTurnRatedVolOrZero/100.0; //F5.2 } tRatio = toTurnRatedVolOrZero/tVbase; //System.out.println("toTurnRatedVol: "+toTurnRatedVolOrZero+", tratio="+tRatio); NumberFormat ddf1 = NumberFormat.getNumberInstance(); ddf1.setMaximumFractionDigits(4); tRatio = new Double(ddf1.format(tRatio)).doubleValue(); branchRec.setToTurnRatio(BaseDataSetter.createTurnRatioPU(tRatio)); } else { PSXfrBranchXmlType psXfrRec = (PSXfrBranchXmlType)branchRec; psXfrRec.setFromAngle(BaseDataSetter.createAngleValue(fromTurnRatedVolOrAngDeg, AngleUnitType.DEG)); psXfrRec.setToAngle(BaseDataSetter.createAngleValue(0, AngleUnitType.DEG)); } } public void processXfrAdjustData(final String str, BaseAclfModelParser<? extends NetworkXmlType> parser) throws ODMException { final String[] strAry = getXfrAdjustDataFields(str); int dataType=0; int angleAdjustment=1; int tapAdjustment=2; int adjustType=3; int tapVoltageAdjustment=4; int tapVarAdjustment=5; int pAngleAdjustment=6; int mAngleAdjustment=7; if(strAry[0].equals("RP")||strAry[0].equals("RM")){ dataType=angleAdjustment; if(strAry[0].equals("RP")){ adjustType=pAngleAdjustment; }else{ adjustType=mAngleAdjustment; } } else{ dataType=tapAdjustment; if(strAry[0].equals("R")||strAry[0].equals("RV")){ adjustType=tapVoltageAdjustment; }else { adjustType=tapVarAdjustment; } } //adjustType: R or RV---remote bus control final String modCode = strAry[1]; final String owner = strAry[2]; final String fromBus =strAry[3]; final double fromTurnRatedV = new Double(strAry[4]).doubleValue(); final String toBus = strAry[6]; final double toTurnRatedV = new Double(strAry[7]).doubleValue(); String cirId = "unknow"; XfrBranchXmlType branchRec = (XfrBranchXmlType)parser.getBranch(fromBus, toBus, cirId); String controlBusId = ""; final String adjBus =strAry[8]; final String adjVol =strAry[9]; // set tapAdjSide int tapAdjSide = 0; if(!strAry[5].equals("")){ tapAdjSide=new Integer(strAry[5]).intValue(); } double stepSize=0.0,maxVoltPQ = 0.0, minVoltPQ = 0.0, totalTap=0.0; double max=0.0, min=0.0; // Minimum MVAR or MW limit [F] // Maximum MVAR or MW limit [F] if(!strAry[10].equals("")){ max = new Double(strAry[10]).doubleValue(); } if(!strAry[11].equals("")){ min = new Double(strAry[11]).doubleValue(); } if(!strAry[12].equals("")){ totalTap = new Double(strAry[12]).doubleValue(); } if(!strAry[13].equals("")){ maxVoltPQ = new Double(strAry[13]).doubleValue(); } if(!strAry[14].equals("")){ minVoltPQ = new Double(strAry[14]).doubleValue(); } // calculate stepsize if (totalTap!=0.0){ stepSize =(max-min)/totalTap; } // scheduled Q for RQ double scheduleQ=0.0; if(!strAry[13].equals("")){ scheduleQ = new Double(strAry[13]).doubleValue(); } if(dataType==tapAdjustment){ TapAdjustmentXmlType tapAdj = OdmObjFactory.createTapAdjustmentXmlType(); branchRec.setTapAdjustment(tapAdj); if(tapAdjSide==1){ tapAdj.setTapAdjOnFromSide(true); if(max>=2*fromTurnRatedV){ max=max/100; } max=max/fromTurnRatedV; if(min>=2*fromTurnRatedV){ min=min/100; } min=min/fromTurnRatedV; } else{ tapAdj.setTapAdjOnFromSide(false); if(max>=2*toTurnRatedV){ max=max/100; } max=max/toTurnRatedV; if(min>=2*toTurnRatedV){ min=min/100; } min=min/toTurnRatedV; } // save result to two digits after . NumberFormat ddf1=NumberFormat.getNumberInstance() ; ddf1.setMaximumFractionDigits(2); max= new Double(ddf1.format(max)).doubleValue() ; min= new Double(ddf1.format(min)).doubleValue() ; if(tapAdjSide==2){ tapAdj.setTapAdjOnFromSide(false); controlBusId=toBus; }else{ tapAdj.setTapAdjOnFromSide(true); controlBusId=fromBus; } tapAdj.setTapLimit(BaseDataSetter.createTapLimit(max, min)); tapAdj.setTapAdjStepSize(stepSize); if (adjustType==tapVoltageAdjustment ){// voltage control VoltageAdjustmentDataXmlType voltTapAdj = OdmObjFactory.createVoltageAdjustmentDataXmlType(); tapAdj.setVoltageAdjData(voltTapAdj); try { voltTapAdj.setAdjVoltageBus(parser.createBusRef(controlBusId)); } catch (Exception e) { ODMLogger.getLogger().severe("Xfr control bus not defined properly, " + e.toString()); } voltTapAdj.setAdjBusLocation(adjBus == toBus ? TapAdjustBusLocationEnumType.NEAR_TO_BUS : TapAdjustBusLocationEnumType.NEAR_FROM_BUS); voltTapAdj.setMode(AdjustmentModeEnumType.RANGE_ADJUSTMENT); BaseDataSetter.setLimit(voltTapAdj.getRange(), maxVoltPQ, minVoltPQ); } else if (adjustType==tapVarAdjustment) {// var control MvarFlowAdjustmentDataXmlType mvarTapAdj = OdmObjFactory.createMvarFlowAdjustmentDataXmlType(); tapAdj.setMvarFlowAdjData(mvarTapAdj); BaseDataSetter.setLimit(mvarTapAdj.getRange(), maxVoltPQ, minVoltPQ); mvarTapAdj.setMode(AdjustmentModeEnumType.RANGE_ADJUSTMENT); mvarTapAdj.setMvarMeasuredOnFormSide(true); } } else if(dataType==angleAdjustment){ PSXfrBranchXmlType psXfrBranch = (PSXfrBranchXmlType)branchRec; AngleAdjustmentXmlType angAdj = OdmObjFactory.createAngleAdjustmentXmlType(); psXfrBranch.setAngleAdjustment(angAdj); angAdj.setAngleLimit(OdmObjFactory.createAngleLimitXmlType()); BaseDataSetter.setLimit(angAdj.getAngleLimit(), maxVoltPQ, minVoltPQ); BaseDataSetter.setLimit(angAdj.getRange(), maxVoltPQ, minVoltPQ); angAdj.setMode(AdjustmentModeEnumType.RANGE_ADJUSTMENT); angAdj.setDesiredMeasuredOnFromSide(true); } } /* T yn DD1G 22.0 DD50 525. 720..000270.0202 22.0 536. */ private static String[] getXformerDataFields(final String str) { final String[] strAry = new String[20]; try{ strAry[0] = ODMModelStringUtil.getStringReturnEmptyString(str,1, 2); strAry[1] = ODMModelStringUtil.getStringReturnEmptyString(str,3, 3).trim(); strAry[2] = ODMModelStringUtil.getStringReturnEmptyString(str,4, 6).trim(); // strAry[3] = ModelStringUtil.getStringReturnEmptyString(str,7, 14).trim(); // strAry[4] = ModelStringUtil.getStringReturnEmptyString(str,15, 18).trim(); // strAry[5] = ModelStringUtil.getStringReturnEmptyString(str,19, 19).trim(); // strAry[6] = ModelStringUtil.getStringReturnEmptyString(str,20, 27).trim(); //----to process the Chinese characters in the fromBus name, if any. String tem=ODMModelStringUtil.getStringReturnEmptyString(str,7, 14).trim(); int chnCharNum1=ODMModelStringUtil.getChineseCharNum(tem); // System.out.println("chnCharNum1:"+chnCharNum1); //from bus name strAry[3] = ODMModelStringUtil.getStringReturnEmptyString(str,7, 14-chnCharNum1).trim(); //from bus basekV strAry[4] = ODMModelStringUtil.getStringReturnEmptyString(str,15-chnCharNum1, 18-chnCharNum1).trim(); //meter strAry[5] = ODMModelStringUtil.getStringReturnEmptyString(str,19-chnCharNum1, 19-chnCharNum1).trim(); //---to process the Chinese characters in the toBus name, if any. tem=ODMModelStringUtil.getStringReturnEmptyString(str,20-chnCharNum1, 27-chnCharNum1).trim(); int chnCharNum2=ODMModelStringUtil.getChineseCharNum(tem); // System.out.println("chnCharNum2:"+chnCharNum2); //to bus name strAry[6] = ODMModelStringUtil.getStringReturnEmptyString(str,20-chnCharNum1, 27-chnCharNum1-chnCharNum2).trim(); //--- replace all the Chinese Characters, since they are not used in the following processing. String str2=ODMModelStringUtil.replaceChineseChar(str); strAry[7] = ODMModelStringUtil.getStringReturnEmptyString(str2,28, 31).trim(); strAry[8] = ODMModelStringUtil.getStringReturnEmptyString(str2,32, 32).trim(); strAry[9] = ODMModelStringUtil.getStringReturnEmptyString(str2,33, 33).trim(); strAry[10] = ODMModelStringUtil.getStringReturnEmptyString(str2,34, 37).trim(); strAry[11] = ODMModelStringUtil.getStringReturnEmptyString(str2,38, 38).trim(); strAry[12] = ODMModelStringUtil.getStringReturnEmptyString(str2,39, 44).trim(); strAry[13] = ODMModelStringUtil.getStringReturnEmptyString(str2,45, 50).trim(); strAry[14] = ODMModelStringUtil.getStringReturnEmptyString(str2,51, 56).trim(); strAry[15] = ODMModelStringUtil.getStringReturnEmptyString(str2,57, 62).trim(); strAry[16] = ODMModelStringUtil.getStringReturnEmptyString(str2,63, 67).trim();//// tap of the fromBus /* T yn DD1G 22.0 DD50 525. 720..000270.0202 22.0 536. */ // tap of the toBus if (str2.length() >= 68){ if(str2.length() <= 72) strAry[17] = ODMModelStringUtil.getStringReturnEmptyString(str2,68, str2.length()).trim(); else { strAry[17]= ODMModelStringUtil.getStringReturnEmptyString(str2,68, 72).trim(); } } if (str2.length() > 78) strAry[18] = ODMModelStringUtil.getStringReturnEmptyString(str2,74, 77).trim();// str2.substring(74, 77).trim(); if (str2.length() > 81) strAry[19] =ODMModelStringUtil.getStringReturnEmptyString(str2,77, 80).trim();// str2.substring(77, 80).trim(); }catch(Exception e){ ODMLogger.getLogger().severe(e.toString() + "\n" + str); e.printStackTrace(); } return strAry; } private static String[] getXfrAdjustDataFields(final String str) { final String[] strAry = new String[15]; try{ // type strAry[0] = ODMModelStringUtil.getStringReturnEmptyString(str,1, 2).trim(); strAry[1] = ODMModelStringUtil.getStringReturnEmptyString(str,3, 3).trim(); strAry[2] = ODMModelStringUtil.getStringReturnEmptyString(str,4, 6).trim(); // //from bus name // strAry[3] = ModelStringUtil.getStringReturnEmptyString(str,7, 14).trim(); // // rated v // strAry[4] = ModelStringUtil.getStringReturnEmptyString(str,15, 18).trim(); // // point of metering interface exchange power // strAry[5] = ModelStringUtil.getStringReturnEmptyString(str,19, 19).trim(); // //to bus name // strAry[6] = ModelStringUtil.getStringReturnEmptyString(str,20, 27).trim(); //----to process the Chinese characters in the fromBus name, if any. String tem=ODMModelStringUtil.getStringReturnEmptyString(str,7, 14).trim(); int chnCharNum1=ODMModelStringUtil.getChineseCharNum(tem); //from bus name strAry[3] = ODMModelStringUtil.getStringReturnEmptyString(str,7, 14-chnCharNum1).trim(); //from bus basekV strAry[4] = ODMModelStringUtil.getStringReturnEmptyString(str,15-chnCharNum1, 18-chnCharNum1).trim(); //meter strAry[5] = ODMModelStringUtil.getStringReturnEmptyString(str,19-chnCharNum1, 19-chnCharNum1).trim(); //---to process the Chinese characters in the toBus name, if any. tem=ODMModelStringUtil.getStringReturnEmptyString(str,20-chnCharNum1, 27-chnCharNum1).trim(); int chnCharNum2=ODMModelStringUtil.getChineseCharNum(tem); //to bus name strAry[6] = ODMModelStringUtil.getStringReturnEmptyString(str,20-chnCharNum1, 27-chnCharNum1-chnCharNum2).trim(); //--- replace all the Chinese Characters, since they are not used in the following processing. String str2=ODMModelStringUtil.replaceChineseChar(str); // to rated v strAry[7] = ODMModelStringUtil.getStringReturnEmptyString(str2,28, 31).trim(); // controlled bus name and rated v strAry[8] = ODMModelStringUtil.getStringReturnEmptyString(str2,34, 41).trim(); strAry[9] = ODMModelStringUtil.getStringReturnEmptyString(str2,42, 45).trim(); //for R RV RQ RN //max tap strAry[10] = ODMModelStringUtil.getStringReturnEmptyString(str2,46, 50).trim(); // min tap strAry[11] = ODMModelStringUtil.getStringReturnEmptyString(str2,51, 55).trim(); // total tap strAry[12] = ODMModelStringUtil.getStringReturnEmptyString(str2,56, 57).trim(); strAry[13] = ODMModelStringUtil.getStringReturnEmptyString(str2,58, 62).trim(); strAry[14] = ODMModelStringUtil.getStringReturnEmptyString(str2,63, 67).trim(); }catch(Exception e){ ODMLogger.getLogger().severe(e.toString()); } return strAry; } }