Digsilent Dpl Tutorial

DIgSILENT PowerFactory Application Guide DPL Tutorial DIgSILENT Technical Documentation DIgSILENT GmbH Heinrich-Hertz

Views 198 Downloads 8 File size 3MB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

DIgSILENT PowerFactory Application Guide

DPL Tutorial DIgSILENT Technical Documentation

DIgSILENT GmbH Heinrich-Hertz-Str. 9 72810 - Gomaringen Germany T: +49 7072 9168 00 F: +49 7072 9168 88 http://www.digsilent.de [email protected] r1152

Copyright ©2013, DIgSILENT GmbH. Copyright of this document belongs to DIgSILENT GmbH. No part of this document may be reproduced, copied, or transmitted in any form, by any means electronic or mechanical, without the prior written permission of DIgSILENT GmbH. DPL Tutorial (DIgSILENT Technical Documentation)

1

Contents

Contents 1 Getting Started in DPL - A Quick Tutorial

5

1.1 Create a small sample project . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

5

1.2 Create a DPL command object . . . . . . . . . . . . . . . . . . . . . . . . . . . .

5

1.3 Create a filter and put it inside the DPL command object . . . . . . . . . . . . . .

7

1.4 Write the DPL Script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

9

2 Anatomy of a DPL Object

11

3 Basic DPL Scripting

16

3.1 Accessing Network Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

16

3.1.1 By the General Selection . . . . . . . . . . . . . . . . . . . . . . . . . . .

17

3.1.2 By Sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

18

3.1.3 By Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

19

3.1.4 By Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

21

3.2 Identifying, Accessing and Modifying Object Parameters . . . . . . . . . . . . . .

22

3.2.1 Identifying Variable Names for a Parameter . . . . . . . . . . . . . . . . .

22

3.2.2 Accessing Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

23

3.2.3 Modifying Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

23

3.3 Creating New Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

24

3.3.1 Copy from an Internal Template . . . . . . . . . . . . . . . . . . . . . . . .

24

3.3.2 Copy from an External Template . . . . . . . . . . . . . . . . . . . . . . .

25

3.3.3 Create a New Object by Code

. . . . . . . . . . . . . . . . . . . . . . . .

26

3.4 Checking if a Project is Active . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

26

3.5 Navigating Folders and Object Contents . . . . . . . . . . . . . . . . . . . . . . .

27

3.5.1 Project Folders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

27

3.5.2 Object Contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

27

3.5.3 Objects in a Study Case . . . . . . . . . . . . . . . . . . . . . . . . . . . .

28

3.6 Accessing Study Cases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

28

3.7 Executing Calculations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

29

3.8 Accessing Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

30

DPL Tutorial (DIgSILENT Technical Documentation)

2

Contents

3.8.1 Static Calculations (Load Flow, Short Circuit, etc) . . . . . . . . . . . . . .

30

3.8.2 Dynamic Simulations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

30

3.9 Writing to the Output Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

30

3.10 Plotting Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

32

3.10.1 Creating a New Virtual Instrument Page . . . . . . . . . . . . . . . . . . .

32

3.10.2 Creating a Virtual Instrument . . . . . . . . . . . . . . . . . . . . . . . . .

32

3.10.3 Adding Objects and Variables to Plots . . . . . . . . . . . . . . . . . . . .

33

3.10.4 Plotting Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

33

4 Advanced DPL Scripting

34

4.1 DPL Sub-Scripts (or Subroutines) . . . . . . . . . . . . . . . . . . . . . . . . . . .

34

4.1.1 Executing Sub-Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

34

4.1.2 Passing Arguments to Sub-Scripts . . . . . . . . . . . . . . . . . . . . . .

35

4.1.3 Accessing Sub-Script Results . . . . . . . . . . . . . . . . . . . . . . . . .

36

4.2 Vectors, Maps and Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

37

4.2.1 Vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

37

4.2.2 Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

39

4.2.3 Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

41

4.3 Topological Search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

42

4.4 Reading from and Writing to External Files . . . . . . . . . . . . . . . . . . . . .

44

4.4.1 Standard File I/O Methods

. . . . . . . . . . . . . . . . . . . . . . . . . .

44

4.4.2 Exporting WMF Graphic Files . . . . . . . . . . . . . . . . . . . . . . . . .

46

4.5 Fast Fourier Transforms (FFT) . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

46

4.5.1 Specifying Input and Output Results Files . . . . . . . . . . . . . . . . . .

47

4.5.2 Executing the FFT Calculation . . . . . . . . . . . . . . . . . . . . . . . .

47

4.5.3 Accessing the FFT Results . . . . . . . . . . . . . . . . . . . . . . . . . .

48

5 Working with Results Files

48

5.1 Adding Results Files to the DPL Script . . . . . . . . . . . . . . . . . . . . . . . .

49

5.2 Structure of Results Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

49

5.3 Loading a Results File into Memory . . . . . . . . . . . . . . . . . . . . . . . . .

50

5.4 Getting the Relevant Column Number . . . . . . . . . . . . . . . . . . . . . . . .

50

DPL Tutorial (DIgSILENT Technical Documentation)

3

Contents

5.5 Getting Data from the Results File . . . . . . . . . . . . . . . . . . . . . . . . . .

50

5.6 Getting the Time Interval Data

51

. . . . . . . . . . . . . . . . . . . . . . . . . . . .

5.7 Finding the Number of Time Intervals

. . . . . . . . . . . . . . . . . . . . . . . .

51

5.8 A Simple Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

51

6 Working with Virtual Instrument Panels

52

6.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

52

6.2 Local Title Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

52

6.2.1 Creating Local Title Blocks Manually . . . . . . . . . . . . . . . . . . . . .

53

6.2.2 Creating Local Title Blocks in DPL . . . . . . . . . . . . . . . . . . . . . .

53

6.2.3 Title Block DPL Script Example . . . . . . . . . . . . . . . . . . . . . . . .

54

6.3 Constants in Visplots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

55

6.3.1 Constants DPL Script Example . . . . . . . . . . . . . . . . . . . . . . . .

56

6.4 Exporting VI Panels to WMF

. . . . . . . . . . . . . . . . . . . . . . . . . . . . .

7 Working with Graphical Objects

56 58

7.1 Graphical Objects in PowerFactory . . . . . . . . . . . . . . . . . . . . . . . . . .

58

7.2 Finding a Graphical Representation of a Network Element . . . . . . . . . . . . .

60

7.3 Creating Graphical Objects in DPL . . . . . . . . . . . . . . . . . . . . . . . . . .

61

DPL Tutorial (DIgSILENT Technical Documentation)

4

1

Getting Started in DPL - A Quick Tutorial

1

Getting Started in DPL - A Quick Tutorial

This is a short step-by-step tutorial that attempts to get the user started in writing and running DPL scripts. Before going through this tutorial, the user should already have a basic grasp of PowerFactory handling and performing simple tasks such as load flows and short circuit simulations.

1.1

Create a small sample project

Firstly, we will create a small sample project. Create a new project and draw the following simple 20kV network using line types from the global library:

1.2

Create a DPL command object

1. Go to the scripts folder of the project library:

DPL Tutorial (DIgSILENT Technical Documentation)

5

1

Getting Started in DPL - A Quick Tutorial

2. Right-click anywhere in the data window and select New → Others. . .

3. Select DPL Command (ComDPL) and press OK:

4. Call the script DPL Loading: DPL Tutorial (DIgSILENT Technical Documentation)

6

1

Getting Started in DPL - A Quick Tutorial

1.3

Create a filter and put it inside the DPL command object

1. DPL command objects can contain other objects within it. To see the contents of a DPL command object, click on the Contents button:

2. We want to create a filter object. Right-click anywhere in the contents area and select New → Others. . . Select General Filter (SetFilt) and press OK. DPL Tutorial (DIgSILENT Technical Documentation)

7

1

Getting Started in DPL - A Quick Tutorial

3. Name the filter Lines and in the Object Filter option, select Line.

4. In the Look In option, select Network Data:

DPL Tutorial (DIgSILENT Technical Documentation)

8

1

Getting Started in DPL - A Quick Tutorial

5. Finally, check the Include Subfolders option. The final filter object should look like this:

6. Click on the Apply button, and the three line objects should appear in a data window:

7. Press OK. The filter object should now be saved inside the DPL command object. When objects are saved inside the DPL command object, they can be called by a DPL script by simply referencing the name of the saved object, i.e. in this case Lines.

1.4

Write the DPL Script

1. Click on the Script tab in the DPL command object:

DPL Tutorial (DIgSILENT Technical Documentation)

9

1

Getting Started in DPL - A Quick Tutorial

2. We will now write a DPL script that will execute a load flow and print out the name of each line and its corresponding loading in the output window. Type the following code into the script area: ! Variable declarations set sLines; object ldf, oLine; ! Run a load flow ldf = GetCaseObject('ComLdf'); ldf.Execute(); ! Get the set of lines contained in the filter ! The object Lines is the filter contained in the DPL command object sLines = Lines.Get(); ! Go through each line, and show name and loading oLine = sLines.First(); while(oLine) { printf('Loading for %s: %6f %%', oLine:loc name, oLine:c:loading); oLine = sLines.Next(); } The script should look like this:

DPL Tutorial (DIgSILENT Technical Documentation)

10

2

Anatomy of a DPL Object

3. Press Save and then Execute. The following results should be seen in the output window: DIgSI/info - DPL Program 'DPL Loading' started DIgSI/info - Element 'External Grid' is local reference in separated area of '1' DIgSI/info - Calculating load flow... DIgSI/info ---------------------------------------------------------------------DIgSI/info - Start Newton-Raphson Algorithm... DIgSI/info - load flow iteration: 1 DIgSI/info - load flow iteration: 2 DIgSI/info - Newton-Raphson converged with 2 iterations. DIgSI/info - Load flow calculation successful. Loading for Line1: 9,862179 % Loading for Line2: 19,908511 % Loading for Line3: 30,347751 % DIgSI/info - DPL program 'DPL Loading' successfully executed Congratulations, you’ve just written your first DPL script!

2

Anatomy of a DPL Object

To understand how DPL works, it is important to understand the general structure of a complete DPL object. The actual script or code is only a part of the story, and this script is actually DPL Tutorial (DIgSILENT Technical Documentation)

11

2

Anatomy of a DPL Object

contained inside an object called the DPL Command object. Now we’ll have a look at what else is inside the DPL command object. DPL command objects are normally located in the project library under Scripts:

Whenever you open a DPL command object, you will see a window with a number of tabs Basic Options, Advanced Options, Script, Description and Version. We will go through each tab and the functions that are available

The Basic Options tab (shown above) has the following functions: • Change the name of the DPL command object

DPL Tutorial (DIgSILENT Technical Documentation)

12

2

Anatomy of a DPL Object

• Choose a general selection (e.g. a set) that can accessed in the script as the set object SEL • Define internal input parameters - in the script, the names of the input parameters can be used like variables and do not need to be redefined • Define external objects - these are objects external to the DPL command object that you want to access via the script. This can be any object, e.g. an element in the network model, a study case, an equipment type, etc. Inside the script, the object can be used like a variable by calling the name defined here. The Advanced Options tab (shown below) has the following functions: • Select a remote script - rather than use a script defined locally in the DPL command object, you can select a script that has been defined in a separate object. One reason to employ a remote script is if you have multiple study cases using the same script code, but different input parameters. If you were to use a remote script, then modifying the master script will affect all the DPL objects that refer to it. If you had locally defined scripts, then you would need to change the code in every single local DPL object individually. • Define result parameters - these are essentially output parameters that are stored inside the DPL command object (even after script execution). You can access these parameters as if they were from any other type of object, i.e. either by another DPL script or as a variable to display on a plot.

The Script tab (shown below) is where you write the script code.

DPL Tutorial (DIgSILENT Technical Documentation)

13

2

Anatomy of a DPL Object

The Description and Version tabs are informational tabs for script descriptions and revision information

DPL Tutorial (DIgSILENT Technical Documentation)

14

2

Anatomy of a DPL Object

Lastly, the DPL command object is also a container for other objects. By clicking on the Contents button, you can see what is inside the DPL command object:

DPL Tutorial (DIgSILENT Technical Documentation)

15

3

Basic DPL Scripting

Inside the DPL command object above, you can see that it contains a vector object dpl vec and another DPL command object sub max vector (this is a sub-script - see Section 4.1 for further details). Much like input parameters and external objects, the objects contained in the DPL command object can be accessed inside the script like variables with the names of the object (they do not need to be re-defined in the script).

3

Basic DPL Scripting

3.1

Accessing Network Objects

There are four main approaches to accessing network objects via DPL: • By the general selection • By sets • By filters • By code (internal functions)

DPL Tutorial (DIgSILENT Technical Documentation)

16

3

Basic DPL Scripting

3.1.1

By the General Selection

The general selection is a set that can be defined in the Basic Options tab:

Alternatively, the general selection can be defined by selecting elements in the single line diagram and pressing right-click → Execute DPL Scripts (see the figure below).

DPL Tutorial (DIgSILENT Technical Documentation)

17

3

Basic DPL Scripting

Inside the script, the general selection can be accessed by invoking the special reserved object variable SEL. For example, the code snippet below gets all of the lines in the general selection: set sLines; ! Get the set of lines contained in the general selection sLines = SEL.AllLines();

3.1.2

By Sets

Sets can be included inside the DPL command object or referenced as an external object. For example, the DPL command object below contains the set object Set.

DPL Tutorial (DIgSILENT Technical Documentation)

18

3

Basic DPL Scripting

Inside the script, this set can be accessed using the name Set. For example, the code snippet below goes through each object in the set object Set and prints out its full name. object oObj; ! Cycle through the objects in the set and print out the full name oObj = Set.First(); while(oObj) { oObj.ShowFullName(); oObj = Set.Next(); }

3.1.3

By Filters

Filter objects have to be put inside the DPL command object for them to be accessible by DPL scripts. To see what’s inside a DPL command object, press the Contents button on the right-hand side

DPL Tutorial (DIgSILENT Technical Documentation)

19

3

Basic DPL Scripting

of the DPL command dialog box.

Firstly, create a filter inside the DPL command object. For example the filter Lines, which finds all of the lines in the project, is created in the DPL command object below:

The name of the filter object will be the name of that is used when referencing the object from inside the DPL script. Within the code, use the Get() command to obtain a set from the filter. For example, the code snippet below gets the results from the filter Lines and puts it into the set sLines: set sLines; ! Get the set of lines contained in the filter Lines ! The object Lines is the filter contained in the DPL command object sLines = Lines.Get();

DPL Tutorial (DIgSILENT Technical Documentation)

20

3

Basic DPL Scripting

3.1.4

By Code

The general approach for accessing network objects in DPL purely through code is as follows: 1. Get a set of the relevant network objects that you are looking for (using the AllRelevent command), based on a specific element type, e.g. lines, transformers, motors, etc 2. Get an object within this set either through filter commands (e.g. FirstFilt, NextFilt, etc) or by order commands (e.g. First, Next, etc) The code snippet below gets the set of all lines, cycles through each line object and prints out its full name: object aLine; set Lines;

! Get the set of all lines Lines = AllRelevant('∗.ElmLne', 1, 1);

! Cycle through the lines and print out the full name aLine = Lines.First(); while(aLine) { aLine.ShowFullName(); aLine = Lines.Next(); } The code snippet below gets the set of all objects, and tries to find the particular line called LineA5: object aLine; set AllObjs;

! Get the set of all objects AllObjs = AllRelevant();

! Get the line called LineA5 and print out its full name aLine = AllObjs.FirstFilt('LineA5.ElmLne'); aLine.ShowFullName();

The code snippet below gets the set of all objects, filters for all lines starting with LineA2, cycles through each line object in the filtered and prints out its full name. object aLine; set AllObjs;

! Get the set of all objects AllObjs = AllRelevant();

DPL Tutorial (DIgSILENT Technical Documentation)

21

3

Basic DPL Scripting

! Filter the set with all lines starting with LineA2 aLine = AllObjs.FirstFilt('LineA2*.ElmLne'); ! Go through filtered set and print out the full name of each object while(aLine) { aLine.ShowFullName(); aLine = AllObjs.NextFilt(); }

3.2

Identifying, Accessing and Modifying Object Parameters

Once a specific object has been selected, the way to access the object parameters or variables is by typing out the object name and the variable name separated by a colon (:), e.g. Object name:Variable name;

3.2.1

Identifying Variable Names for a Parameter

Most of the time it isn’t obvious what the variable name for a particular object parameter is. For example , suppose you want to access the power factor parameter in a static generator element - what is the variable name? Variable names can often be found in the manual and in the technical references, but the easiest way to identify variable names is to go into the relevant object and hover the mouse over the field of interest. A tooltip will appear with the corresponding variable name. For example, hovering over the power factor field in the static generator element yields the variable name: cosn:

DPL Tutorial (DIgSILENT Technical Documentation)

22

3

Basic DPL Scripting

3.2.2

Accessing Parameters

Suppose we have a line object oLine and we want to save the length of the line (variable name = dline) to an internal DPL variable dLength, this is how to do it: dLength = oLine:dline; An alternative method is to use the GetVal (variable, parameter, row, [column]) object method. This is particularly useful when the parameter is a matrix or a vector. By using the ':' method, only the value in the first row and column can be accessed. The previous example using GetVal is as follows: oLine.GetVal(dLength, 'dline', 0);

3.2.3

Modifying Parameters

Suppose we have a line object oLine and we want to change the length of the line (variable name = dline) to 2km, this is how to do it: oLine:dline = 2; An alternative method is to use the SetVal (value, parameter, row, [column]) object method. This is particularly useful when the parameter is a matrix or a vector. By using the ':' method, only the value in the first row and column can be accessed. The previous example using SetVal is as follows:

DPL Tutorial (DIgSILENT Technical Documentation)

23

3

Basic DPL Scripting

oLine.GetVal(2, 'dline', 0);

3.3

Creating New Objects

There are at least three ways to create new objects in the database: 1. Copy template object contained inside the script object 2. Copy external template object 3. Create new object from scratch in code

3.3.1

Copy from an Internal Template

Copying an interal template object is potentially the easiest option for creating new objects. The DPL command object can contain other objects within it. To see what’s inside a DPL object, click on the Contents button of the DPL command dialog box:

You can use an internal object inside the DPL command object as a template for the object type you want to create. In the figure above, an event (EvtShc) object call “SC Event” is placed inside the DPL command object and used as the template. Now to create the object, you can use the AddCopy(object name) command. In order to use this command, you must first locate the folder (or object) that you want to copy the template into. For example, suppose “oFold” is an object with the reference to the target folder and “SC Event” is the internal template object, a new object will be created in the target folder by the following: DPL Tutorial (DIgSILENT Technical Documentation)

24

3

Basic DPL Scripting

oFold.AddCopy(SC Event); The code snippet below copies an internal short circuit event template into the simulation events folder of the active study case and then changes the time of the copied event to t=1. object aPrj, oFold, oEvent; set EventSet; ! Get the simulation events folder in the active study case oFold = GetCaseObject('IntEvt'); oFold.ShowFullName(); ! Copy the template short circuit event into the events folder oFold.AddCopy(SC Event); ! Get the copied event and set the time to 1 EventSet = oFold.GetContents('∗.EvtShc'); oEvent = EventSet.First(); oEvent:time = 1;

3.3.2

Copy from an External Template

This is almost identical to copying an object from an internal template, except that an external object is referenced instead of using an object from inside the DPL command. In the DPL command dialog (under “Basic Options”), there is an area for referencing external objects:

To use this area, simply double-click on the object field and select an object you’d like to reference from pretty much anywhere in the project hierarchy. One distinction of this method is that you can give the object any name that you like (using the “Name” field). This is the name that DPL Tutorial (DIgSILENT Technical Documentation)

25

3

Basic DPL Scripting

the object will be called inside the DPL script. Once the external template object has been selected, you can use the AddCopy(object name) command to create a new object in the database. In order to use this command, you must first locate the folder (or object) that you want to copy the template into. For example, suppose “oFold” is an object with the reference to the target folder and “Trig” is the external template object, a new object will be created in the target folder by the following: oFold.AddCopy(Trig); Refer to the example given earlier in Section 3.3.1 for more details.

3.3.3

Create a New Object by Code

Creating new objects purely by code is the most intensive method for making new objects, because all of the object parameters need to be set in code. With template objects, you can set default parameters and even add child objects inside the template). But creating objects purely in code requires all of this to be done manually in the script. The CreateObject(class name, object name) function is used to create new objects. Like the previous two methods, you must first locate the folder (or object) that you want to create the object in. For example, suppose “oFold” is an object with the reference to the target folder and you want to create a short-circuit event object (∗.EvtShc) called “SC Event”, you would use the following command: oFold.CreateObject('EvtShc', 'SC Event'); Note that if the target folder (or object) does not accept the object class you are trying to create (e.g. a VI page object in the simulation events folder), then an error will be raised. The code snippet below creates a new short circuit event into the simulation events folder of the active study case and then sets the time of the event to t=1. object aPrj, oFold, oEvent; set EventSet; ! Get the simulation events folder in the active study case oFold = GetCaseObject('IntEvt'); oFold.ShowFullName(); ! Create short circuit event into the events folder oFold.CreateObject('EvtShc', 'SC Event'); ! Get the copied event and set the time to 1 EventSet = oFold.GetContents('∗.EvtShc'); oEvent = EventSet.First(); oEvent:time = 1;

3.4

Checking if a Project is Active

The function ActiveProject() returns NULL if there no project currently active. object aPrj;

DPL Tutorial (DIgSILENT Technical Documentation)

26

3

Basic DPL Scripting

! Check if there is an active project aPrj = ActiveProject(); if (aPrj=NULL) { Error('Please activate a project first'); exit(); }

3.5 3.5.1

Navigating Folders and Object Contents Project Folders

As an entry or starting point into the project folder hierarchy, use the GetProjectFolder(string) function. This function will return an object with a reference to the top level of project folders, e.g. the folders containing study cases, scripts, libraries, diagrams, etc. For example, the following line puts a reference to the equipment type library folder into object “oFold”: oFold = GetProjectFolder('equip'); A list of the project folders available and the corresponding string is shown below: String equip netmod oplib scen script study templ netdat dia scheme cbrat therm ra mvar outage fault

3.5.2

Folder Description Equipment type libary Network model Operational libary Operational scenario Script Study Case Template Network data Diagram Variation CB rating Thermal rating Running arrangement Mvar limits curve Outage Fault

Object Contents

The GetContents(string) function is a generic way of navigating through objects and finding the set of objects contained within them. The function returns a set of objects that meet the criteria in the string. Some examples: 1. Return all objects contained in oObj into the set Contents: Contents = oObj.GetContents(); DPL Tutorial (DIgSILENT Technical Documentation)

27

3

Basic DPL Scripting

2. Return ElmTerm type objects (terminals) contained in oObj into the set Contents Contents = oObj.GetContents('∗.ElmTerm'); 3. Return the specific object T2.ElmTerm contained in oObj into the set Contents: Contents = oObj.GetContents('T2.ElmTerm'); 4. Return all ElmTerm type objects that have names starting with T contained in oObj into the set Contents: Contents = oObj.GetContents('T∗.ElmTerm');

3.5.3

Objects in a Study Case

In order to access objects within the active study case (e.g. calculation command objects, simulation events, graphics boards, sets, outputs of results, title blocks, etc), you can use the function GetCaseObject(string). This function is essentially a shortcut to accessing objects inside a study case, which is used in lieu of navigating to the study case project folder, selecting a study case and then selecting an object. The other advantage of GetCaseObject() is that if the object doesn’t exist inside the study case, the function will create it. Note however that this function only works with the active study case. The code snippet below gets the graphics board object from the active study case. obj oDesk; oDesk = GetCaseObject('SetDesktop');

3.6

Accessing Study Cases

Study cases are IntCase objects that are stored in the study cases project folder. In order to access a study case, you must first access the study case folder. The code snippet below does the following: 1. Gets the set of all study cases 2. Counts the number of study cases 3. Activates each study case and prints its full name object aFold, aCase; set aCases; int iCases; ! Get the study cases folder and make a set of all study cases aFold = GetProjectFolder('study'); aCases = aFold.GetContents('∗.IntCase');

! Count the number of study cases iCases = aCases.Count(); if (iCases=0) { Error('There are no study cases in the current selection'); DPL Tutorial (DIgSILENT Technical Documentation)

28

3

Basic DPL Scripting

exit(); } printf('Number of cases:

%d', iCases);

! Cycle through all study cases ! Activate each study case and then print out the name of the study case aCase = aCases.First(); while (aCase) { ! Show name of calculation case aCase.ShowFullName(); aCase.Activate(); aCase = aCases.Next(); } Note that if there are subfolders within the study case folder, then further processing needs to be done to access the study case objects within these subfolders. Refer to Navigating Project Folders in section 3.5.

3.7

Executing Calculations

The GetCaseObject(string) can be used to get an existing or create a new calculation command object. The Execute() object function can then be used to execute the calculation. The following list of calculation command objects are available: ComLdf ComShc ComSim ComInc ComSimoutage ComRel3 ComMod ComHldf ComGenrelinc ComGenrel ComCapo ComVstab ComRed ComVsag ComCabsize ComTieopt ComSe ComFlickermeter

Load flow Short circuit Time domain (RMS or EMT) simulation Time domain initial conditions Contingency analysis Reliability assessment Modal analysis Harmonic load flow Initialise generation adequacy Run generation adequacy Optimal capacitor placement Load flow sensiivities Network reduction Voltage sag table assessment Cable reinforcement optimisation Tie open point optimisation State estimator Flickermeter

The code snippet below executes a load flow in the active study case: object ldf; ! Get load flow object from calculation case (or create it) ldf = GetCaseObject('ComLdf'); DPL Tutorial (DIgSILENT Technical Documentation)

29

3

Basic DPL Scripting

! Execute load flow calculation ldf.Execute();

3.8 3.8.1

Accessing Results Static Calculations (Load Flow, Short Circuit, etc)

The results of static calculations are stored as parameters in the objects themselves. Therefore, static results can be accessed in the same way object variables are accessed, e.g. Object name:Result variable name; For example, suppose you had a bus object Bus1 and you wanted to save the per-unit voltage to an internal DPL variable called dVoltage, you would type in this: dVoltage = Bus1:m:u; The simple example below runs a load flow for the active study case, gets all the lines and prints out the name and loading of each line (the reference to the line loading is shown below in bold). object ldf, aLine; set Lines; ! Run a load flow ldf = GetCaseObject('ComLdf'); ldf.Execute(); ! Get the set of all lines Lines = AllRelevant('ElmLne', 1, 1); aLine = Lines.First(); ! Go through each line, and show name and loading while (aLine) { printf('Loading for %s: %6f %%', aLine:loc name, aLine:c:loading); aLine = Lines.Next(); }

3.8.2

Dynamic Simulations

Unlike the static cases, the results of dynamic simulations are not stored as part of the object parameters, but in a separate results file. Refer to the section 5, Working with Results Files for more information.

3.9

Writing to the Output Window

DPL offers a few options for writing text to the output window, which are summarised below:

DPL Tutorial (DIgSILENT Technical Documentation)

30

3

Basic DPL Scripting

Function

Usage / Example

Print a formatted string to the output window

printf (string, [variables]) The printf function works in the same manner as the equivalent C/C++ function of the same name. Example a): printf('Hello world'); Prints the text “Hello World” in the output window in default black font. Example b): printf('Voltage = %f pu', dVoltage); For the float / double variable dVoltage = 1.03, this example prints the following in the output window: Voltage = 1.030000 pu Note that by default, PowerFactory prints 6 decimal places for floating point variables. To change the number of decimal places, use the decimal place specifier in the % tag. For example, for 3 decimal places:

Print a red error message

printf('Voltage = %.3f pu', dVoltage); Error (string, [variables]) Example: Error('Script failed!'); Prints the following message in the output window:

Print a brown warning message

DIgSI/err - Script failed! Warn (string, [variables]) Example: Warn('Script not initialised properly'); Prints the following message in the output window:

Print a green information message

DIgSI/wrng Script not initialised properly Info (string, [variables]) Example: Info('Script running iteration %d', i); Prints the following message in the output window (for i = 1):

Clear output window

DIgSI/info Script running iteration 1 ClearOutput() Example: ClearOutput(); Clears all text in the output window.

DPL Tutorial (DIgSILENT Technical Documentation)

31

3

Basic DPL Scripting

3.10

Plotting Results

Plots from dynamic (time-domain) or static simulations can be easily created using DPL.

3.10.1

Creating a New Virtual Instrument Page

You can create a new virtual instrument (VI) page using a graphics board object (∗.SetDesktop). The function GetPage (string name, int create) will create a new page provided the name doesn’t refer to an existing VI page and the create flag is activated (=1). For example, the snippet below uses the graphics board object oGrb to create a VI page called “Plots”: object oViPg; oViPg = oGrb.GetPage('Plots',1);

3.10.2

Creating a Virtual Instrument

Similar to creating a new VI page, you can use the VI page object (∗.SetVipage) to create a new virtual instrument with the function GetVI (string name, string class, int create). To create a new VI, the name should not be the same as another existing VI and the create flag should be activated (=1). The class of the VI is the type of VI that you want to create. If it is not entered, the class is set as a subplot (∗.VisPlot) by default. The classes for virtual instruments are shown in the table below: VI Class Name VisPlot VisPlot2 VisXyplot VisFft VisOcplot VisDraw VisPlotz VisEigen VisModbar VisModphasor VisVec VisHrm VisBdia VisPath VisVsag VisPdc VisDefcrv VisMeas VisBitmap VisSwitch VisButton

Description Subplot Subplot with two y-axes X-Y plot FFT plot Time-overcurrent plot R-X plot Time-distance plot Eigenvalue plot Mode bar plot Mode phasor plot Vector diagram Waveform plot Distortion plot Voltage profile plot Voltage sag plot Probability density plot Curve-input plot Measurement (scales, displays, etc) Picture box Button Command button

Table 3.2: Input/Output signals

DPL Tutorial (DIgSILENT Technical Documentation)

32

3

Basic DPL Scripting

For example, the snippet below uses the VI page object “oViPg” and creates a subplot type VI called “Subplot”: object oPlot; oPlot = oViPg.GetVI('Subplot','VisPlot',1);

3.10.3

Adding Objects and Variables to Plots

In order to show the actual plots on a VI, you need to add objects and variables to the VI. Using the VI object, use the AddVars function to add variables and objects to the plot. The function AddVars can be used in one of two ways: 1. AddVars (string V, object O1, ... O8) Here we want to add the variable V to objects O1 to O8 (i.e. variables can be added to up to 8 objects simultaneously). For example, the snippet below adds the variable 'm:u1' for the objects “oBus1” and “oBus2” to the VI object “oPlot” (oBus1 and oBus2 could be substation buses and we want to plot the voltage 'm:u1' on these buses): oPlot.AddVars('m:u1', oBus1, oBus2); 2. AddVars (string O, object V1, ... V8) Alternatively, we can add multiple variables V1 to V8 to a single object O (i.e. up to 8 variables can be added to an object simultaneously). For example, the snippet below adds the variables 'm:phiu' for the object “oBus” to the VI object “oPlot”: oPlot.AddVars(oBus, 'm:u1', 'm:phiu');

3.10.4

Plotting Example

The example below gets the current graphics board, creates a new VI page called “Plots”, creates a subplot, adds the variable “m:u” for the object “oBus” (which is defined elsewhere) and then adjusts the y-axis max and min settings: object oGrb, oViPg, oPlot; set Lines; ! Get current graphics board oGrb = GetGraphBoard(); if (oGrb=NULL) {exit(); } ! Create VI page oViPg = oGrb.GetPage('Plots',1); ! Create a new subplot oPlot = oViPg.GetVI('Subplot','VisPlot',1); ! Add variable 'm:u1' for object 'oBus' to the subplot ! Note that by default, the ‘‘All Calculations" results object is used oPlot.AddVars('m:u1', oBus); ! Adjust y-axis min and max settings oPlot:y max = 2; oPlot:y min = 0;

DPL Tutorial (DIgSILENT Technical Documentation)

33

4

Advanced DPL Scripting

For further details on manipulating Virtual Instrument panels in DPL, refer to the section 5, Working with Virtual Instrument Panels.

4 4.1

Advanced DPL Scripting DPL Sub-Scripts (or Subroutines)

DPL scripts are able to call other DPL scripts that are contained inside the DPL command object. For example, the DPL command object in the figure below (max dpl vector ) contains another DPL script called sub max vector. This script (sub max vector ) is referred to as a sub-script or a subroutine and can be executed from inside the parent script (max dpl vector ).

The use of sub-scripts is quite straightforward and will be described briefly in this section.

4.1.1

Executing Sub-Scripts

To execute a sub-script, simply call the sub-script object in the code and use the Execute() method: sub script.Execute(); DPL Tutorial (DIgSILENT Technical Documentation)

34

4

Advanced DPL Scripting

For example, to execute the sub-script sub max vector in the figure above: sub max vector.Execute();

4.1.2

Passing Arguments to Sub-Scripts

Sub-scripts may have input parameters that need to be initialised or adjusted before execution. Consider the script calc power below, which has two input parameters P and Q.

There are two general approaches for passing arguments to a sub-script within DPL: 1. Explicit Approach The sub-script is treated as an object and the object parameters are changed directly inside the object. For example, to change the parameters P and Q in the sub-script calc power above: calc power:P = 4; calc power:Q = 3; 2. Implicit Approach Alternatively, the arguments can be passed implicitly as part of the Execute(arguments) method, where the arguments appear in the same order as the input parameters. For example, to pass P=4 and Q=3 into the sub-script calc power above: calc power.Execute(4,3);

DPL Tutorial (DIgSILENT Technical Documentation)

35

4

Advanced DPL Scripting

4.1.3

Accessing Sub-Script Results

A sub-script may simply execute some actions (e.g. activating study cases, changing model parameters, etc), but sub-scripts may also produce results as either variables or objects. These results are defined as parameters in the Advanced Options tab of the DPL command object. Consider the results parameter S defined in the script calc power below:

Once the script is executed, the result parameter S is stored in the script object and can be accessed like any other object parameter, e.g. double app power; app power = calc power:S; This is the explicit approach to accessing results from a sub-script object. However, like passing arguments to a sub-script, there is also an implicit approach using the Execute (arguments, results) method. In the implicit approach, the execute command is used firstly with the sub-script arguments (input parameters in the order that they are presented in the DPL command object) and then with the variables to store the results. This is best illustrated by example. In the snippet below, we pass the input arguments P=4 and Q=3 and then store the results in the variable app power (of type double): double app power; calc power.Execute(4,3,app power);

DPL Tutorial (DIgSILENT Technical Documentation)

36

4

Advanced DPL Scripting

4.2

Vectors, Maps and Matrices

Vectors, maps and matrices can be created and manipulated in one of four types: • • • •

IntVec: IntDplvector: IntMat: IntDplmap:

4.2.1

a vector of decimal numbers (of type double) a vector of objects, sets, integers, strings or decimal numbers a matrix of decimal numbers (of type double) a vector of objects, sets, integers, strings or decimal numbers mapped to key values

Vectors

There are two types of vectors that can be used in PowerFactory : IntVec and IntDplvector. IntVec is used to describe arrays of decimal numbers. IntDplvector is a more general purpose vector that can describe an array / container of objects, sets, strings or numbers:

The other key differences between the two vector types are as follows: • IntVec objects can be edited manually in the data manager, whereas IntDplvecotr objects can only be manipulated within a DPL script. • The first item in IntVec objects is at index “1”, while in IntDplvector objects, it is at index “0” • IntDplVector objects have no resizing functionality, and the vector size grows (or shrinks) organically with item insertions and removals. • IntDplVector objects have a reverse lookup feature, i.e. one can find the index number of a vector item • IntDplVector objects are sortable. Note that the values in an IntDplvector must have the same type. The first value inserted into the IntDplvector determines the type. For example, if you insert an object, then all other values in the vector must also be of type object. The functions and usage of IntVec and IntDplVector objects are shown in the table below: Function

IntVec

IntDplVector

Initialise a vector

Init(n)

Clear()

Example: Vec.Init(5)

Example: DplVec.Clear()

Initialises a vector with 5 items and sets all item values to “0”

Empties the vector of all items. The size of the vector is null / 0.

DPL Tutorial (DIgSILENT Technical Documentation)

37

4

Advanced DPL Scripting

Function Get value at index “i”

Set value at index “i”

Resize vector to size “n”

IntVec Get (i)

IntDplVector Get (i)

Example: x = Vec.Get(1)

Example: x = Vec.Get(0)

Get the value of the first item and put it into variable x. Set (i, value)

Get the value of the first item and put it into variable x.

Insert (i, item)

Example: Vec.Set(3, 2.5)

Example: Vec.Insert(1,oBus)

Sets the value “2.5” into the vector at index “3” Resize (n)

Puts the object “oBus” into the vector at index “1” N/A

Example: Vec.Resize(3)

Get number of items in vector

Resizes the vector to 3 items. All additional items are set to '0'. Size() Example: x = Vec.Size()

Add item to the end of a vector

Gets the number of items in the vector and puts it into variable x. N/A

Size() Example: x = Vec.Size() Gets the number of items in the vector and puts it into variable x.

Insert (item) Example: DplVec.Clear()

Remove item at index “i”

N/A

Adds the object “oBus” to the end of the vector. This increases the size of the vector by 1. Remove (i) Example: Vec.Remove(3) Removes the item at index 3. This reduces the size of the vector by 1.

DPL Tutorial (DIgSILENT Technical Documentation)

38

4

Advanced DPL Scripting

Function Find the index of item “x” in the vector (reverse lookup)

IntVec N/A

IntDplVector IndexOf (x) Example: i = Vec.IndexOf(x)

Sort items in vector

N/A

Returns the index of item “x” and puts it into (integer) variable i. The function returns “-1” if no match is found. Sort (order, attribute) Example: a) Vec.Sort(1) Sorts a vector (e.g. of numbers) in ascending order Example: b) Vec.Sort(0,'uknom') Sorts a vector (e.g. of terminal objects) in descending order according to their nominal voltages (uknom). Refer to the DPL reference in the PowerFactory manual for more details.

4.2.2

Maps

DPL map objects (IntDplmap) are so-called associative arrays, which are essentially arrays of key - value pairs. For example, consider the DPL map shown below:

In the example above, there are five key-value pairs, e.g. “12, oBus1”, “8, oGen2”, etc. Thus for the key-value pair “9, oGen3”, the key “9” corresponds to the value “oGen3”. We can say that we’ve mapped the key “9” to the object “oGen3”. In DPL map objects, the keys can be represented by numbers, strings, objects or sets. In the example above, all of the keys are shown as integer numbers, while their corresponding paired values are objects. Note that the keys and values must have homogenous types. The first keyvalue pair inserted into the map determines the types for the keys and values. For example, if you insert an object key and a set value, then all other keys-value pairs must be of type object and set. DPL Tutorial (DIgSILENT Technical Documentation)

39

4

Advanced DPL Scripting

The functions and usage of DPL map objects are shown in the table below: Function

IntDplmap

Initialise a DPL map

Clear() Example: Map.Clear()

Get value associated with key “x”

Empties the DPL map of all items. The size of the map is null / 0. GetValue (x) Example: oVal = Map.GetValue(x)

Get number of key-value pairs in DPL map

Gets the value associated with the key “x” and puts it into the object variable “oVal”. Size() Example: i = Map.Size()

Add or modify a key-value pair

Gets the number of key-value pairs and puts it into variable “i” Insert (key, value) Example: Map.Insert(x, oBus)

Remove a key-value pair

Adds a new key-value pair “x, oBus” if the key “x” does not already exist. Otherwise, it sets the value “oBus” to the existing key “x”. Remove (key) Example: Map.Remove(x)

Check if key “x” exists in the DPL map

Removes the key-value pair with key “x”. This will reduce the size of the DPL map by 1. Contains() Example: iBool = Map.Contains(x)

Get the first key-value pair in the DPL map

Checks if the map contains the key “x” and returns the result to variable “iBool” (returns “1” of the key exists in the map, and “0” otherwise) First (key, value) Example: iBool = Map.First(x, oVal) Gets the first key-value pair in the DPL map and puts the key into variable “x” and value into variable “oVal”. Returns the status of the operation into variable “iBool” (returns “0”: if the operation is successful, and “1” if there is an error, e.g. if the DPL map is empty)

DPL Tutorial (DIgSILENT Technical Documentation)

40

4

Advanced DPL Scripting

Function Get the next key=value pair in the DPL map

IntDplmap Next (key, value) Example: iBool = Map.Next(x, oVal) Gets the next key-value pair in the DPL map (relative to the last pair) and puts the key into variable “x” and value into variable “oVal”. Returns the status of the operation into variable “iBool” (returns “0”: if the operation is successful, and “1” if there is an error, e.g. there are no more key-value pairs)

4.2.3

Matrices

Matrix objects (IntMat) are two dimensional matrices of decimal numbers. The functions and usage of matrix objects are shown in the table below: Function

IntMat

Initialise a matrix

Init (rows, columns, init val) Example: Mat.Init(3,4,2)

Get the rows and columns of a matrix

Initialises a 3 x 4 matrix and initialises all elements to the value “2” NRow() / NCol() Example: iRow = Mat.NRow()

Resize a matrix

Gets the number of rows in the matrix and puts it in variable “iRow” Resize (rows, columns, init val) Example: Mat.Resize(5,5)

Get the value at row “x” and column “y”

Resizes to a 5 x 5 matrix. As init val is not set, all additional elements are initialised to 0. Get (x, y) Example: dVal = Mat.Get(2,3)

Set the value at row “x” and column “y”

Gets the value stored in the 2nd row and 3rd column and puts it into the variable “dVal” Set (x, y, value) Example: Mat.Set(3,2,10)

Read the labels of rows and columns in a matrix

Sets the value in the 3rd row and 2nd column to 10. RowLbl (row) / ColLbl (column) Example: sLabel = Mat.RowLbl(1) Gets the label of the 1st row and puts it into the (string) variable “sLabel”

DPL Tutorial (DIgSILENT Technical Documentation)

41

4

Advanced DPL Scripting

Function Set the labels of rows and columns in a matrix

IntMat RowLbl (label, row) / ColLbl (label, column) Example: Mat.ColLbl('busbars', 2)

Multiply two matrices

Sets the label of the 2nd column to “busbars” Multiply (Mat A, Mat B) Example: iBool = Mat.Multiply(A, B)

Invert a matrix

Multiplies the matrices A and B, and stores the result into itself (i.e. matrix “Mat”). Returns the status of the operation into variable “iBool” (returns “0”: if the operation is successful, and “1” if there is an error, e.g. multiplication not possible and matrix “Mat” is left unchanged) Invert() Example: iBool = Mat.Invert()

Sort a matrix alphanumerically according to column

Inverts the matrix and then stores the result into itself (i.e. matrix “Mat”). Returns the status of the operation into variable “iBool” (returns “0”: if the operation is successful, and “1” if there is an error, e.g. inversion not possible and matrix “Mat” is left unchanged) SortToColumn (column) Example: iBool = Mat.SortToColumn(2) Sorts the matrix alphanumerically according to column “2”. Returns the status of the operation into variable “iBool” (returns “0”: if the operation is successful, and “1” if there is an error, e.g. column doesn’t exist)

4.3

Topological Search

It is sometimes useful to be able to navigate topologically through a network and search for elements using DPL. For example, suppose you wanted to get the set of transformers connected to a bus, or you wanted to follow a branch circuit through lines and transformers to its end point. PowerFactory has a number of DPL functions that can help in this task. Some of the useful topological search functions are outlined in the table below: Function

Usage / Example

Object Funtions

DPL Tutorial (DIgSILENT Technical Documentation)

42

4

Advanced DPL Scripting

Function Get a set of the elements connected to an object

Usage / Example GetConnectedElms (breakers, disconnectors, out of service) Example a): setObj = oTerm.GetConnectedElms(1,1,0) Gets all of elements connected to “oTerm” and puts it into the set “setObj”, taking into account the state of breakers and switch-disconnectors, but disregarding out of service flags. Example b): setObj = oTerm.GetConnectedElms() By default, the options are set to (0, 0, 0). Therefore, this gets the set of all elements connected to “oTerm”, irrespective of breaker / switch operating states and out of service flags. Important Note: when using this function to find connected terminals, one must be careful about the use of the “internal node” option in terminals.

Get the terminal / node connected to an object

When this option is set, then GetConnectedElms() will ignore this terminal. This is to avoid returning the interior nodes of a substation, and instead returning the main busbar. GetNode (bus no = 0 or 1, switch state = 0 or 1 Example a): GetNode (bus no = 0 or 1, switch state = 0 or 1) Gets the terminal connected to bus “0” of line object “oLine”, taking into account the switch states, and puts the terminal into object “oTerm” Example b): oTerm = oLine.GetNode(1)

Get the cubicle connected to an object

By default, the switch state setting is “0”, so the above snippet gets the terminal connected to bus “1” of line object “oLine”, ignoring switch states. GetCubicle (index) Example: oLine.GetCubicle(1)

Get the number of connections / cubicles connected to an object

Gets the cubicle with index “1” at line object “oLine” and puts it into the object “oCub”. Returns NULL if the cubicle doesn’t exist. GetConnectionCount() Example: i = oLine.GetConnectionCount() Gets the number of connections or cubicles connected to line object “oLine” and puts it into the variable “i”

DPL Tutorial (DIgSILENT Technical Documentation)

43

4

Advanced DPL Scripting

Function Check if an object is of a certain class (useful when filtering for certain types of objects)

Usage / Example IsClass() Example: iBool = obj.IsClass('ElmLne') Checks if the object “obj” is a line (i.e. of class “ElmLne”) and stores the result in variable “iBool”. Returns “1” if the result is true, and “0” otherwise.

Cubicle Functions Get the set of all network elements downstream / upstream of a cubicle

GetAll (direction = 0 (branch) or 1 (terminal), switch state = 0 or 1) Example a): setObj = oCub.GetAll(1, 1) Gets the set of all network elements starting from cubicle “oCub” in the direction of the branch, and taking into account switch states (i.e. it will stop at an open switch). Example b): setObj = oCub.GetAll(0, 0) Gets the set of all network elements starting from cubicle “oCub” in the direction of the terminal, ignoring switch states. Example c): setObj = oCub.GetAll() Without setting any of the options, the above snippet is equivalent to calling oCub.GetAll(1, 0), i.e. traversal in the direction of the branch ignoring switch states.

Terminal Functions Get the next busbar (at a higher nominal voltage level) connected to the terminal

GetNextHVBus() Example: oTerm.GetNextHVBus() Gets the next bus with a higher voltage relative to terminal “oTerm” and returns the result to object “oBus”. If no bus is found, then null is returned.

4.4 4.4.1

Reading from and Writing to External Files Standard File I/O Methods

The standard file I/O methods in DPL are similar to those found in the standard C/C++ library: Function

Usage / Example

Open a file

fopen (path / filename, mode, file number, [return value]) Opens a file and assigns it to a file number (up to 10 files can be opened simultaneously). The path name must exist on the disk. The mode is how the file should be accessed, e.g. 'r'= read only (filename must exist) 'w'= create new file (if the filename exists, the existing file is wiped)

DPL Tutorial (DIgSILENT Technical Documentation)

44

4

Advanced DPL Scripting

Function

Write a formatted string to a file

Set the carriage return

Read strings from a file

Usage / Example 'a'= append (filename must exist, and updates are written to the end of file) If return value is set to 1, then the function will return 1 if the file open operation was successful and 0 if not. Example a): fopen('c:\temp\results.txt', 'r', 0) Opens file 'results.txt' as read only and assign it to file number 0. Example b): iResult = fopen('c:\temp\results.txt', 'w', 1) Creates new file 'results.txt' and returns 1 to integer variable 'iResult'if operation is successful (and 0 if not) fprintf (file number, string, [variables]) Similar to the printf function, but writes to a file instead of the output window. Example: fprintf(0,'Voltage = %f pu', dVoltage); For the float / double variable dVoltage = 1.03, this example writes the following to file number 0: Voltage = 1.030000 pu SetLineFeed (i) Set or reset the automatic line carriage return (i=0 'off' ; i=1 'on') Example a) Automatic carriage return enabled: SetLineFeed(1); fprintf(0, 'ABCD'); fprintf(0, 'EFGH'); Writes the following to file number 0: ABCD EFGH Example b) Automatic carriage return disabled: SetLineFeed(0); fprintf(0, 'ABCD'); fprintf(0, 'EFGH'); Writes the following to file number 0: ABCDEFGH int fscanf (file number, format, [variables]) Reads formatted strings from a file separated by a space or tab. The strings can be converted into other variable types. The function stores the current position in the file so that repeated function calls will continue through the file. Returns 0 if no value is assigned to a variable, and -1 if the end of line is reached or there is an error. Otherwise, returns the number of values assigned to variables. Example a): iRet = fscanf(0, '%f %s', dVal, sVal); Reads the next two values of file number 0 and stores the first as a double in variable dVal and the second value as a string in variable sVal. Returns result of operation to variable iRet. int fscanfsep (file number, format, [variables], separator, line) Same as fscanf except that a separator character can be defined, and there is an option to stop after the end of the line. Example a): iRet = fscanfsep(0, '%f %s', dVal, sVal, ';', 0); Same as example a, except that values are separated by semi-colons ';'.

DPL Tutorial (DIgSILENT Technical Documentation)

45

4

Advanced DPL Scripting

Function Save contents of file buffer

Close a file

Usage / Example fflush (file number) For performance purposes, file operations such as fprintf are first stored in a memory buffer and then periodically transferred to disk. The fflush routine forces the file buffer to be saved onto disk. fclose (file number) Closes the file with the specified file number.

4.4.2

Exporting WMF Graphic Files

The function WriteWMF(filename) can be used to export the active graphics page to a graphic file in Windows Metafile (WMF) format. The function can only be used with a graphics board object (∗.SetDesktop), so a relevant graphics board object needs to be retrieved before exporting to a WMF. The example below gets the first graphics board in the active study case and exports the active VI page to the path / file 'c:\temp\results1.wmf': obj oDesk; oDesk = GetCaseObject('SetDesktop'); oDesk.WriteWMF('C:\temp\results1');

4.5

Fast Fourier Transforms (FFT)

A Fast Fourier Transform (FFT) can be executed on the results of a time domain simulation using the FFT Calculation object (ComFft):

DPL Tutorial (DIgSILENT Technical Documentation)

46

4

Advanced DPL Scripting

To execute an FFT in DPL, the easiest approach is to manually create the FFT Calculation object inside the DPL command object with the relevant settings pre-defined. The following steps should then be followed to set up the result files, run the FFT and accessing the results.

4.5.1

Specifying Input and Output Results Files

The FFT calculation object requires a time domain simulation results file (ElmRes) and the FFT calculation output is stored in another results file. These input and output results files need to be specified. In the DPL script, these can be specified by using the FFT calculation object variables pRes in and pRes out. For example, given the FFT calculation object FFT Calculation: ! Input results file ‘‘EMT Calc" FFT Calculation:pRes in = EMT Calc; ! Output results file ‘‘FFT Results" FFT Calculation:pRes out = EMT Calc;

4.5.2

Executing the FFT Calculation

To execute the FFT calculation, simply use the Execute() method of the FFT calculation object: FFT Calculation.Execute();

DPL Tutorial (DIgSILENT Technical Documentation)

47

5

Working with Results Files

4.5.3

Accessing the FFT Results

The FFT results are stored in the output results file that was specified earlier in the FFT calculation object. In order to access these results, the same process for accessing results files described in Section 5 should be used. A summary specific to FFT calculations is presented below: First, the results file needs to be loaded into memory using the LoadResData() function, e.g.: LoadResData(FFT Results); Next, we need to find the column numbers of the objects and variables of interest in the results file. FFT results objects have the following variables: FFT Variable FFT mag() FFT phi() FFT re() FFT im() FFT HD() FFT PSD()

Description FFT magnitude FFT angle (deg) FFT real part FFT imaginary part Harmonic distortion (%) PSD (*/Hz)

The brackets () represent the network object variable that the FFT is being calculated on. For example, suppose we have a transformer object and we run an FFT on the transformer primary current on phase A (m:i:bushv:A). Then to get the FFT magnitude, we need to reference the variable: FFT mag(m:i:bushv:A To find the column number, we use the ResIndex() function. For example, to get the column number for the FFT of the transformer primary current in the example above (given the transformer object oTrans): int iCol mag; iCol mag = ResIndex(FFT Results, oTrans, 'FFT mag(m:I:busac:A)'); Finally, to access the actual FFT results data, the GetResData() function can be used, using the column numbers for the variables of interest that we found earlier. For example, to get the magnitude data for row 3 of the results file FFT Results and store it into the variable dMag: double dMag; GetResData(dMag, FFT Results, 3, iColMag); For more detailed information on working with results files, refer to Section 5 of this document.

5

Working with Results Files

Suppose you want to get a PowerFactory Results file (of type ElmRes) from a dynamic simulation, peer into it, pull out a set of relevant values, perform some calculations on the data and generate some outputs. How do you do that? This section describes how to use a DPL script to manipulate Results files from dynamic simulations.

DPL Tutorial (DIgSILENT Technical Documentation)

48

5

Working with Results Files

5.1

Adding Results Files to the DPL Script

The easiest way to work with a results file is to save it into the DPL script command object. For example, you can drag and drop an All Calculations results file into your script. Note that the name of the results file needs to be changed to eliminate spaces, e.g. in the screenshot below, All Calculations has been renamed to All calcs.

Once it has been dragged into the script, the Results file can be called inside the DPL script like an object variable that has already been defined. All object methods and functions are exposed.

5.2

Structure of Results Files

In order to manipulate the data in a Results file, it is important to understand the structure of the file and how data is stored inside it. The results file is structured as a 2d matrix as shown in the figure below.

The number of rows represents the total number of time intervals for the simulation. For examDPL Tutorial (DIgSILENT Technical Documentation)

49

5

Working with Results Files

ple, if there is 10s of simulation with a time interval of 0.01s, then there would be 1,000 rows. Each row represents a time interval. Column 1 in the Results file is the time of the simulation. Columns 2 onward represent the objects (shown in the diagram as object 1 to object n) and their respective variables (shown in the diagram as var[ 1] to var[ k]). An object can be any PowerFactory object (e.g. a line, motor, terminal, load, etc) and a variable is any element defined in a variable set for the specific object that is to be measured during the simulation (e.g. m:u1, s:speed, etc) Note that in the diagram above, each object has k variables, but this is not necessarily the case in practice as each object can be defined with an arbitrary number of variables in the set. It is important to know that accessing data from a specific object and variable in the Results file hinges on knowing the relevant column index. Similarly, accessing data for a particular time requires the row number for the relevant time interval.

5.3

Loading a Results File into Memory

Adding a Results file to a DPL script does not enable access to the data contained within it. You must first load the results file into memory using the command: void LoadResData(ResultsFile); LoadResData loads the contents of a Results file into memory and allows you to begin accessing the data. You can only load one Result file into memory at any one time.

5.4

Getting the Relevant Column Number

In order to access the object and variable of interest, you need to know the right column number in the Results file. To do this, use the following command to search for the relevant column number: int ResIndex(ResultsFile, object, 'var name'); ResIndex returns an integer, which is the column number for the object and variable you’ve searched for. Object is the specific PowerFactory object of interest (which can be defined explicitly or by a general selection). var name is the variable of interest (e.g. m:u1, s:speed, etc).

5.5

Getting Data from the Results File

Once you know the relevant column index (object / variable) and row index (time), you can start getting data from the Results file. Data points can only be accessed one at a time (i.e. you can’t get a vector of data from the Results file). Use the following command to get a data point: void GetResData(output, ResultsFile, row index, column index); The row and column indices are integers. Output is a variable where the data from the Results file is stored. It must be a variable that has been already defined.

DPL Tutorial (DIgSILENT Technical Documentation)

50

5

Working with Results Files

5.6

Getting the Time Interval Data

Similar to getting data from the Results file, the time interval data (e.g. t=0s, t=0.5s, etc) can be accessed using GetResData, but without inputting the column index, i.e.: void GetResData(output, ResultsFile, row index); where Output is the variable to store the time interval data.

5.7

Finding the Number of Time Intervals

To find the number of time intervals in the simulation (i.e. number of rows), use the command: int ResNval(ResultsFile, ColumnNo); The ResNVal function returns an integer with the number of time intervals for a specific column. Using ColumnNo = 0 gives the total number of rows.

5.8

A Simple Example

This example opens a Results file, selects the first object from the general selection and prints out the voltage at each time interval in the output window. Note that in the example below, All calcs is the name of the Results file that has been added into the DPL script. ! Define and initialise variables object oSet; int N, i, i1; double dt, du; set S; i = 1;

! From all objects in the general selection, get the first object S = SEL.All(); oSet = S.First();

! Load the Results file ‘‘All calcs" into memory LoadResData(All calcs);

! Return the number of rows (i.e. N = ResNval(All calcs,0);

time intervals)

! Get the column index for the voltage 'm:u1' for the selected ! object i1 = ResIndex(All calcs, oSet, 'm:u1');

! Loop through each row and output the time and voltage while (i1) { printf('t = %f s; u = %f', dt, du); } i = i + 1; }

6 6.1

Working with Virtual Instrument Panels Introduction

Virtual instrument (VI) panels are contained in SetVipage objects within a graphics board, and are used to visualise the results of dynamic simulations for relevant variables of interest. This document provides some detailed instructions on manipulating virtual instrument panel objects using the DPL scripting language. Firstly some general definitions for the objects related to virtual instrument panels: • • •

6.2

Graphics Board VI Panel Visplots

–is the container for all graphics, including the VI panels –is the name of the whole virtual instrument page (∗.SetVIpage) –are the individual plots inside a VI panel (∗.VisPlot)

Local Title Blocks

Title blocks are SetTitm objects that can be attached to VI graphical objects. The title blocks provide drawing information, revision numbers, dates and logos, and is therefore primarily used for printouts of VI graphics. One can manipulate the data in title blocks using DPL, which makes automation possible for a large number of similarly themed drawings.

DPL Tutorial (DIgSILENT Technical Documentation)

52

6

Working with Virtual Instrument Panels

6.2.1

Creating Local Title Blocks Manually

By default, a global title block is applied to each VI panel with common title block information (but with different page numbers). But sometimes you may want to have different title block information for each VI page. Local title blocks can be created with information specific to the individual VI panel. You can create local title blocks manually by right-clicking on the default title block and selected Create local Title from the context menu (see screenshot below).

6.2.2

Creating Local Title Blocks in DPL

Creating local title blocks manually can be tedious if you have to do it for many VI panels. A faster way is to use a DPL script. However there isn’t an easy direct way to create local title block objects via a DPL script. Instead, the simplest way is to copy a template title block into a VI panel object. Firstly, find the template title block and add it as an external object to the DPL command object. The template title block can be any title block in the graphics board. In the example below, the default global title block for the graphics board is used as the template (which can be found in the main graphics board object).

Next, get the VI panel object (∗.SetVipage) and use the general object method AddCopy to copy the title block template into the object. This creates a local title block for the VI panel. You can now fill in the title block information by getting the title block object (∗.SetTitm) and DPL Tutorial (DIgSILENT Technical Documentation)

53

6

Working with Virtual Instrument Panels

accessing its variables. For example, if the title block object is oTitle, then you can change the annex, title 1 and title 2 by accessing the variables oTitle:annex, oTitle:sub1z and oTitle:sub2z respectively. The variable names for each title block field is shown below:

6.2.3

Title Block DPL Script Example

This DPL script gets the first graphics board and cycles through each VI panel. The script then checks to see if it has a local title block and adds one if it doesn’t. Lastly, the script fills in the title block information. In this example, the object CopyTemplate is the title block template that has been added as an external object. object oCase,oTitle,GrBrd,Pg; set allDesks,allTitms,Pgs; string strStation, strVIpage; int n;

! Get the first graphics board oCase = ActiveCase(); allDesks = oCase.GetContents('∗.SetDesktop'); GrBrd = allDesks.First(); if (GrBrd) {

! Get a set of all VI panels Pgs = GrBrd.GetContents('∗.SetVipage'); Pgs.SortToVar(0,'order'); Pg = Pgs.First();

!

Go through each VI panel

DPL Tutorial (DIgSILENT Technical Documentation)

54

6

Working with Virtual Instrument Panels

while (Pg) { printf('Name of object:

%s', Pg.GetFullName());

! Get the first local title block allTitms = Pg.GetContents('∗.SetTitm'); oTitle = allTitms.First();

! If no local title block for VI panel exists, create one if (.not. oTitle) {

printf('No local title block exists... Creating local title block...'); Pg.AddCopy(CopyTemplate); allTitms = Pg.GetContents('∗.SetTitm'); oTitle = allTitms.First(); }

! ! ! ! !

Fill in Annex = Title 1 Title 2 where X

title block with the following information: ‘‘1" = ‘‘Motor Re-Acceleration Simulation" = ‘‘Voltage Profile for Station X" is the name of the VI panel

oTitle:anex = '1'; oTitle:sub1z = sprintf('Motor Re-Acceleration Simulation'); strVIpage = Pg:loc name; oTitle:sub2z = sprintf('Voltage Profile Station %s', strVIpage);

Pg = Pgs.Next(); } } Note: Objects cannot be copied into a VI panel object while the graphic is open. Therefore, close the graphics board prior to executing any DPL scripts that will manipulate title block objects.

6.3

Constants in Visplots

Horizontal and vertical constants in Visplots are contained in VisXvalue and VisYvalue objects respectively. There is no easy direct way to create these objects. It is easier to copy and paste a template object rather than creating a new object from scratch and setting up the attributes to be a VisXvalue or VisYvalue object.

DPL Tutorial (DIgSILENT Technical Documentation)

55

6

Working with Virtual Instrument Panels

6.3.1

Constants DPL Script Example

This DPL script gets the first VI panel and cycles through all the VIsplots in the panel. In each Visplot, it changes the colour of the first constant to red (color 2) and adds two more constants. object oCase,oPlot,oConstant,GrBrd,Pg; set allDesks,allPlots,allConstants,Pgs; int n;

! Get graphics board oCase = ActiveCase(); allDesks = oCase.GetContents('∗.SetDesktop'); GrBrd = allDesks.First();

if (GrBrd) { ! Get all VI panels Pgs = GrBrd.GetContents('∗.SetVipage'); Pgs.SortToVar(0,'order'); Pg = Pgs.First();

! Get the set of all Visplots in VI panel allPlots = Pg.GetContents('∗.VisPlot'); oPlot = allPlots.First();

!

Cycle through each Visplot

while (oPlot) { ! Change colour of first constant to red allConstants = oPlot.GetContents('∗.VisXvalue'); oConstant = allConstants.First(); oConstant:color = 2;

! Add two more constants to each plot oPlot.AddCopy(CopyTemplate1); oPlot.AddCopy(CopyTemplate2);

} }

6.4

Exporting VI Panels to WMF

Often you will want to send VI panels as a picture file or insert it into a report. Obviously, you could do this manually using the export command (i.e. to a WMF or a BMP):

DPL Tutorial (DIgSILENT Technical Documentation)

56

6

Working with Virtual Instrument Panels

But this can be a tedious task if there are many VI panels to export. A quicker alternative is to use a DPL script to bulk export VI panels or any other type of graphic (this was covered briefly in Section 4.4.2). The general process is as follows: 1. Locate the relevant graphics board 2. Select the VI panels or graphic objects that you want to export 3. Export the VI panel with the WriteWMF function The following example gets the first graphic board in the active study case and exports all of the VI panels in the graphics board as File1.wmf, File2.wmf, File3.wmf, etc in the directory strPath (a variable defined in the DPL command object): obj oDesk, oVIpg; set allVis; string strFilename; int i, j; i = 0;

! Get the graphics board in the active study case oDesk = GetCaseObject('SetDesktop');

! Get the set of all VI panels and cycle through each VI panel allVis = oDesk.GetContents('∗.SetVipage'); for(oVIpg = allVis.First(); oVIpg; oVIpg = allVis.Next()) {

! Show the VI panel onscreen oDesk.Show(oVIpg);

! Formulate the filename for the WMF file i = i + 1; strFilename = sprintf('%s\\File%d',strPath,i);

! Export the current VI panel to a WMF ! If successful, output a message saying that a file is created

DPL Tutorial (DIgSILENT Technical Documentation)

57

7

Working with Graphical Objects

j = oDesk.WriteWMF(FileName); if (j = 1) { printf('File created:

%s', strFilename);

} } Alternatively, in lieu of getting the graphics board and getting a set of the VI pages, you could use a set of the graphical objects that you want to export, e.g.

7 7.1

Working with Graphical Objects Graphical Objects in PowerFactory

On single line diagrams, graphical representations of network elements, text objects and other graphics (e.g. rectangles, circles, etc) are stored Graphical Net Objects (∗.IntGrf) inside diagram graphics (∗.IntGrfnet), which are in turn located in the Network Model / Diagrams subfolder. The figure below presents the contents of diagram graphic Grid, showing a number of graphical net objects stored inside the diagram:

If we were to edit a Graphical Net Object (GNO), we would see the following:

DPL Tutorial (DIgSILENT Technical Documentation)

58

7

Working with Graphical Objects

The Net Data Object field (variable name 'pDataObj') highlighted in red indicates that this GNO is associated with grid element L3, which simply means that this is a graphical representation of a network element. There can be more than one graphical representation of the same object across many diagrams, though not in a single diagram. When the GNO does not represent a grid element (e.g. it is just a rectangle, circle, etc), the Net Data Object field is blank. The Symbol Name field (variable name 'pSymNam') defines the graphical symbol for this GNO, in this case a load symbol. The X-Position and Y-Position fields (variable names 'rCenterX' and 'rCenterY' respectively) specifies the (x,y) coordinates in the diagram where the symbol should be drawn (centre points). There is also another type of graphical object that defines the connections between two objects (e.g. a load connected to a bus). This object is called a Graphical Connection Object (∗.IntGrfcon) and can typically be found inside a GNO:

Editing the first Graphical Connection Object (GCO), we get the dialog box on the following page:

DPL Tutorial (DIgSILENT Technical Documentation)

59

7

Working with Graphical Objects

The GCO specifies the (x, y) coordinates for straight-line connections between the GNO (e.g. a load) and its connected element (e.g. a bus). In the example above, the GCO shows a simple vertical connection with endpoint (x, y) coordinates (192.5, 96.25) and (192.5, 109.375). By adding another row, we can make this into an L-shaped connection, i.e.:

By adding more coordinates, it is possible to create connections of arbitrary shapes. This brief background was intended to describe the nature of graphical objects and how they are used in PowerFactory . By understanding the concepts of GNOs and GCOs, we can start using DPL to manipulate graphical objects.

7.2

Finding a Graphical Representation of a Network Element

Sometimes it is necessary to find the graphical net object (GNO) in a diagram that is associated with a specific network element. There is no in-built method that will achieve this and finding a GNO for a specific object has to be done using a loop.

DPL Tutorial (DIgSILENT Technical Documentation)

60

7

Working with Graphical Objects

The following code snippet tries to find the GNO associated with the object 'oObj' inside the diagram object 'oDiagram': set sObj; object oGrf

!

Get all graphical net objects in diagram object 'oDiagram' sObj = oDiagram.GetContents('∗.IntGrf'); oGrf = sObj.First(); while(oLoadGrf) { ! !

Check if graphic object is associated with object 'oObj' Break out of loop if it is

if (oGrf:pDataObj = oObj) { break; } oGrf = sObj.Next(); }

7.3

Creating Graphical Objects in DPL

As with other DPL applications, the easiest way to create a graphical object is probably by copying a template object. As the configuration of the graphical objects will be largely dependent on the specific application, only a general process for creating graphical objects is presented here. 1. Create template graphical net objects (GNO), complete with graphical connection objects (GCO) stored within. Make sure the template objects are accessible by the DPL script either as internally or externally referenced objects (see section 3.3). 2. Find the diagram object (∗.IntGrfnet) where you want to create the graphical objects 3. Find or create the network element with which you want to associate the graphical object 4. Copy the template GNO into the selected diagram object (with the AddCopy function) 5. Get the newly created GNO and modify the following (as required): a. Associated network element (GNO:pDataObj) b. Graphical symbol (GNO:pSymNam) c. X- and Y- coordinates for object (GNO:rCenterX and GNO:rCenterY) 6. Access the associated GCO and modify the X- and Y- coordinates for the connections (GCO:rX and GCO:rY) HINT: as the GCO parameters rX and rY are vectors, the SetVal function will need to be used to modify the parameters (see section 3.2.3). For example, to modify the first row of rX to 100 and the second row to 150:

oGCO.SetVal(100, 'rX', 0); oGCO.SetVal(150, 'rX', 1); DPL Tutorial (DIgSILENT Technical Documentation)

61