( @' n( ?3 P M0 t ; F9 ]/ n% ]3 I O' {PSSE30提供了Python的API接口,使在PSSE中使用Python脚本语言成为了可能,这不仅使PSSE批量运行,同时可以根据你的Python代码,使处理功能更强大,更灵活。; D. q: P8 f/ i
我没有找到很好的关于在PSSE中使用Pyhton的资料,我把我能找到的东西写在这里供初学者入门。5 x! d. z2 c9 t- y& l9 _
前面的一些资料能在使用说明书USERS.pdf的第12章找到,其他资料是通过API.pdf和IPLAN.pdf综合而来的,可以从中找到。 $ s( J/ @/ i' I/ f1 t5 ?% I我发现使用Adobe的搜索功能非常有用,你可以根据一个关键词同时搜索在一个文件夹下面的所有的pdf文件,这样寻找某个函数的IPLAN和API的描述遍得很简单。IPLAN的描述一般在查找详细描述“某些传递数据的参数”的解释时非常有用。IPLAN函数的名称同API文档中Python的那些函数相同,只是后者是大写字母而已。 0 n" W" y1 q/ P5 [我使用的是30版本的PSSE,和2.3版的Pyhton,这篇文章的前提是你了解一些基本的Python,Mack Lutz和David Ascher写的《Learning Pyhon》非常不错。$ h* l/ D9 d& u5 j2 Z Python ! _& C: m( [# e5 p9 JPython.org homepage - H, I( _; H2 ]! a* sPSSE " L6 D" G& I& X2 A5 f+ w$ oPower System Simulator for Engineering. @* p- _1 u2 F" Z
' a% N& a: W6 h 在PSSE中使用Python简介+ y6 K- v% V, c, k+ a2 P
PSSE说明文档说:根据你在PSSE中的操作可以生成Python代码。这花了我一段时间才理解,因为我是PSSE和Python的初学者。根据以下步骤,可以生成你的第一个python代码,用来进行潮流计算分析。前提是你有一个包含有网络信息的.raw文件,格式符合PSSE30要求。 - U) b+ I3 S+ C) g6 f1、. j) r8 F4 X" {8 K. |
打开PSSE。 # O: @% l) s& K# ~2、0 M2 r0 R) S" F7 ?
选择“I/O Control”中的“Start Recording”菜单,输入一个PSSE写入的文件名。PSSE会自动地添加.py后缀。 " p3 ~ d& r$ e( N) }3、) C* a% E1 j( W
使用“File”菜单中的“Open”按钮,读入网络信息。将文件类型设定为.raw告诉PSSE你在给他的是raw文件(不知道是原文傻还是我翻译的傻:’() : q6 f2 z7 B! P; Z, \/ O4、 9 d, a. z2 q9 ]" p6 ~$ ]选择“Power Flow”中“Solution”,选择“Solve”,运行潮流计算。选择所需要的设置模式,点击“Solve”按钮。 7 E. I9 {: N% L5、% I* _1 b. }' J3 ~
选择“File”菜单中的“Save or Show”保存运算结果。选择“Power Flow Raw Data”选项卡,点击“Data File”单选按钮,并在旁边的文本框中输入文件名。点击OK按钮。 * p5 p2 H. K8 y% E使用你最喜欢的python浏览器查看生成的python代码。 . o* l$ C1 ?. ^' y+ W
# 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"""); I5 X1 k: q _9 V+ \& N( ?+ S8 W: u9 v
psspy.fdns([0,0,0,1,1,0,99,0])5 E; h) D# ~! h E
psspy.rawd(0,1,[1,1,1,0,0,0],0,r"""C:\Documents and Settings\jbo\MySensibleFolderName\SOLVEDtestCase_30EV30test.raw""")
注意,所有的方法都是通过一个叫做psspy的对象调用的。这个对象包括所有可用的方法和对象。他们看起来只不过是通过一个列表来组织的。我还没有写任何接口对象来组织和调用psspy方法时,就是这么想的。(瞎翻译的) : j- Y" T# n* K# S K/ k! L9 w注意声称路径字符串的方法,这不是python提倡的格式,下面的写法更好:$ y. N' q- z' v7 j
"C:\\Documents and Settings\\jbo\\MySensibleFolderName\\testCase_30EV30test.raw".
x4 e* @* C- V% J% ` 怎样来运行python代码 # @% I/ X8 \* E我试过三种方式 0 t g& ~1 `1 m" [# l& p9 F1、) M2 L- U( x5 V8 Y
在PSSE中打开命令输入窗口(command line input, CLI)任务。% B+ s: i" {( T; x" z+ C8 Q
2、 # Y* P5 j. Q* e' B6 S' {在PSSE中选择“Run Automation File”按钮运行一个python文件。 # ?% r3 V7 q: k+ k3、 , C1 {# g* T+ M6 E# p6 S在PSSE30中python文件作为一个命令行变量。你可以指定图形界面只有在完成之后才出现。这可以为机器节省内存。在这种情况下,你可以指定仿真的母线数量。可以参照PSSE Users Manual中的PSSE Overview。; }" L4 j" k$ h5 M 在PSSE中打开CLI4 p$ }# {; q |4 `& \1 \# o
1、# q0 J9 G) m/ D. }" J
在“I/O Control”菜单中选择“Begin command line input session”。3 q' W4 ]0 u& \7 z b+ m
2、9 V! v# w3 ]3 y1 t Q& I
使用“Command Language”选择框将语言更改为python。 + m5 f, L$ W: C: y' `4 g3、/ |+ S, x( D! G4 k# a- Y! `. W
选择“RunAuto”按钮并选择一个python文件,PSSE会运行那个文件。 % z# ?# Z& ^- q% d* [注意python命令可以直接在控制台输入。控制台动作同编译python的交互式平台不同,它不自动显示调用方法所返回的结果。要想显示的话必须使用python的print命令,例如:print(psspy.aMethod(myParameters))。- _( U o9 N" E, z+ K" X
一个重要的点是所有列出的方法都是psspy方法。所以使用要使用totbus方法返回母线数量时,输入CLI时不能使用ival=totbus(),而应该使用ival=psspy.totbus()。在CLI中使用print(ival)来显示ival。Python语法也可以使其简化,如:from psspy import * 。采用何种编程风格由用户决定。 2 Y7 z3 z$ [3 q ; u7 ~6 X- i( J# F i, u 在IDLE编译平台测试python代码 - M" j, q; l0 u. a我花了让人崩溃的长时间来寻找下面这个加入到python路径的方法。- w! z. C6 ^. C
当你想将自己写的一个模块导入python,或者要把一个处在其他文件夹下的模块加入到python文件中去,那么下面的方法就大有用啦:) R3 h3 `) ?6 q! o# n& m
1、; }7 e% n+ q7 C7 Y7 m' D; o
创建一个扩展名为.pth的文件。我们起个很漂亮比尔盖茨又很喜欢的名字myconfig.pth。当你在使用记事本之类的编辑器时就要小心了,不要保存成myconfig.pth.txt哦。 8 z) Y; u& \. d( W6 k' L2 h: B2、 G' A- b5 C' t- m! P. a
把这个文件放到python根目录下面去,比如我的就是C:\Python23。$ \- `2 C2 g$ y8 t2 B
3、- M- g e4 A7 R0 y
把每个你想加入PYTHONPATH的文件夹全路径,单独一行的加入到这个文件中去。例如,第一行可能就是:C:\aFolder\work\Python。0 t& t2 i8 y: ^* |" ^
这样可以解决下面的错误,当你导入Spam这个模块的时候就不会出现:ImportError: No module named Spam.0 V; L& Q, N+ \
4 p8 \' Y& l3 S5 \6 A1 _ 获取和设置网络数据0 l% {+ T, }. o- g% B" S
直接获取数据是很费力费时的事情。在网络中的每个部分都有几个不同的参量,比如负荷。每个参量均必须分别通过函数调用来访问。所以如果要找出每个母线的电压,那么必须对每个母线通过psspy对象调用方法busdat。它的参数通过一个字符串来解释,就如一开始所说的,这些参数可以在IPLAN说明书里找到,同Python里的命令名字相同。 ! Q" S$ h/ S6 ^. @1 [# @4 j7 j2 g
生成# ~% @) \5 P' [2 [& W
字符/文件8 V/ P7 _! h+ q3 l; P
格式的报告是可以的,我曾经试图寻找转存这些变量的方法,这样就可以不通过文件系统直接可以通过python代码来访问了,但是没找到。如果有谁找到了这种方法请告诉我。如果西门子能改进一下API的话这将变得很简单,但是我们现在只能根据已有的东西来做。7 t/ C; M/ P/ n" `. C7 A1 K
反过来,也令人郁闷的是,要设置数据,每个部分的所有参量都要提供出来。幸运的是,有默认的对象_i 和_f,当你不想改变某个值时,插入这些对象即可。当运行和导入我自己的主模块时,我把这些对象存储在psspy对象中,这样每当psspy对象使用的时候,他们就能使用。对于整形和浮点数参数分别有个默认值(对象),我想他们与各自能取到的最大值相等。 ) e$ Z) r) J; Q6 m : q# U5 J: N* x, |2 B 在Python中组织PSSE数据" o3 y) T& B! u5 N" [* [4 T
当使用Python扩展PSSE时,经常没有必要抽取所有的PSSE使用的数据。我创建了两个主要的类,一个与一个母线有关,叫做Bus,另一个与两条母线有关,叫做Branch。我所使用的所有层次如下所示: * ^, J) X. J! D3 ]$ K0 q
· . U! C w2 ~- F0 i' E1 h5 pBus
o & O; P0 u/ O, MLoad
o. X& g2 V0 R1 v; ?3 k$ z; s
Machine
· + d% a+ R3 ^, ?% K+ tBranch
o$ L% U- s3 s" Z$ C+ _5 x
Line
o * y8 n# H: D) o4 hTransformer
我把这些对象做一个列表来标识整个的网络。Python在快速和简化处理对象列表方面非常擅长。选择或者增加方法可以用于大批bus和branch类,这些类包含有用于对象中所有参量的处理方法。这样可以提供一种便利:一个部分的任何参量,通过大量的方法均可以对其他部分可见。可是呢,我正在有目的的在我的工作中避免出现这种情况。; X8 q) v2 ~, Y w% p
注意当在Python中创建一个PSSE模型的拷贝时,这些拷贝还处于同步状态。因为潮流计算的原因,一些参数会改变而其他参数不会,例如,改变线路参数并重新计算,貌似改变了复杂(复数)的母线电压,但是不改变负荷。这样必须把从PSSE模型里观察到的数据同存储在python模型中但是在PSSE模型中使用的数据区分开来。" i$ I9 u! v$ l8 P0 j0 X r! w
) _1 Q d/ @$ [0 Q 编译更复杂的Python程序 3 r8 Z% y. u! [# j* t2 ]. p我保留了一个叫做PSSPYStub.py的python文件,它包含一个仿冒的psspy类,其中对应于每个所使用的psspy方法均创建一个短小的仿冒方法。这样当我进行简单测试编译python代码时把这个PSSPYStub类代替psspy类,这样就避免了开启PSSE,可以允许python调试工具的简单使用。. I( F8 w' H ]8 ^6 a
这个短小的仿冒方法对于psspy函数来说是微不足道的,但是在使用一些函数时需要注意,例如nxtbus函数,这个函数用来返回 V! }" ?2 ?: @
调用inibus函数之后还没有输出的下一个载入PSSE的母线节点号。为在这个仿冒方法中实现这个函数,需要在inibus函数中创建一个count变量,并且在nxtbus函数中对这个变量进行递减,并返回一个母线节点号直到其达到0。+ d8 j9 N+ ?& o% l9 H0 w 注意!更难的python内容 ' Q( S G/ n. e调试过后的代码如果能在PSSE中运行同样可以使用IDLE界面。打开PSSE和CLI界面并且输入并运行Runldle.py,不出意外地话会打开IDLE编程环境。通过打开这个调试器运行你的python代码。 * H# U5 Z1 v) b+ Q) q6 n使用这个方法有点不同,当你使用import命令时,主要的psspy对象和伴随的_i和_f将在你运行中的模块中不能访问。在PSSE中的“Run Auto”按钮不同于标准python 中的import命令。“”按钮允许运行一个python模块时把psspy作为一个全局变量。但是在你得到的IDLE解释器中的import命令不会把psspy作为导入模块的全局变量。在python中一个全局变量只能在本模块中可见。# ?" T( j9 O# s! w% r$ b
为了解决这个问题,我在本应在“Run Auto”按钮运行的代码之外创建了一个类,__init__的定义会将psspy对象作为一个参数分配到一个类变量中。这样他在整个类中都会可见。( t4 y$ q$ N d+ W% f6 N0 J
包含这个类的模块被导入后,一个这种类的对象会被创建,这样这个类的所有函数都能被调用。例如,这个类可能包含如下的函数: & y; R* j% D' C1 p" @- g" O
在Python中,在主程序中插入退出字符来建立包含变量的字符串。紧接着一个包含需要插入主程序的值的tuple(元组)。最后一样连接三个其他的字符串,并在每个字符串后面放置“;”字符,这同时把三个命令分开,并能组织MATLAB输出这些结构内容。; r. B' ]5 J: `1 f8 u1 `4 E; ?" s7 ?
下面的测试代码在Python中运行会产生一个示例保存文件。 ) M/ c U- \' L. w1 L. I* h
结构“bus10”现在可以在键入的matlab代码中起到作用。其中“10”部分是根据bus和母线节点号在matlabSring()函数中生成的。 5 `6 D- e8 {4 c" j$ `. B E; k 5 H3 N; G9 _# q) C# t% m) j异常处理2 |+ q+ R. R* p2 H% [3 @
异常处理,是现代编程语言中使用的一种错误处理和诊断的方法。例如,没有必要在其他返回值再增加一个错误代码,而是如果有错误发生的话直接引发一个异常。这样做的好处是,错误不会被默认忽略。如果不检查错误代码的话,这个方法的失败就可能不被发现,可能会造成跟踪程序错误的困难。7 @, Z1 L; v7 s9 W" d5 e+ P8 J& n
在python.org有一个异常处理的手册,它同样包含有用户自定义异常。 B6 G9 t* D2 L! u$ ^
2 X. }- d) S! m H; d, g( z% U( z* Y但是PSSE提供的API接口不适用异常处理,这样你在每次调用API时,都要严格检查错误代码变得很重要。我建立了一个与PSSE交互的特殊类来解决这个问题,所有API的调用都要适用这些类。每个API调用的时候都跟随错误代码检查。如果错误代码只是的是失败,则就引发一个异常,根据具体的错误代码使用合适的,定制的异常和信息。! B& m* [; F S. I
. ?) S! p7 K; ]+ k3 w2 G. r# z' f" _% p使用Python模块random3 r7 r% f1 p5 L" Q Random模块可以根据不同的分布状态产生随机数,并允许控制产生的状态。使用在Python中引入模块的标准方法,导入random。你可以通过dir(random)函数查看可用的方法和类的构造。 ! h9 |- O S. _$ w我用的最多的方法是:6 R8 D" C; T- m; E
Getstate ) C4 t9 r) [8 ?0 R( \( M+ b+ F. D这个方法返回产生随机数的当前状态。这个状态可以保存并在稍后用来设置模块的状态回到以前状态,具体方法可以查看下面的setstate,例如:savedState = random.getstate().4 G% [- B5 Y' B! m( ?0 E1 u
Jumpahead1 z2 ]) V$ v/ f: Z
这个方法用来改变当前状态,只要模块不会产生一系列数字覆盖在执行jumping ahead命令之前的状态。例如random.jumpahead(42)1 W8 q+ p7 m9 G5 A( I
normalvariate和uniform1 K+ w, T4 ^: w. J% _
这些方法是少数返回随即数的方法的两个,他们分别返回符合正态分布和平均分布的随机数。方法mormalvariate需要平均值和标准偏差两个参数,方法uniform需要最大值最小值得范围rang[min, max)。 ( e) m! B% v0 M3 P/ y; h例如:random.normalvariate(0,1)和random.normalvariate(0,10). 0 L9 {0 X% R3 b7 {# oSeed/ V) U5 E) `6 Z
这种方法可以使用任何不规则格式设置随机数产生器的状态,例如字符串。这样,不必要首先在文件系统中存储一个状态类就可以设置状态了。例如:random.seed("My! I do like coding, it's such fun!"). % @# m$ o$ ?7 K! }# z; eSetstate& b& L1 m0 I! E8 G- Q" b- w
这种方法使随机数产生器的状态设置为之前使用getstate保存的状态,例如:random.setstate(saveState)。% W) u1 |& b- H- I c
我发现在使用random模块时创建自己的类是十分有用的,在其中,产生随机数的方法保证了random模块的状态不发生变化。这可能被忽略了,但是一次只有一个random模块导入。那样我就可以创建多个自定义的random模块来产生随机数字,没有必要干涉每个产生器的状态。 . _2 ^. m5 Q+ {: V0 y " g, i+ q- ?$ p; i/ G' ]其他注意事项 ' I( C1 ]" A* E* ?# r' b/ \' {9 F# K+ tl , b$ D: [1 B! C3 ~( X" C我也写了一些实现以下功能的python代码: 9 _ b" j/ @& U# y² % Y% n8 f0 U5 c! h% f潮流运算和获取网络所有的数据。3 R6 R% l* s/ N' [6 m
² ) Y/ |; I5 U! v4 D基本的低/高/带通滤波器。 ! U2 y# _4 w- J. _& ]" S²7 a2 E0 p. S/ L
梯形三角形模糊逻辑 ; p8 A0 `+ J9 P7 L+ x. `/ \²6 }- ^9 p% M! v9 K
如下所说的我不能使用scipy,基本的插补类! ]: M/ R1 x5 u1 z. l6 [! V+ f
l: s. L: S% O1 n/ x, F2 {1 ? e
我在PSSE CLI或者在CLI运行代码时,使用import scipy时出现了问题,当我从Fortran machine里导入时,出现了浮点数溢出的现象,所以我尝试了很多次重建wheel因为我不能使用。 * c8 B; n/ _1 V6 {! R( }6 kl " N3 X, K, M, ?我又碰到浮点数溢出的现象了,这次是当我把自己的模糊逻辑模块应应用为PSSE扩展脚本的一部分时出现的,我想这是甚至因为我再scipy只引入了interp部分造成的。如果只在python解释器下测试的话就不会出现这个问题。9 N3 f; T! |7 Y
l ) |- ?2 |5 z! T我碰到了一个Fortran的错误,可能是由Python引起的。我忘记了它是不是被零除过,还是因为我试图当作一个list来读取数字,或者这两个方面都有。这里的课程可能会在Python没有抛出异常的地方出现问题,结果造成了不良的运行时错误,但是原因可能很简单而且错误能确定。 4 b/ D2 L; F) L, Jl6 ~. h) f8 F0 Q: J
在潮流运行完毕之后需要使用solved()来检验潮流是不是收敛了。如果潮流没有收敛,一些网络可能从步参数比默认参数小100或者更多(-_-)受益。当先减小补偿时,代数限制应该也要放宽。5 W2 t$ f# d0 i
l ) }5 E1 `" ]& O7 S读一下说明书。他有不同求解方法的正面和反面介绍。 # o2 ]& E( S0 _# d/ xl/ A: M5 E n: @0 M* `3 M+ `- t! |
在我的版本中GSLV会让电脑崩溃,更郁闷的是他在我的工程里运行比在MSLV中运行的好,而我只能呢个使用MSLV进行扩展仿真。 2 F. b; E4 n) n- |/ {/ A6 H" kl* ?0 d7 c" E$ q5 ]& F* F7 d
警告。逐步备份你的.raw文件。PSSE有个坏习惯,覆盖的时候没有警告,即使那个模式已经关掉。PSSE还可能把不能自动调节的变压器,做成能自动调节的变压器模型。我不确定什么时候会发生这种情况,但是我已经被这个问题浪费了一些时间了。5 {3 {$ v+ | o; d! |
l ) M% E, H4 `" Z6 s9 k8 n& ^5 ?一个不错的网站,关于Python的。 $ m: B$ V6 \. I 2 o% g c9 n0 k% |建议和评论( m7 E6 C% Y) q# \" r0 O# N) V
如果有任何建议或者改进欢迎发Email给我,我可以分别把具体的PSSE功能性的使用和详细地执行信息联系起来。Email jbo at ee ed ac uk。# ?, ^8 \9 M& O: v6 _$ l
发邮件给我的任何问题或者在AQ网页里的问题我都会回答的。 ; Y; i! |, J& J- D! r* Z2 e; M- a! S; f1 z7 j) X z