📄 odm2psat
字号:
#!/usr/bin/perl -w# ODM2PSAT converts ODM data file into PSAT data file## ODM2PSAT <OPTIONS> FILEINPUT <FILEOUTPUT>## Author: Federico Milano# Date: 29-Feb-2008# Version: 1.0.0# # E-mail: Federico.Milano@uclm.es#use strict;use XML::Simple;use Data::Dumper;# -----------------------------------------------------------------------# variable declaration# -----------------------------------------------------------------------my $xml = new XML::Simple;my $nargin = 0;my $verbose = 0;my $helpmsg = 0;my ($i,$h,$j);my $nbus = -1;my $nsw = -1;my $npv = -1;my $npq = -1;my $npqgen = -1;my $nsh = -1;my $narea = -1;my $nzone = -1;my $nline = -1;my $pbas = 100;my $fbas = 60;my ($data,$temp,$gen,$load,$shunt,$area,%nvpair);my $apptype = "Transmission";my $base;my $format;my $type = "";my $pos = 0;my ($title1,$title2,$title3,$title4);my $year = "n.d.";my $originator = "unknown";my $season = "";my $date = "unknown";my $id = "Generic ODM case";my (%busid,%lineid);my (@buskv,@busname,@busvol,@area,@zone,@busang,@vmax,@vmin);my (@pgen,@qgen,@ppqgen,@qpqgen,@psw,@qsw,@qswmax,@qswmin,@qmin,@qmax);my (@swidx,@pvidx,@pqidx,@pqgenidx,@pload,@qload);my (@shidx,@shsb,@shvb,@pcap,@qcap);my (@busfr,@busto,@rline,@xline,@bshunt,@gshunt,@tap,@phs,@linevb,@linesb,@kt,@imax);my (@areanum,@areaslack,@areaexp,@areatol,@areaname);my (@zonenum,@zonename);# -----------------------------------------------------------------------# check inputs# -----------------------------------------------------------------------$nargin = @ARGV;$nargin || die "Error: No input data file.\n";# -----------------------------------------------------------------------# check options# -----------------------------------------------------------------------while ($ARGV[0] =~ /^-/) { if ($ARGV[0] =~ /v/) {$verbose = 1;} if ($ARGV[0] =~ /h/) {$helpmsg = 1;} shift(@ARGV); $nargin--; if ($nargin == 0) { last; }}$title1 = 'Generic ODM data format '.$ARGV[0];# -----------------------------------------------------------------------# help (if requested)# -----------------------------------------------------------------------if ($helpmsg) { print "\nODM2PSAT converts ODM data files into PSAT data files.\n\n"; print "odm2psat [<options>] fileinput [<fileoutput>]\n"; print " -v verbose\n"; print " -h print this help and exit\n\n"; print "Requirements: Perl 5.8 and the module XML::Simple\n\n"; print "Author: Federico Milano\n"; print "Date: 29-Feb-2008\n"; print "Version: 1.0.0\n\n"; print "E-mail: Federico.Milano\@uclm.es\n"; die "\n";}# -----------------------------------------------------------------------# define output file name (if necessary)# -----------------------------------------------------------------------if ($nargin == 1) { $ARGV[1] = $ARGV[0]; $ARGV[1] =~ s/^d*_*/d_/; $ARGV[1] =~ s/[^\w\.]/_/g; $ARGV[1] =~ s/\..+$/.m/;} elsif ($nargin == 0) { die "Error: Input file name is missing.\n";}# -----------------------------------------------------------------------# parse input data file# -----------------------------------------------------------------------print "Parsing ODM data file \"$ARGV[0]\"...\n";# Read data file and parse XML input into a Perl structure$data = $xml->XMLin($ARGV[0], keyattr => [], forcearray => [ qw (pss:interchange pss:lossZone) ]);## uncomment to write down the perl data structure#open OUT, ">dumper.txt" || die "cannot open dumper.txt: $!\n";#print OUT Dumper($data);#close(OUT);print "ODM data version: " . $data->{"pss:schemaVersion"} . "\n";$apptype = $data->{"pss:networkCategory"};print "Network category: " . $apptype . "\n";print "Analysis category: " . $data->{"pss:analysisCategory"} . "\n";if (defined($data->{"pss:baseCase"}->{"pss:baseKva"})) { if ($data->{"pss:baseCase"}->{"pss:baseKvaUnit"} eq "MVA") { $pbas = $data->{"pss:baseCase"}->{"pss:baseKva"}; } elsif ($data->{"pss:baseCase"}->{"pss:baseKvaUnit"} eq "KVA") { $pbas = $data->{"pss:baseCase"}->{"pss:baseKva"}/1000; }}if (defined($data->{"pss:baseCase"}->{"pss:basePower"})) { $temp = $data->{"pss:baseCase"}->{"pss:basePower"}; if ($temp->{"pss:unit"} eq "MVA") { $pbas = $temp->{"pss:power"}; } elsif ($temp->{"pss:unit"} eq "KVA") { $pbas = $temp->{"pss:power"}/1000; }}# -----------------------------------------------------------------------# bus data# -----------------------------------------------------------------------for $temp ( @{$data->{"pss:baseCase"}->{"pss:busList"}->{"pss:bus"}} ) { $nbus++; $busid{$temp->{"pss:id"}} = $nbus; # default values $busname[$nbus] = "Bus " . $temp->{"pss:id"}; $buskv[$nbus] = 1; $busvol[$nbus] = 1; $busang[$nbus] = 0; $vmax[$nbus] = 1.1; $vmin[$nbus] = 0.9; $area[$nbus] = 1; $zone[$nbus] = 1; # bus name if (defined($temp->{"pss:name"})) { $busname[$nbus] = $temp->{"pss:name"}; } # voltage rate (kV) if (defined($temp->{"pss:baseVoltage"})) { if (defined($temp->{"pss:baseVoltageUnit"})) { if ($temp->{"pss:baseVoltageUnit"} eq "KV") { $buskv[$nbus] = $temp->{"pss:baseVoltage"}; } elsif ($temp->{"pss:baseVoltageUnit"} eq "VOLT") { $buskv[$nbus] = $temp->{"pss:baseVoltage"}/1000; } } elsif (defined($temp->{"pss:baseVoltage"}->{"pss:unit"})) { if ($temp->{"pss:baseVoltage"}->{"pss:unit"} eq "KV") { $buskv[$nbus] = $temp->{"pss:baseVoltage"}->{"pss:voltage"}; } elsif ($temp->{"pss:baseVoltage"}->{"pss:unit"} eq "VOLT") { $buskv[$nbus] = $temp->{"pss:baseVoltage"}->{"pss:voltage"}/1000; } } } # area number if (defined($temp->{"pss:area"})) { $area[$nbus] = $temp->{"pss:area"}; } # zone number if (defined($temp->{"pss:zone"})) { $zone[$nbus] = $temp->{"pss:zone"}; } # voltage magnitude (p.u.) if (defined($temp->{"pss:loadflowBusData"}->{"pss:voltage"})) { $h = $temp->{"pss:loadflowBusData"}->{"pss:voltage"}; if ($h->{"pss:unit"} eq "PU") { $busvol[$nbus] = $h->{"pss:voltage"}; } elsif ($h->{"pss:unit"} eq "KV") { $busvol[$nbus] = $h->{"pss:voltage"}/$buskv[$nbus]; } elsif ($h->{"pss:unit"} eq "VOLT") { $busvol[$nbus] = $h->{"pss:voltage"}/$buskv[$nbus]/1000; } } # voltage angle (rad) if (defined($temp->{"pss:loadflowBusData"}->{"pss:angle"})) { $h = $temp->{"pss:loadflowBusData"}->{"pss:angle"}; if ($h->{"pss:unit"} eq "DEG") { $busang[$nbus] = 0.017453292519943*$h->{"pss:angle"}; } elsif ($h->{"pss:unit"} eq "RAD") { $busang[$nbus] = $h->{"pss:angle"}; } } # PV and slack data if (defined($temp->{"pss:loadflowBusData"}->{"pss:genData"})) { $gen = $temp->{"pss:loadflowBusData"}->{"pss:genData"}; if ($gen->{"pss:code"} eq "PV") { $pvidx[++$npv] = $nbus; if ($gen->{"pss:gen"}->{"pss:unit"} eq "MVA") { $pgen[$npv] = $gen->{"pss:gen"}->{"pss:p"}/$pbas; $qgen[$npv] = $gen->{"pss:gen"}->{"pss:q"}/$pbas; } elsif ($gen->{"pss:gen"}->{"pss:unit"} eq "PU") { $pgen[$npv] = $gen->{"pss:gen"}->{"pss:p"}; $qgen[$npv] = $gen->{"pss:gen"}->{"pss:q"}; } if (defined($gen->{"pss:qGenLimit"})) { $h = $gen->{"pss:qGenLimit"}; if ($h->{"pss:qLimitUnit"} eq "MVAR") { $qmax[$npv] = $h->{"pss:qLimit"}->{"pss:max"}/$pbas; $qmin[$npv] = $h->{"pss:qLimit"}->{"pss:min"}/$pbas; } elsif ($h->{"pss:qLimitUnit"} eq "PU") { $qmax[$npv] = $h->{"pss:qLimit"}->{"pss:max"}; $qmin[$npv] = $h->{"pss:qLimit"}->{"pss:min"}; } } else { $qmax[$npv] = 0; $qmin[$npv] = 0; } } elsif ($gen->{"pss:code"} eq "PQ") { $pqgenidx[++$npqgen] = $nbus; if ($gen->{"pss:gen"}->{"pss:unit"} eq "MVA") { $ppqgen[$npqgen] = $gen->{"pss:gen"}->{"pss:p"}/$pbas; $qpqgen[$npqgen] = $gen->{"pss:gen"}->{"pss:q"}/$pbas; } elsif ($gen->{"pss:gen"}->{"pss:unit"} eq "PU") { $ppqgen[$npqgen] = $gen->{"pss:gen"}->{"pss:p"}; $qpqgen[$npqgen] = $gen->{"pss:gen"}->{"pss:q"}; } } elsif ($gen->{"pss:code"} eq "SWING") { $swidx[++$nsw] = $nbus; if (defined($gen->{"pss:gen"})) { if ($gen->{"pss:gen"}->{"pss:unit"} eq "MVA") { $psw[$nsw] = $gen->{"pss:gen"}->{"pss:p"}/$pbas; $qsw[$nsw] = $gen->{"pss:gen"}->{"pss:q"}/$pbas; } elsif ($gen->{"pss:gen"}->{"pss:unit"} eq "PU") { $psw[$nsw] = $gen->{"pss:gen"}->{"pss:p"}; $qsw[$nsw] = $gen->{"pss:gen"}->{"pss:q"}; } } else { $psw[$nsw] = 0; $qsw[$nsw] = 0; } if (defined($gen->{"pss:gGenLimit"})) { if ($gen->{"pss:qGenLimit"}->{"pss:qLimitUnit"} eq "MVAR") { $qswmax[$nsw] = $gen->{"pss:qGenLimit"}->{"pss:qLimit"}->{"pss:max"}/$pbas; $qswmin[$nsw] = $gen->{"pss:qGenLimit"}->{"pss:qLimit"}->{"pss:min"}/$pbas; } elsif ($gen->{"pss:qGenLimit"}->{"pss:qLimitUnit"} eq "PU") { $qswmax[$nsw] = $gen->{"pss:qGenLimit"}->{"pss:qLimit"}->{"pss:max"}; $qswmin[$nsw] = $gen->{"pss:qGenLimit"}->{"pss:qLimit"}->{"pss:min"}; } } else { $qswmax[$nsw] = 0; $qswmin[$nsw] = 0; } } } # load data if (defined($temp->{"pss:loadflowBusData"}->{"pss:loadData"})) { $load = $temp->{"pss:loadflowBusData"}->{"pss:loadData"}; if ($load->{"pss:code"} eq "CONST_P") { $pqidx[++$npq] = $nbus; if ($load->{"pss:load"}->{"pss:unit"} eq "MVA") { $pload[$npq] = $load->{"pss:load"}->{"pss:p"}/$pbas; $qload[$npq] = $load->{"pss:load"}->{"pss:q"}/$pbas; } elsif ($load->{"pss:load"}->{"pss:unit"} eq "PU") { $pload[$npq] = $load->{"pss:load"}->{"pss:p"}; $qload[$npq] = $load->{"pss:load"}->{"pss:q"}; } } } # shunt admittance data if (defined($temp->{"pss:loadflowBusData"}->{"pss:shuntY"})) { $shunt = $temp->{"pss:loadflowBusData"}->{"pss:shuntY"}; addshunt($shunt,$nbus,$pbas,$buskv[$nbus]); }}# -----------------------------------------------------------------------# line data# -----------------------------------------------------------------------for $temp ( @{$data->{"pss:baseCase"}->{"pss:branchList"}->{"pss:branch"}} ) { $nline++; $busfr[$nline] = $busid{$temp->{"pss:fromBus"}->{"pss:idRef"}}; $busto[$nline] = $busid{$temp->{"pss:toBus"}->{"pss:idRef"}}; if (defined($temp->{"pss:id"})) { $lineid{$temp->{"pss:id"}} = $nline; } else { $lineid{$busfr[$nline] . $busto[$nline] . $temp->{"pss:circuitId"}} = $nline; } # default values $linesb[$nline] = $pbas; $linevb[$nline] = $buskv[$busfr[$nline]]; $rline[$nline] = 0; $xline[$nline] = 0.001; $bshunt[$nline] = 0; $gshunt[$nline] = 0; $tap[$nline] = 0; $phs[$nline] = 0; $kt[$nline] = 0; $imax[$nline] = 0; if ($temp->{"pss:loadflowBranchData"}->{"pss:code"} eq "Line") { $h = $temp->{"pss:loadflowBranchData"}->{"pss:lineData"}; ratings($h); impedance($h); lineshunt($h); } elsif ($temp->{"pss:loadflowBranchData"}->{"pss:code"} eq "Transformer") { $kt[$nline] = $linevb[$nline]/$buskv[$busto[$nline]]; $h = $temp->{"pss:loadflowBranchData"}->{"pss:xformerData"}; ratings($h); impedance($h); lineshunt($h); tapratio($h); } elsif ($temp->{"pss:loadflowBranchData"}->{"pss:code"} eq "PhaseShiftXformer") { $kt[$nline] = $linevb[$nline]/$buskv[$busto[$nline]]; $h = $temp->{"pss:loadflowBranchData"}->{"pss:phaseShiftXfrData"}; ratings($h); impedance($h); tapratio($h); lineshunt($h); phaseshifting($h); } else { # other series component } # rating limits if (defined($temp->{"pss:loadflowBranchData"}->{"pss:ratingLimit"})) { $h = $temp->{"pss:loadflowBranchData"}->{"pss:ratingLimit"}; if (defined($h->{"pss:currentRating"})) { if ($h->{"pss:currentRatingUnit"} eq "KA") { $base = $linesb[$nline]/$linevb[$nline]/1.732050807568877; $imax[$nline] = $h->{"pss:currentRating"}/$base; } elsif ($h->{"pss:currentRatingUnit"} eq "AMP") { $base = $linesb[$nline]/$linevb[$nline]/0.001732050807569; $imax[$nline] = $h->{"pss:currentRating"}/$base; } elsif ($h->{"pss:currentRatingUnit"} eq "PU") { $imax[$nline] = $h->{"pss:currentRating"}; } } }}# -----------------------------------------------------------------------# area data# -----------------------------------------------------------------------for $temp ( @{$data->{"pss:baseCase"}->{"pss:interchangeList"}->{"pss:interchange"}} ) { unless (defined($temp->{"pss:ieeeCDFInterchange"})) { next }; $area = $temp->{"pss:ieeeCDFInterchange"};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -