/* * @(#)BPALineBranchRecord.java * * Copyright (C) 2006-2008 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 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.BaseJaxbHelper; import org.ieee.odm.model.base.ODMModelStringUtil; import org.ieee.odm.schema.BranchXmlType; import org.ieee.odm.schema.BusXmlType; import org.ieee.odm.schema.CurrentUnitType; import org.ieee.odm.schema.LengthUnitType; import org.ieee.odm.schema.LineBranchXmlType; import org.ieee.odm.schema.LoadflowBusXmlType; import org.ieee.odm.schema.NetworkXmlType; import org.ieee.odm.schema.YUnitType; import org.ieee.odm.schema.ZUnitType; public class BPALineBranchRecord { public void processBranchData(final String str, BaseAclfModelParser<? extends NetworkXmlType> parser) throws ODMException { final double baseMVA = parser.getNet().getBasePower().getValue(); // symmetry line data if(str.startsWith("L ")){ // parse the branch input line str final String[] strAry = getBranchDataFields(str); // symetry branch final String branchType=strAry[0]; 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); // set cirId, if not specified, set to 1 //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]; } LineBranchXmlType branchRec = null; try { branchRec = (LineBranchXmlType) parser.createLineBranch(fid, tid, cirId); } catch (Exception e) { ODMLogger.getLogger().severe("branch data error, " + e.toString() + " " + fname + "->" + tname + "_" + cirId); return; } // TODO owner code double fVol=0.0; double tVol=0.0; if(!strAry[4].equals("")){ fVol= new Double(strAry[4]).doubleValue(); } if(!strAry[7].equals("")){ tVol= new Double(strAry[4]).doubleValue(); } branchRec.setId(ODMModelStringUtil.formBranchId(fid, tid, cirId)); String multiSectionId=""; if(!strAry[9].equals("")){ multiSectionId = strAry[9]; //set multiSection data if necessary // TODO } //if currentRating!=0.0,set rated current double currentRating=0.0; if(!strAry[10].equals("")){ currentRating = new Double(strAry[10]).doubleValue(); AclfDataSetter.setBranchRatingLimitData(branchRec.getRatingLimit(), currentRating, CurrentUnitType.AMP); } /* * Set branch r,x,b * ================ */ double rpu=0.0, xpu=0.0001, halfGpu=0.0, halfBpu=0.0; if(!strAry[12].equals("")){ rpu = new Double(strAry[12]).doubleValue(); /* it is due to the data storage fomat, for example , when it stores 000123, it is ,in fact, 1.23E-3 fix digital points by default five */ if(Math.abs(rpu)>=1.0&&!strAry[12].contains(".")){ rpu=rpu/100000; } rpu=ODMModelStringUtil.getNumberFormat(rpu); if(Math.abs(rpu)>1) ODMLogger.getLogger().warning("Line#"+fname+"-to-"+tname+",the resistance now is" +rpu+" ,seems to be out of normal range[0~1.0]pu, please check!"); } if(!strAry[13].equals("")){ xpu = new Double(strAry[13]).doubleValue(); if(Math.abs(xpu)>=1.0&&!strAry[13].contains(".")){ xpu=xpu/100000; } xpu=ODMModelStringUtil.getNumberFormat(xpu); if(Math.abs(xpu)>1||Math.abs(xpu)<1E-5) ODMLogger.getLogger().warning("Line#"+fname+"-to-"+tname+",the reactance now is" +xpu+" ,seems to be out of normal range[1E-5~1]pu, please check!"); } if(!strAry[14].equals("")){ halfGpu = new Double(strAry[14]).doubleValue(); if(Math.abs(halfGpu)>=1.0&&!strAry[14].contains(".")){ halfGpu=halfGpu/100000; } if(Math.abs(halfGpu)>1) ODMLogger.getLogger().warning("Line#"+fname+"-to-"+tname+",the line charging G/2 now is" +halfGpu+" ,seems to be out of normal range[0,1]pu, please check!"); } if(!strAry[15].equals("")){ halfBpu = new Double(strAry[15]).doubleValue(); if(Math.abs(halfBpu)>=1.0&&!strAry[15].contains(".")){ halfBpu=halfBpu/100000; } if(Math.abs(halfBpu)>5){ ODMLogger.getLogger().warning("Line#"+fname+"-to-"+tname+",the line charging B/2 now is" +halfBpu+" ,seems to be out of normal range[-5,+5](pu), please check!"); } } if(rpu!=0.0||xpu!=0.0||halfGpu!=0.0||halfBpu!=0.0){ AclfDataSetter.setLineData(branchRec, rpu, xpu, ZUnitType.PU, 2*halfGpu, 2*halfBpu, YUnitType.PU);; } //branch length double length=0.0; if(!strAry[16].equals("")){ AclfDataSetter.setLineLength(branchRec.getLineInfo(), length, LengthUnitType.MILE); } // if there is a description, set String desc= ""; if(!strAry[17].equals("")){ desc= strAry[17]; BaseJaxbHelper.addNVPair(branchRec, "branch description", desc); } } /** * transform the shunt reactor at the end(s) of a branch to a shuntY, * and add it to the corresponding bus of the branch. */ else if(str.startsWith("L+")){ final String[] strAry = getBranchDataFields(str); final String fname = strAry[3]; final String tname = strAry[6]; final String fid = BPABusRecord.getBusId(fname); final String tid = BPABusRecord.getBusId(tname); if(!strAry[9].equals("")){ final double fromShuntVar=new Double(strAry[9]).doubleValue(); double fShuntVar=ODMModelStringUtil.getNumberFormat(fromShuntVar/baseMVA); // x(pu)=Var/baseMVA if(fShuntVar!=0.0){ LoadflowBusXmlType fromBus= (LoadflowBusXmlType)parser.getBus(fid); /* * It should be negative considering that positive sign means capacitive shunt var * */ AclfDataSetter.addBusShuntVar(fromBus, -fShuntVar, YUnitType.PU); } } if(!strAry[10].equals("")){ final double toShuntVar=new Double(strAry[10]).doubleValue(); double tShuntVar=ODMModelStringUtil.getNumberFormat(toShuntVar/baseMVA); if(tShuntVar!=0.0){ LoadflowBusXmlType toBus= (LoadflowBusXmlType)parser.getBus(tid); AclfDataSetter.addBusShuntVar(toBus, -tShuntVar, YUnitType.PU); } } } else{ throw new ODMException("Only type L or L+ branch is allowed"); } } private static String[] getBranchDataFields(final String str) { final String[] strAry = new String[20]; // line type strAry[0] = ODMModelStringUtil.getStringReturnEmptyString(str,1, 2).trim(); // change strAry[1] = ODMModelStringUtil.getStringReturnEmptyString(str,3, 3).trim(); //ower strAry[2] = ODMModelStringUtil.getStringReturnEmptyString(str,4, 6).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 bus baseKV strAry[7] = ODMModelStringUtil.getStringReturnEmptyString(str2,28, 31).trim(); // circuit ID strAry[8] = ODMModelStringUtil.getStringReturnEmptyString(str2,32, 32).trim(); if(strAry[0].equals("L")){ // no use strAry[9] = ODMModelStringUtil.getStringReturnEmptyString(str2,33, 33).trim(); // current rating(ampacity) strAry[10] = ODMModelStringUtil.getStringReturnEmptyString(str2,34, 37).trim(); // no use strAry[11] = ODMModelStringUtil.getStringReturnEmptyString(str2,38, 38).trim(); // R strAry[12] = ODMModelStringUtil.getStringReturnEmptyString(str2,39, 44).trim(); // X strAry[13] = ODMModelStringUtil.getStringReturnEmptyString(str2,45, 50).trim(); //G/2 strAry[14] = ODMModelStringUtil.getStringReturnEmptyString(str2,51, 56).trim(); //B/2 strAry[15] = ODMModelStringUtil.getStringReturnEmptyString(str2,57, 62).trim(); } else if(strAry[0].equals("L+")){ //processing Branch Shunt Var Data Fields if(str2.length()>38){// get the shunt Var at the fromBus side strAry[9] = ODMModelStringUtil.getStringReturnEmptyString(str2,34, 38).trim(); } else strAry[9] = ODMModelStringUtil.getStringReturnEmptyString(str2,34, str2.length()).trim(); // there is shunt Var at the toBus side if(str2.length()>48) strAry[10] = ODMModelStringUtil.getStringReturnEmptyString(str2,44, 48).trim(); else strAry[10] = ODMModelStringUtil.getStringReturnEmptyString(str2,44, str2.length()).trim(); } if(strAry[0].equals("L")){ //line length strAry[16] = ODMModelStringUtil.getStringReturnEmptyString(str2,63, 66).trim(); strAry[17] = ODMModelStringUtil.getStringReturnEmptyString(str2,67, 74).trim(); }else{ strAry[16] = ODMModelStringUtil.getStringReturnEmptyString(str2,63, 67).trim(); strAry[17] = ODMModelStringUtil.getStringReturnEmptyString(str2,69, 74).trim(); } // date of first put into use strAry[18] = ODMModelStringUtil.getStringReturnEmptyString(str2,75, 77).trim(); // date of out of service strAry[19] = ODMModelStringUtil.getStringReturnEmptyString(str2,78, 80).trim(); // return strAry; } // private static String[] getBranchShuntVarDataFields(String str) { // final String[] strAry = new String[8]; // // Branch record type // strAry[0] = ModelStringUtil.getStringReturnEmptyString(str,1, 2).trim(); // // from bus name and basekV // strAry[1] = ModelStringUtil.getStringReturnEmptyString(str,7, 14).trim(); // strAry[2] = ModelStringUtil.getStringReturnEmptyString(str,15, 18).trim(); // // to bus name and basekV // strAry[3] = ModelStringUtil.getStringReturnEmptyString(str,20, 27).trim(); // strAry[4] = ModelStringUtil.getStringReturnEmptyString(str,28, 31).trim(); // strAry[5] = ModelStringUtil.getStringReturnEmptyString(str,32, 32).trim(); // // shunt Var at the fromBus side // if(str.length()>38) // strAry[6] = ModelStringUtil.getStringReturnEmptyString(str,34, 38).trim(); // else // strAry[6] = ModelStringUtil.getStringReturnEmptyString(str,34, str.length()).trim(); // // shunt Var at the toBus side // if(str.length()>44){ // strAry[7] = ModelStringUtil.getStringReturnEmptyString(str,44, str.length()).trim(); // } // return strAry; // } } //else if(str.startsWith("E")){ //final String[] strAry = getBranchDataFields(str,adapter); //// symetry branch //final String branchType=strAry[0]; // //final String modCode =strAry[1]; //final String owner=strAry[2]; // //final String fid = strAry[3]; //final String tid = strAry[6]; //ODMLogger.getLogger().fine("Branch data loaded, from-Bus, to-Bus: " + fid + ", " + tid); // //if(!fid.equals("")){ // branchRec.addNewFromBus().setIdRef(fid); //} //if(!tid.equals("")){ // branchRec.addNewToBus().setIdRef(tid); //} // //double fVol=0.0; //double tVol=0.0; //if(!strAry[4].equals("")){ // fVol= new Double(strAry[4]).doubleValue(); //} //if(!strAry[7].equals("")){ // tVol= new Double(strAry[4]).doubleValue(); //} // measure location for power interchange, 1--from side, 2- to side //set transfer power measured location in tie line data //int measureLocation=0; //if(!strAry[5].equals("")){ // measureLocation= new Integer(strAry[5]).intValue(); // try{ // if(measureLocation==1){ // PSSNetworkXmlType.TieLineList.Tieline tieLine=parser.addNewBaseCaseTieline(); // // // set tieline data // tieLine.addNewMeteredBus().setName(fid); // tieLine.addNewNonMeteredBus().setName(tid); // // BusRecordXmlType busRecFrom=XBeanParserHelper.findBusRecord(fid, baseCaseNet); // busRecFrom.getZoneNumber(); // NetAreaXmlType areaFrom=XBeanParserHelper. // getAreaRecordByZone(busRecFrom.getZoneNumber(), baseCaseNet); // tieLine.setMeteredArea(areaFrom.getName()); // // BusRecordXmlType busRecTo=XBeanParserHelper.findBusRecord(tid, baseCaseNet); // busRecTo.getZoneNumber(); // NetAreaXmlType areaTo=XBeanParserHelper. // getAreaRecordByZone(busRecTo.getZoneNumber(), baseCaseNet); // tieLine.setNonMeteredArea(areaTo.getName()); // // to do: set area number // // }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(); // } // //} //// set cirId, if not specified, set to 1 //String cirId=""; //if(!strAry[8].equals("")){ // cirId = strAry[8]; // branchRec.setCircuitId(cirId); //} //else{ // branchRec.setCircuitId("1"); //} // //LoadflowBranchDataXmlType branchData = branchRec.addNewLoadflowData(); // //branchRec.setId(ModelStringUtil.formBranchId(fid, tid, cirId)); //branchData.setCode(LFBranchCodeEnumType.LINE); // //String multiSectionId=""; //if(!strAry[9].equals("")){ // multiSectionId = strAry[9]; // //set multiSection data if necessary //} // ////if currentRating!=0.0,set rated current //double currentRating=0.0; //if(!strAry[10].equals("")){ // currentRating = new Double(strAry[10]).doubleValue(); // XBeanDataSetter.setBranchRatingLimitData(branchData.addNewBranchRatingLimit(), // currentRating, CurrentUnitType.AMP); //} //double rpu=0.0, xpu=0.0001, G1pu=0.0, B1pu=0.0, G2pu=0.0, B2pu=0.0; //if(!strAry[12].equals("")){ // rpu = new Double(strAry[12]).doubleValue(); //} //if(!strAry[13].equals("")){ // xpu = new Double(strAry[13]).doubleValue(); //} //if(!strAry[14].equals("")){ // G1pu = new Double(strAry[14]).doubleValue(); //} //if(!strAry[15].equals("")){ // B1pu = new Double(strAry[15]).doubleValue(); //} //if(!strAry[16].equals("")){ // G2pu = new Double(strAry[16]).doubleValue(); //} //if(!strAry[17].equals("")){ // B2pu = new Double(strAry[17]).doubleValue(); //} //ZXmlType z= branchData.addNewZ(); //XBeanDataSetter.setZValue(z, rpu, xpu, ZUnitType.PU); //YXmlType y1 = branchData.addNewFromShuntY(); //YXmlType y2 = branchData.addNewToShuntY(); //XBeanDataSetter.setYData(y1, G1pu, B1pu, YUnitType.PU); //XBeanDataSetter.setYData(y2, G2pu, B2pu, YUnitType.PU); //}