1 e% V& h7 j0 `$ Q# K2 p1 {$ S1 S- Z0 l3 X
PSSE30提供了Python的API接口,使在PSSE中使用Python脚本语言成为了可能,这不仅使PSSE批量运行,同时可以根据你的Python代码,使处理功能更强大,更灵活。; i, W! }$ z* j; N
我没有找到很好的关于在PSSE中使用Pyhton的资料,我把我能找到的东西写在这里供初学者入门。9 g: t; j9 A/ m- l$ }
前面的一些资料能在使用说明书USERS.pdf的第12章找到,其他资料是通过API.pdf和IPLAN.pdf综合而来的,可以从中找到。# x0 }$ l( U5 K9 }
我发现使用Adobe的搜索功能非常有用,你可以根据一个关键词同时搜索在一个文件夹下面的所有的pdf文件,这样寻找某个函数的IPLAN和API的描述遍得很简单。IPLAN的描述一般在查找详细描述“某些传递数据的参数”的解释时非常有用。IPLAN函数的名称同API文档中Python的那些函数相同,只是后者是大写字母而已。- Q: J q. T8 l9 y2 X1 n& P
我使用的是30版本的PSSE,和2.3版的Pyhton,这篇文章的前提是你了解一些基本的Python,Mack Lutz和David Ascher写的《Learning Pyhon》非常不错。" B+ c) L( h) _2 U( z \5 Z Python : \8 x% e& x$ Q2 kPython.org homepage . [2 g4 c+ _! d& Z, L9 {0 SPSSE 7 D; d0 {) I( W6 ~2 r7 u% q9 lPower System Simulator for Engineering. 3 v4 o& M4 K9 [* e
5 w% l6 Z7 D, s! b 在PSSE中使用Python简介( s6 i' b2 ^$ N% V
PSSE说明文档说:根据你在PSSE中的操作可以生成Python代码。这花了我一段时间才理解,因为我是PSSE和Python的初学者。根据以下步骤,可以生成你的第一个python代码,用来进行潮流计算分析。前提是你有一个包含有网络信息的.raw文件,格式符合PSSE30要求。 0 `) T6 l- Z; u4 h! I$ L3 d1、7 B" e$ J/ {, c( e5 ]0 m/ ~ T, M
打开PSSE。# l, B* b) {( H* L9 H7 C; N
2、- ]- X6 M5 k; R7 N* f; m. ]! A7 A1 Q+ d
选择“I/O Control”中的“Start Recording”菜单,输入一个PSSE写入的文件名。PSSE会自动地添加.py后缀。) O9 y' O5 A0 c7 O/ K: L
3、7 h1 K: O* u- D- [' ?5 z9 f; N& a
使用“File”菜单中的“Open”按钮,读入网络信息。将文件类型设定为.raw告诉PSSE你在给他的是raw文件(不知道是原文傻还是我翻译的傻:’()) G! r7 _! f2 V. j9 v4 ~! [
4、 # k( h; y8 Q' @4 E6 b& F选择“Power Flow”中“Solution”,选择“Solve”,运行潮流计算。选择所需要的设置模式,点击“Solve”按钮。 3 _' L% u0 y6 w0 j" t. Y5、 3 [. X6 x/ O9 T选择“File”菜单中的“Save or Show”保存运算结果。选择“Power Flow Raw Data”选项卡,点击“Data File”单选按钮,并在旁边的文本框中输入文件名。点击OK按钮。3 ?$ H# K, \2 i) P9 R
使用你最喜欢的python浏览器查看生成的python代码。 1 X( z6 A/ c7 X8 `& q) J3 t
# File:"C:\Documents and Settings\jbo\MySensibleFolderName\pssetest.py", generated on TUE, FEB 08 2005 14:11 psspy.read(0,r"""C:\Documents and Settings\jbo\MySensibleFolderName\testCase_30EV30test.raw""") ( v% i: C! h/ f' y# ~psspy.fdns([0,0,0,1,1,0,99,0])3 X6 O" U: _$ Y* T$ X% w
psspy.rawd(0,1,[1,1,1,0,0,0],0,r"""C:\Documents and Settings\jbo\MySensibleFolderName\SOLVEDtestCase_30EV30test.raw""")
注意,所有的方法都是通过一个叫做psspy的对象调用的。这个对象包括所有可用的方法和对象。他们看起来只不过是通过一个列表来组织的。我还没有写任何接口对象来组织和调用psspy方法时,就是这么想的。(瞎翻译的)2 p, Y, P: h; T3 n/ S& |6 E2 W" ~. t
注意声称路径字符串的方法,这不是python提倡的格式,下面的写法更好: 0 M# o/ A# P5 G7 J2 |- Z) E
"C:\\Documents and Settings\\jbo\\MySensibleFolderName\\testCase_30EV30test.raw".
% v8 G E& ~, X; G Z怎样来运行python代码 % U# U# L/ w* M3 ^! l l, Q1 D# v我试过三种方式 9 N: {6 P9 L y6 V* s1、 2 |$ V5 U, O6 z$ v" C, ^在PSSE中打开命令输入窗口(command line input, CLI)任务。 6 I/ l& ?1 L% v( x1 a2、* M1 S& n7 A; I/ z2 i7 \9 ^0 Y3 O# X
在PSSE中选择“Run Automation File”按钮运行一个python文件。! C* }# Z) I& z4 S7 L! o+ W
3、 7 l, s/ U/ r4 \- [在PSSE30中python文件作为一个命令行变量。你可以指定图形界面只有在完成之后才出现。这可以为机器节省内存。在这种情况下,你可以指定仿真的母线数量。可以参照PSSE Users Manual中的PSSE Overview。 $ |! o3 c- `1 l; ]5 b1 K# C( u* w在PSSE中打开CLI8 t/ J" T# H$ M* Z( V
1、1 B- T. [% M; g
在“I/O Control”菜单中选择“Begin command line input session”。$ }+ _9 A- M0 M7 L2 s
2、$ @' n. C' {) S- l+ ?/ n
使用“Command Language”选择框将语言更改为python。 6 ?& @$ v, z4 c5 d0 Q3、 1 V" b5 v9 [$ ]& F+ `4 T/ J选择“RunAuto”按钮并选择一个python文件,PSSE会运行那个文件。 ) Z8 L' h" y. N f6 a注意python命令可以直接在控制台输入。控制台动作同编译python的交互式平台不同,它不自动显示调用方法所返回的结果。要想显示的话必须使用python的print命令,例如:print(psspy.aMethod(myParameters))。, {/ v- Y' v3 P) {+ G4 s+ y
一个重要的点是所有列出的方法都是psspy方法。所以使用要使用totbus方法返回母线数量时,输入CLI时不能使用ival=totbus(),而应该使用ival=psspy.totbus()。在CLI中使用print(ival)来显示ival。Python语法也可以使其简化,如:from psspy import * 。采用何种编程风格由用户决定。 3 g% t/ z" n2 M; P) T# S+ N 1 h& |. P- G6 F7 H 在IDLE编译平台测试python代码 " s& @0 w7 x8 k我花了让人崩溃的长时间来寻找下面这个加入到python路径的方法。6 v- b' ^4 z6 }: n
当你想将自己写的一个模块导入python,或者要把一个处在其他文件夹下的模块加入到python文件中去,那么下面的方法就大有用啦:3 }2 E6 X) c- |- y- m
1、 : a; I! @. m$ R. d创建一个扩展名为.pth的文件。我们起个很漂亮比尔盖茨又很喜欢的名字myconfig.pth。当你在使用记事本之类的编辑器时就要小心了,不要保存成myconfig.pth.txt哦。+ d% S: C& ` h* M3 d3 Z9 M' |, B
2、6 Q; [4 c- _8 t
把这个文件放到python根目录下面去,比如我的就是C:\Python23。 % r1 h g7 i& a/ l! v+ ]+ s) {$ r+ y& d3、 2 s9 Z! U3 |, p把每个你想加入PYTHONPATH的文件夹全路径,单独一行的加入到这个文件中去。例如,第一行可能就是:C:\aFolder\work\Python。 ) `- X, I8 W9 D7 w" D7 t这样可以解决下面的错误,当你导入Spam这个模块的时候就不会出现:ImportError: No module named Spam. 7 L7 e O1 m. l9 s. l# Z3 V ( f8 k8 U, ^# e+ q获取和设置网络数据 $ P' R0 F6 r7 U E直接获取数据是很费力费时的事情。在网络中的每个部分都有几个不同的参量,比如负荷。每个参量均必须分别通过函数调用来访问。所以如果要找出每个母线的电压,那么必须对每个母线通过psspy对象调用方法busdat。它的参数通过一个字符串来解释,就如一开始所说的,这些参数可以在IPLAN说明书里找到,同Python里的命令名字相同。 6 N& x# Z& Z3 y% q. {, K0 y. [
生成 7 S4 P8 ^% u* }5 [2 P3 c字符/文件 % ]% U. r) J% A9 b格式的报告是可以的,我曾经试图寻找转存这些变量的方法,这样就可以不通过文件系统直接可以通过python代码来访问了,但是没找到。如果有谁找到了这种方法请告诉我。如果西门子能改进一下API的话这将变得很简单,但是我们现在只能根据已有的东西来做。! M1 k' T/ k3 ?
反过来,也令人郁闷的是,要设置数据,每个部分的所有参量都要提供出来。幸运的是,有默认的对象_i 和_f,当你不想改变某个值时,插入这些对象即可。当运行和导入我自己的主模块时,我把这些对象存储在psspy对象中,这样每当psspy对象使用的时候,他们就能使用。对于整形和浮点数参数分别有个默认值(对象),我想他们与各自能取到的最大值相等。 / ]# d4 e# s' ^" q 7 b/ n. \5 |9 s8 g! ^0 G7 g" G/ }( d在Python中组织PSSE数据 . w; f$ T9 @0 T+ H当使用Python扩展PSSE时,经常没有必要抽取所有的PSSE使用的数据。我创建了两个主要的类,一个与一个母线有关,叫做Bus,另一个与两条母线有关,叫做Branch。我所使用的所有层次如下所示: ; V, M. [) f6 G
·. K' u2 k1 ~! m8 |3 }0 n% p: m3 @
Bus
o+ C1 g$ O% ?; _; I/ A! Z, m
Load
o / |0 J; m' s O$ N$ sMachine
·+ s( a) a* N2 ~) y4 u6 s3 Q
Branch
o $ G7 `: U1 Y: |" }1 [Line
o+ M3 j; ?/ b: e! a6 \, u
Transformer
我把这些对象做一个列表来标识整个的网络。Python在快速和简化处理对象列表方面非常擅长。选择或者增加方法可以用于大批bus和branch类,这些类包含有用于对象中所有参量的处理方法。这样可以提供一种便利:一个部分的任何参量,通过大量的方法均可以对其他部分可见。可是呢,我正在有目的的在我的工作中避免出现这种情况。 e( x6 q3 o/ K* N7 } ~6 V4 c
注意当在Python中创建一个PSSE模型的拷贝时,这些拷贝还处于同步状态。因为潮流计算的原因,一些参数会改变而其他参数不会,例如,改变线路参数并重新计算,貌似改变了复杂(复数)的母线电压,但是不改变负荷。这样必须把从PSSE模型里观察到的数据同存储在python模型中但是在PSSE模型中使用的数据区分开来。 9 A1 S! A# |* @, ^ / ~0 P- ? f' P1 l编译更复杂的Python程序 ! J `/ y' c3 Z. i. F0 l我保留了一个叫做PSSPYStub.py的python文件,它包含一个仿冒的psspy类,其中对应于每个所使用的psspy方法均创建一个短小的仿冒方法。这样当我进行简单测试编译python代码时把这个PSSPYStub类代替psspy类,这样就避免了开启PSSE,可以允许python调试工具的简单使用。" B% `" k& |0 x
这个短小的仿冒方法对于psspy函数来说是微不足道的,但是在使用一些函数时需要注意,例如nxtbus函数,这个函数用来返回 % R. ^/ v. z) T; O! @调用inibus函数之后还没有输出的下一个载入PSSE的母线节点号。为在这个仿冒方法中实现这个函数,需要在inibus函数中创建一个count变量,并且在nxtbus函数中对这个变量进行递减,并返回一个母线节点号直到其达到0。 0 U! z9 h9 G7 W5 Q; y3 Q- t) F注意!更难的python内容 & M+ ]. M5 B. e, G9 e6 ?. C调试过后的代码如果能在PSSE中运行同样可以使用IDLE界面。打开PSSE和CLI界面并且输入并运行Runldle.py,不出意外地话会打开IDLE编程环境。通过打开这个调试器运行你的python代码。9 L9 p- _# a, a: \" C" b
使用这个方法有点不同,当你使用import命令时,主要的psspy对象和伴随的_i和_f将在你运行中的模块中不能访问。在PSSE中的“Run Auto”按钮不同于标准python 中的import命令。“”按钮允许运行一个python模块时把psspy作为一个全局变量。但是在你得到的IDLE解释器中的import命令不会把psspy作为导入模块的全局变量。在python中一个全局变量只能在本模块中可见。 1 ` h: c7 Z( J6 s6 O为了解决这个问题,我在本应在“Run Auto”按钮运行的代码之外创建了一个类,__init__的定义会将psspy对象作为一个参数分配到一个类变量中。这样他在整个类中都会可见。 $ J; i. L h3 B/ `) A* d包含这个类的模块被导入后,一个这种类的对象会被创建,这样这个类的所有函数都能被调用。例如,这个类可能包含如下的函数: 3 ^* L/ j4 B8 ^3 o& U! l+ M
你可以从Python解释器中手动调用这些函数。 & @$ h1 Y# i2 t) z/ J# Y! k- H同样的,你可以使用__init__+ D6 f5 J1 Z/ X) f! h G
函数仅按顺序包含所有你想执行的脚本。这些命令就像是初始化PSSE和你想使用的任何Python对象。最终这些命令会使PSSE进行一些例如潮流的计算。/ G& Z9 h* c$ E) P$ @1 u
( u6 y" C; T" P7 g! A. Q- Y 处理数组/ ]: Q/ {6 z5 y: B8 D, u
我逐渐能熟练处理数组和数字矩阵了。不在重复强调使用列表类型,而使用数字类型,这样会比使用列表快的多,而且你的程序读起来也更直观。它同在MATLAB里面使用一样方便,数字类型不仅仅是一个Python模块,也与最优化并且与编译的矩阵运算代码相关。8 i+ G* s% @ {0 c5 l8 \, W
与数字类型相关的信息可以在这里找到8 w1 m. h: s& o5 U
在导入数字类型(Numeric)之前必须进行安装。使用在Python中导入模块的标准方法进行导入,你可以通过dir(Numeric)命令观察可用的方法及类结构。 " c8 n6 B. w. z我使用的最多的方法是: 4 x( H% ?+ I; } {Array4 b9 g+ E. ]/ o Y7 c
使用这种方法从一个列表里创建数组可以包含一个数字或者一列数字。加些参数就可以使数组包含浮点数等等。例如:Numeric.array([1,2,3],'f')可以返回一个包含有浮点数1,2和3的数组。0 P, U5 D$ K0 j! d4 A9 {
Arrange ~' |) k. E) W1 m这个方法根据你的描述来产生一个范围的等差数字,例如:Numeric.arange(0,0.5,0.1)返回 3 k/ R, Q; x( Qarray([ 0. , 0.1, 0.2, 0.3, 0.4]). 注意数组中不包括最终值。 ! D3 y3 J1 w u! ~Transpose) O8 n$ R. ]/ y7 B
给定a=array([array([0,1,2]),array([3,4,5])]), 那么transpose(a)可以返回: , @6 w' I2 {% R; Y% j: c+ m$ l v : |& x1 z% O4 ]" @7 ]2 }9 M ; U# ~. u, o7 n9 G! U, \6 E# J4 @" y) i
array([[0, 3],9 m' y1 j% T) x. k, X6 h2 D
9 _' ?( v4 u- H/ {3 Q+ J9 y
[1, 4], 0 R2 l) W3 V, X[2, 5]])数字数组中最有用的功能是数字定义了标准的操作如何执行例如加法,乘法和逻辑运算。 保存数据以便在MATLAB中使用导入数据到MATLAB中有多种方法,广义来说主要有以下三种:l ! Z C+ z& E/ ~* `4 JMATLAB格式.mat文件l5 E8 Q Q8 }# h3 h; j3 O1 r5 T! T
ASCII编码数据文件l4 c; B9 `/ l! ?$ G4 C
文本文件MATLAB格式.mat文件这个格式需要各种文件头。我不知道有没有pythond的模块可以执行保存为.mat文件,但是在这个文件中细节描述了这种格式。ASCII编码数据文件就我所注意到的,这些文件只能存储数字信息。这些值按照行列来组织,每一行的列数必须相等。列之间可以使用各种字符隔开,比较常用的选择就是使用tab建或者空格键键入的空格。行使用转行分开,这样他们在文本编辑器中显示新的一行。下面是一个例子:
from Numeric import *m = array([1,10,2,20])m = reshape(m,(2,2))f = open('test.dat','w')for r in m:5 i* ?. S: N' e; x& d. k2 i; c
for c in r:" c9 D+ z2 {5 O: k1 M
f.write("%i ")' Z- g3 r( ^% L1 {" y+ Z9 _
f.write("\n")f.close()
在MATLAB里面,下面的语句就可以装载test.dat文件并把它作为一个变量test。文本文件最强大的,看起来可以被容易执行的方法,就是生成一个文本字符串,当执行的时候可以生成需要的对象或者在MATLAB中的对象。但是我想这可能不是最有效的办法。例如,设想一个bus类含有fields, voltage, load 和 generation over time,如下所示:
class Bus:! I* D% V% ]* W
number=None3 I8 P8 [# O) v
Pgen=[] ! b0 A1 `, C @Pload=[] 4 [' k5 N% T) Z. C. f* {V=[]0 V H- P- J3 z6 \
def __init__(self,number):, Y* A, Q; z ?9 P
0 J* N6 ~+ z4 a9 vself.number = number + I- @% x8 d: L$ I/ [$ e) Q6 C; S
def storeStepData(self,g,l,v):6 `! a8 O& @4 x. x
9 B1 h0 \3 h+ hself.Pgen.append(g); Z. j9 g( z4 I5 W F
self.Pload.append(l) ! t4 @6 a4 l g& L4 B0 b6 lself.V.append(v)
在类的定义中加入一种方法,这个方法可以产生适用于MATLAB的自我解释的字符串描述。9 o3 H) V: K4 j( u9 s) n
def matlabString(self):5 P1 T7 R* B( y; h
s1="bus%i.Pgen=%s"%(self.number,str(self.Pgen)) " A4 @7 f% B. B. C; C) as2="bus%i.Pload=%s"%(self.number,str(self.Pload))" X- d ]- e0 e6 k% N8 G( o
s3="bus%i.V=%s"%(self.number,str(self.V))& L; j$ m* y# N
return("%s;%s;%s;")%(s1,s2,s3)
在Python中,在主程序中插入退出字符来建立包含变量的字符串。紧接着一个包含需要插入主程序的值的tuple(元组)。最后一样连接三个其他的字符串,并在每个字符串后面放置“;”字符,这同时把三个命令分开,并能组织MATLAB输出这些结构内容。1 w$ @, x- t6 l' w( c
下面的测试代码在Python中运行会产生一个示例保存文件。5 y$ S9 T/ ~+ r1 {; ~. N; G# X