Está en la página 1de 54

DIgSILENT

PowerFactory

Advanced Tutorial

DIgSILENT Programing Language (DPL)

I N T E G R AT E D P O W E R S Y S T E M A N A LY S I S S O F T W A R E F O R
TRANSMISSION / DISTRIBUTION / INDUSTRY / G E N E R AT I O N / I N T E G R AT I O N O F R E N E W A B L E S
Publisher:
DIgSILENT GmbH
Heinrich-Hertz-Strae 9
72810 Gomaringen / Germany
Tel.: +49 (0) 7072-9168-0
Fax: +49 (0) 7072-9168-88
info@digsilent.de

Please visit our homepage at:


http://www.digsilent.de

Copyright 2017 DIgSILENT GmbH


All rights reserved. No part of this
publication may be reproduced or
distributed in any form without written
permission of DIgSILENT GmbH.

February 2017
Version: 1
Edition: 3
Contents

Contents

1 Getting Started in DPL - A Quick Tutorial 1

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

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

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

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

2 Anatomy of a DPL Object 7

3 Basic DPL Scripting 11

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

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

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

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

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

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

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

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

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

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

3.3.1 Copy from an Internal Object . . . . . . . . . . . . . . . . . . . . . . . . . 17

3.3.2 Copy from an External Object . . . . . . . . . . . . . . . . . . . . . . . . . 18

3.3.3 Create a New Object by Code . . . . . . . . . . . . . . . . . . . . . . . . 19

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

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

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

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

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

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

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

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

DIgSILENT PowerFactory, Advanced Tutorial i


DIgSILENT Programing Language (DPL)
Contents

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

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

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

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

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

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

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

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

4 Advanced DPL Scripting 27

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

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

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

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

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

4.2.1 Vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

4.2.2 Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

4.2.3 Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

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

4.3.1 Object Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

4.3.2 Cubicle Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

4.3.3 Terminal Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

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

4.4.1 Standard File I/O Methods . . . . . . . . . . . . . . . . . . . . . . . . . . 38

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

5 Working with Results Files 40

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

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

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

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

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

DIgSILENT PowerFactory, Advanced Tutorial ii


DIgSILENT Programing Language (DPL)
Contents

5.6 Getting the Time Interval Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

5.7 Finding the Number of Time Intervals . . . . . . . . . . . . . . . . . . . . . . . . 42

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

6 Working with Virtual Instrument Panels 43

6.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

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

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

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

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

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

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

6.4 Exporting VI Panels to WMF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

DIgSILENT PowerFactory, Advanced Tutorial iii


DIgSILENT Programing Language (DPL)
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:

DIgSILENT PowerFactory, Advanced Tutorial 1


DIgSILENT Programing Language (DPL)
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:

DIgSILENT PowerFactory, Advanced Tutorial 2


DIgSILENT Programing Language (DPL)
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.

DIgSILENT PowerFactory, Advanced Tutorial 3


DIgSILENT Programing Language (DPL)
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:

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

DIgSILENT PowerFactory, Advanced Tutorial 4


DIgSILENT Programing Language (DPL)
1 Getting Started in DPL - A Quick Tutorial

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:

DIgSILENT PowerFactory, Advanced Tutorial 5


DIgSILENT Programing Language (DPL)
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 = GetFromStudyCase('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();
}

3. Press Save and then Execute. The output window should look like the following figure:

DIgSILENT PowerFactory, Advanced Tutorial 6


DIgSILENT Programing Language (DPL)
2 Anatomy of a DPL Object

Congratulations, youve 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
contained inside an object called the DPL Command object. Now well 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 pages -
Basic Options, Results, Script, Description and Version. We will go through each page and the
functions that are available

DIgSILENT PowerFactory, Advanced Tutorial 7


DIgSILENT Programing Language (DPL)
2 Anatomy of a DPL Object

The Basic Options page (shown above) has the following functions:

Change the name of the DPL command object

Choose a general selection (e.g. a set) that can be 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 Results page (shown below) has the following functions:

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.

DIgSILENT PowerFactory, Advanced Tutorial 8


DIgSILENT Programing Language (DPL)
2 Anatomy of a DPL Object

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

In this page it is also possible to 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.

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

DIgSILENT PowerFactory, Advanced Tutorial 9


DIgSILENT Programing Language (DPL)
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:

Inside the DPL command object above, you can see that it contains a result object Results and
another DPL command object CreatePlotRes (this is a sub-script - see Section 4.1 for further

DIgSILENT PowerFactory, Advanced Tutorial 10


DIgSILENT Programing Language (DPL)
3 Basic DPL Scripting

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)

3.1.1 By the General Selection

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

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

DIgSILENT PowerFactory, Advanced Tutorial 11


DIgSILENT Programing Language (DPL)
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.

DIgSILENT PowerFactory, Advanced Tutorial 12


DIgSILENT Programing Language (DPL)
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 whats inside a DPL command object, press the Contents button on the right-hand side
of the DPL command dialog box.

DIgSILENT PowerFactory, Advanced Tutorial 13


DIgSILENT Programing Language (DPL)
3 Basic DPL Scripting

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();

3.1.4 By Code

The general approach for accessing network objects in DPL purely through code is as follows:

DIgSILENT PowerFactory, Advanced Tutorial 14


DIgSILENT Programing Language (DPL)
3 Basic DPL Scripting

1. Get a set of the relevant network objects that you are looking for (using the GetCalcRel-
evantObjects 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 = GetCalcRelevantObjects('*.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 = GetCalcRelevantObjects();

! 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 = GetCalcRelevantObjects();

! 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();
}

DIgSILENT PowerFactory, Advanced Tutorial 15


DIgSILENT Programing Language (DPL)
3 Basic DPL Scripting

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 isnt 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:

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);

DIgSILENT PowerFactory, Advanced Tutorial 16


DIgSILENT Programing Language (DPL)
3 Basic DPL Scripting

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 2 km, 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:
oLine.SetVal(2, 'dline', 0);

3.3 Creating New Objects

There are at least three ways to create new objects in the database:

1. Copy object contained inside the script object


2. Copy external object
3. Create new object from scratch in code

3.3.1 Copy from an Internal Object

Copying an internal object is potentially the easiest option for creating new objects. The DPL
command object can contain other objects within it. To see whats 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.

DIgSILENT PowerFactory, Advanced Tutorial 17


DIgSILENT Programing Language (DPL)
3 Basic DPL Scripting

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:
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 oFold,
oEvent;
set EventSet;

! Get the simulation events folder in the active study case


oFold = GetFromStudyCase('IntEvt');
oFold.ShowFullName();

! Copy the 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 Object

This is almost identical to copying an object from an internal object, 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 youd 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 the object will be called inside the DPL script.

DIgSILENT PowerFactory, Advanced Tutorial 18


DIgSILENT Programing Language (DPL)
3 Basic DPL Scripting

Once the external object has been selected, you can use the AddCopy(object name) com-
mand 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 oGrid is
the external object, a new object will be created in the target folder by the following:
oFold.AddCopy(oGrid);

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 oFold,
oEvent;

! Get the simulation events folder in the active study case


oFold = GetFromStudyCase('IntEvt');
oFold.ShowFullName();

! Create short circuit event into the events folder


oEvent=oFold.CreateObject('EvtShc', 'SC_Event');
! Set the time to 1
oEvent:time = 1;

3.4 Checking if a Project is Active

The function GetActiveProject() returns NULL if there no project currently active.


object aPrj;

! Check if there is an active project


aPrj = GetActiveProject();
if (aPrj=NULL) {

DIgSILENT PowerFactory, Advanced Tutorial 19


DIgSILENT Programing Language (DPL)
3 Basic DPL Scripting

Error('Please activate a project first');


exit();
}

3.5 Navigating Folders and Object Contents

3.5.1 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 Folder Description


equip Equipment type library
netmod Network model
oplib Operational library
scen Operational scenario
script Script
study Study Case
templ Template
netdat Network data
dia Diagram
scheme Variation
cbrat CB rating
therm Thermal rating
ra Running arrangement
mvar Mvar limits curve (capability curves)
outage Outage
fault Fault

3.5.2 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:

DIgSILENT PowerFactory, Advanced Tutorial 20


DIgSILENT Programing Language (DPL)
3 Basic DPL Scripting

Contents = oObj.GetContents();

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 GetFromStudyCase(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 GetFromStudyCase() is that if the object doesnt 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 = GetFromStudyCase('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;

DIgSILENT PowerFactory, Advanced Tutorial 21


DIgSILENT Programing Language (DPL)
3 Basic DPL Scripting

! Get the study cases folder and make a set of all study cases
aFold = GetProjectFolder('study');
aCases = aFold.GetContents('*.IntCase',1); !includes subfolders

! Count the number of study cases


iCases = aCases.Count();
if (iCases=0) {
Error('There are no study cases in the current selection');
exit();
}
printf('Number of cases: %i', 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();
}

3.7 Executing Calculations

The GetFromStudyCase(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 code snippet below executes a load flow calculation in the active study case:
object ldf;

! Get load flow object from calculation case (or create it)
ldf = GetFromStudyCase('ComLdf');
! Execute load flow calculation
ldf.Execute();

3.8 Accessing Results

3.8.1 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.

DIgSILENT PowerFactory, Advanced Tutorial 22


DIgSILENT Programing Language (DPL)
3 Basic DPL Scripting

object ldf, aLine;


set Lines;

! Run a load flow


ldf = GetFromStudyCase('ComLdf');
ldf.Execute();

! Get the set of all lines


Lines = GetCalcRelevantObjects('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:

Print a formatted string to the output window


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 p.u.', dVoltage);

For the float / double variable dVoltage = 1.03, this example prints the following in the
output window:
Voltage = 1.030000 p.u.

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:
printf('Voltage = %.3f p.u.', dVoltage);

DIgSILENT PowerFactory, Advanced Tutorial 23


DIgSILENT Programing Language (DPL)
3 Basic DPL Scripting

Print a red error message


Error (string, [variables]), example:
Error('Script failed!');

Prints the following message in the output window:


DIgSI/err - Script failed!
Print a brown warning message
Warn (string, [variables]), example:
Warn('Script not initialised properly');

Prints the following message in the output window:


DIgSI/wrng Script not initialised properly

Print a green information message


Info (string, [variables]), example:
Info('Script running iteration %d', i);

Prints the following message in the output window:


DIgSI/info Script running iteration 1

Clear output window


ClearOutputWindow(), example:
ClearOutputWindow();

Clears all text in the output window.

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
doesnt refer to an existing VI page and the create flag is activated (=1).

For example, the snippet below uses the graphics board object oGrb (defined as external object)
to create a VI page called Plots:
object oViPg;

oViPg = oGrb.GetPage('Plots',1);

DIgSILENT PowerFactory, Advanced Tutorial 24


DIgSILENT Programing Language (DPL)
3 Basic DPL Scripting

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 virtual instrument 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 Description


VisPlot Subplot
VisPlot2 Subplot with two y-axes
VisXyplot X-Y plot
VisFft FFT plot
VisOcplot Time-overcurrent plot
VisDraw R-X plot
VisPlotz Time-distance plot
VisEigen Eigenvalue plot
VisModbar Mode bar plot
VisModphasor Mode phasor plot
VisVec Vector diagram
VisHrm Waveform plot
VisBdia Distortion plot
VisPath Voltage profile plot
VisVsag Voltage sag plot
VisPdc Probability density plot
VisDefcrv Curve-input plot
VisMeas Measurement (scales, displays, etc)
VisBitmap Picture box
VisSwitch Button
VisButton Command button

Table 3.1: Input/Output signals

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:

DIgSILENT PowerFactory, Advanced Tutorial 25


DIgSILENT Programing Language (DPL)
3 Basic DPL Scripting

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 (object O, string 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:u1 and 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(oBus,'m:u1');

! Adjust y-axis min and max settings


oPlot:y_max = 2;
oPlot:y_min = 0;

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

DIgSILENT PowerFactory, Advanced Tutorial 26


DIgSILENT Programing Language (DPL)
4 Advanced DPL Scripting

4 Advanced DPL Scripting

4.1 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 (TimeSweep) contains another DPL
script called CreatePlotRes. This script (CreatePlotRes) is referred to as a sub-script or a
subroutine and can be executed from inside the parent script (TimeSweep).

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()
command:
sub_script.Execute();

For example, to execute the sub-script CreatePlotRes in the figure above:


CreatePlotRes.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.

DIgSILENT PowerFactory, Advanced Tutorial 27


DIgSILENT Programing Language (DPL)
4 Advanced DPL Scripting

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);

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 Results page of the DPL command object. Consider
the results parameter S defined in the script calc power below:

DIgSILENT PowerFactory, Advanced Tutorial 28


DIgSILENT Programing Language (DPL)
4 Advanced DPL Scripting

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);

4.2 Vectors, Maps and Matrices

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

IntVec: a vector of decimal numbers (of type double)


IntDplvector: a vector of objects, sets, integers, strings or decimal numbers

IntMat: a matrix of decimal numbers (of type double)


IntDplmap: a vector of objects, sets, integers, strings or decimal numbers mapped to key
values

DIgSILENT PowerFactory, Advanced Tutorial 29


DIgSILENT Programing Language (DPL)
4 Advanced DPL Scripting

4.2.1 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 IntDPLvector 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 Empties the vector of all items.


items and sets all item The size of the vector is null / 0.
values to 0
Get value at index i Get (i) Get (i)

Example: x = Example: x = Vec.Get(0)


Vec.Get(1)
Get the value of the first item
Get the value of the first and put it into variable x.
item and put it into
variable x.

DIgSILENT PowerFactory, Advanced Tutorial 30


DIgSILENT Programing Language (DPL)
4 Advanced DPL Scripting

Function IntVec IntDplVector


Set value at index i Set (i, value) Insert (i, item)

Example: Vec.Set(3, Example:


2.5) Vec.Insert(1,oBus)

Sets the value 2.5 into Puts the object oBus into the
the vector at index 3 vector at index 1
Resize vector to size n Resize (n) N/A

Example:
Vec.Resize(3)

Resizes the vector to 3


items. All additional items
are set to 0 .
Get number of items in vector Size() Size()

Example: x = Example: x = Vec.Size()


Vec.Size()
Gets the number of items in the
Gets the number of items vector and puts it into variable x.
in the vector and puts it
into variable x.
Add item to the end of a vector N/A Insert (item)

Example: DplVec.Clear()

Adds the object oBus to the


end of the vector. This
increases the size of the vector
by 1.
Remove item at index i N/A Remove (i)

Example: Vec.Remove(3)

Removes the item at index 3.


This reduces the size of the
vector by 1.
Find the index of item x in the N/A IndexOf (x)
vector (reverse lookup)
Example: i =
Vec.IndexOf(x)

Returns the index of item x


and puts it into (integer) variable
i. The function returns -1 if no
match is found.

DIgSILENT PowerFactory, Advanced Tutorial 31


DIgSILENT Programing Language (DPL)
4 Advanced DPL Scripting

Function IntVec IntDplVector


Sort items in vector N/A 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
weve 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 key-
value 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.

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

DIgSILENT PowerFactory, Advanced Tutorial 32


DIgSILENT Programing Language (DPL)
4 Advanced DPL Scripting

Function IntDplmap
Initialise a DPL map Clear()

Example: Map.Clear()

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

Gets the value associated with the key x and puts it into the
object variable oVal.
Get number of key-value Size()
pairs in DPL map
Example: i = Map.Size()

Gets the number of key-value pairs and puts it into variable i


Add or modify a Insert (key, value)
key-value pair
Example: Map.Insert(x, oBus)

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 a key-value pair Remove (key)

Example: Map.Remove(x)

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

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)
Get the first key-value First (key, value)
pair in the DPL map
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)

DIgSILENT PowerFactory, Advanced Tutorial 33


DIgSILENT Programing Language (DPL)
4 Advanced DPL Scripting

Function IntDplmap
Get the next key=value Next (key, value)
pair in the DPL map
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)

Initialises a 3 x 4 matrix and initialises all elements to the value


2
Get the rows and NRow() / NCol()
columns of a matrix
Example: iRow = Mat.NRow()

Gets the number of rows in the matrix and puts it in variable


iRow
Resize a matrix Resize (rows, columns, init val)

Example: Mat.Resize(5,5)

Resizes to a 5 x 5 matrix. As init val is not set, all additional


elements are initialised to 0.
Get the value at row x Get (x, y)
and column y
Example: dVal = Mat.Get(2,3)

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

Sets the value in the 3rd row and 2nd column to 10.

DIgSILENT PowerFactory, Advanced Tutorial 34


DIgSILENT Programing Language (DPL)
4 Advanced DPL Scripting

Function IntMat
Read the labels of rows RowLbl (row) / ColLbl (column)
and columns in a matrix
Example: sLabel = Mat.RowLbl(1)

Gets the label of the 1st row and puts it into the (string) variable
sLabel
Set the labels of rows RowLbl (label, row) / ColLbl (label, column)
and columns in a matrix
Example: Mat.ColLbl(busbars, 2)

Sets the label of the 2nd column to busbars


Multiply two matrices Multiply (Mat A, Mat B)

Example: iBool = Mat.Multiply(A, B)

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 a matrix Invert()

Example: iBool = Mat.Invert()

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)
Sort a matrix SortToColumn (column)
alphanumerically
according to 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 doesnt exist)

DIgSILENT PowerFactory, Advanced Tutorial 35


DIgSILENT Programing Language (DPL)
4 Advanced DPL Scripting

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 below:

4.3.1 Object Functions

GetConnectedElements (breakers, disconnectors, out of service): gets a set of the


elements connected to an object.

Example a):
setObj = oTerm.GetConnectedElements(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.GetConnectedElements();

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.
Note: when using this function to find connected terminals, one must be careful
about the use of the internal node option in terminals. When this option is set,
then GetConnectedElements() 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): gets the terminal / node connected to
an object.

Example a):
oTerm=oLine.GetNode(0,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);

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): gets the cubicle connected to an object.

Example
oCub=oLine.GetCubicle(1);

DIgSILENT PowerFactory, Advanced Tutorial 36


DIgSILENT Programing Language (DPL)
4 Advanced DPL Scripting

Gets the cubicle with index 1 at line object oLine and puts it into the object oCub.
Returns NULL if the cubicle doesnt exist.

GetConnectionCount(): gets the number of connections / cubicles connected to an


object.
Example
i = oLine.GetConnectionCount();

Gets the number of connections or cubicles connected to line object oLine and puts
it into the variable i
IsClass(): checks if an object is of a certain class (useful when filtering for certain types
of objects).
Example
iLine = obj.IsClass('ElmLne');

Checks if the object obj is a line (i.e. of class ElmLne) and stores the result in
variable iLine. Returns 1 if the result is true, and 0 otherwise.

4.3.2 Cubicle Functions

GetAll (direction = 0 (branch) or 1 (terminal), switch state = 0 or 1): gets the set of all
network elements downstream / upstream of a cubicle.
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 traversal
in the direction of the branch ignoring switch states.

4.3.3 Terminal Functions

GetNextHVBus(): gets the next busbar (at a higher nominal voltage level) connected to
the terminal.

Example:

DIgSILENT PowerFactory, Advanced Tutorial 37


DIgSILENT Programing Language (DPL)
4 Advanced DPL Scripting

oBus=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 Reading from and Writing to External Files

4.4.1 Standard File I/O Methods

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

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)
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]): writes a formatted string to a file, similar to the
printf function, but writes to a file instead of the output window.
Example:
fprintf(0,'Voltage = %f p.u.' , dVoltage);

For the float / double variable dVoltage = 1.03, this example writes the following to
file number 0:
Voltage = 1.030000 p.u.
SetLineFeed (i): sets or resets 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

DIgSILENT PowerFactory, Advanced Tutorial 38


DIgSILENT Programing Language (DPL)
4 Advanced DPL Scripting

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 sep-
arated 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 previous example, except that values are separated by semi-colons ;


fflush (file number): saves contents of file buffer. For performance purposes, file opera-
tions 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 ob-
ject (*.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:tempresults1.wmf:
obj oDesk;
oDesk = GetFromStudyCase('SetDesktop');
oDesk.WriteWMF('C:\temp\results1');

DIgSILENT PowerFactory, Advanced Tutorial 39


DIgSILENT Programing Language (DPL)
5 Working with Results Files

5 Working with Results Files

Suppose you want to get a PowerFactory Results file (of type ElmRes) from a dynamic simu-
lation, 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.

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.

DIgSILENT PowerFactory, Advanced Tutorial 40


DIgSILENT Programing Language (DPL)
5 Working with Results Files

The number of rows represents the total number of time intervals for the simulation. For
example, if there is 10 s of simulation with a time interval of 0.01 s, then there would be 1000
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[] ). 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:
ElmRes.Load();

Load() loads the contents of a results file into memory and allows you to begin accessing the
data. You can only load one results file into memory at any one time.

DIgSILENT PowerFactory, Advanced Tutorial 41


DIgSILENT Programing Language (DPL)
5 Working with Results Files

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 ElmRes.FindColumn(object,'var_name');

FindColumn returns an integer, which is the column number for the object and variable youve
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 cant
get a vector of data from the results file). Use the following command to get a data point:
ElmRes.GetValue(output, 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.

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 GetValue, but without inputting the column index, i.e.:
ElmRes.GetValue(output, 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 ElmRes.GetNumberOfRows(ColumnNo);

The GetNumberOfRows() function returns an integer with the number of time intervals for a
specific column. If no ColumnNo is specified, it 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.

DIgSILENT PowerFactory, Advanced Tutorial 42


DIgSILENT Programing Language (DPL)
6 Working with Virtual Instrument Panels

! 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


All_calcs.Load();

! Return the number of rows (i.e. time intervals)


N = All_calcs.GetNumberOfRows();

! Get the column index for the voltage 'm:u1' for the selected object
i1 = All_calcs.FindColumn(oSet,'m:u1');

! Loop through each row and output the time and voltage
while (i<N) {
All_calcs.GetValue(dt, i);
All_calcs.GetValue(du, i,i1);
if (i>1) {
printf('t = %f s; u = %f', dt, du);
}
i = i + 1;
}
! Release the results file All_calcs from memory
All_calcs.Release();

6 Working with Virtual Instrument Panels

6.1 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 section provides some detailed instructions on manipulating virtual instrument panel ob-
jects using the DPL scripting language. Firstly some general definitions for the objects related
to virtual instrument panels:

Graphics Board: is the container for all graphics, including the VI panels.

VI Panel: is the name of the whole virtual instrument page (*.SetVIpage).


Visplots:are the individual plots inside a VI panel (*.VisPlot).

DIgSILENT PowerFactory, Advanced Tutorial 43


DIgSILENT Programing Language (DPL)
6 Working with Virtual Instrument Panels

6.2 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.

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 isnt an easy direct way to create local title
block objects via a DPL script. Instead, the simplest way is to copy a title block into a VI panel
object and use it as a template.

DIgSILENT PowerFactory, Advanced Tutorial 44


DIgSILENT Programing Language (DPL)
6 Working with Virtual Instrument Panels

Firstly, find the 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
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:

DIgSILENT PowerFactory, Advanced Tutorial 45


DIgSILENT Programing Language (DPL)
6 Working with Virtual Instrument Panels

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 doesnt. Lastly, the script fills in the
title block information. In this example, the object TitleBlock 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 = GetActiveStudyCase();
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


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) {

DIgSILENT PowerFactory, Advanced Tutorial 46


DIgSILENT Programing Language (DPL)
6 Working with Virtual Instrument Panels

printf('No local title block exists. Creating local title block');


Pg.AddCopy(TitleBlock);
allTitms = Pg.GetContents('*.SetTitm');
oTitle = allTitms.First();
}
! Fill in title block with the following information:
! Annex = 1
! Title 1 = Motor Re-Acceleration Simulation
! Title 2 = Voltage Profile for Station X

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.

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 = GetActiveStudyCase();
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

DIgSILENT PowerFactory, Advanced Tutorial 47


DIgSILENT Programing Language (DPL)
6 Working with Virtual Instrument Panels

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(Constant1);
oPlot.AddCopy(Constant2);
}

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. File Export Graphic) 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 = GetFromStudyCase('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 on screen
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

j = oDesk.WriteWMF(FileName);

DIgSILENT PowerFactory, Advanced Tutorial 48


DIgSILENT Programing Language (DPL)
6 Working with Virtual Instrument Panels

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.

DIgSILENT PowerFactory, Advanced Tutorial 49


DIgSILENT Programing Language (DPL)