Beruflich Dokumente
Kultur Dokumente
PowerFactory 2018
I N T EG R AT E D P O W E R S Y S T EM A N A LY S I S S O F T WA R E F O R
T R A N S M I S S I O N / D I S T R I BU T I O N / I N D U S T RY / G EN E R AT I O N / I N T EG R AT I O N O F R EN E WA B L E S
Publisher:
DIgSILENT GmbH
Heinrich-Hertz-Straße 9
72810 Gomaringen / Germany
Tel.: +49 (0) 7072-9168-0
Fax: +49 (0) 7072-9168-88
info@digsilent.de
Contents
1 Introduction 1
2.2 Initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
2.3.4 Status . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.5 Directories . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
5 Annexes 6
5.1 digdplarg.hpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1 Introduction
The built-in PowerFactory scripting language DPL can be extended by user-defined functions.
Those functions must be provided as a standard DLL following some specific implementation
requirements.
Functions implemented in those DLL are registered in the DPL interpreter and can be used
like built-in functions. The loading and registering process is executed once the first time the
interpreter meets an unknown function.
Please note: Displaying graphical user interfaces (e.g. dialogs, windows forms) inside user-
defined functions is not supported!
The DPL interpreter searches for DLLs whose names start with digdplfun and end with .dll in
the PowerFactory installation directory. All of these DLLs are loaded at runtime of the DPL
interpreter.
If the first try to load such a DLL fails, no further attempts are made.
If multiple DLLs provide a function of same name, a warning is report and this function is not
registered.
The loading order is undefined.
The DLL is a standard MS Windows library having pure C functions exported by name.
In order to work with the arguments delivered by PowerFactory , the header digdplarg.hpp
must be included into the DLL. This header provides
• message output codes for printing messages to the output window of PowerFactory ,
• error enums for setting the execution status,
• structure of passed arguments and
• structure of returned result.
2.2 Initialization
The DLL must provide the following functions that are called in the registration process by the
DPL interpreter:
This function publicizes all functions names. It’s called by the interpreter with increasing iFncNr.
A return of value ”0” means that additional functions are available for registration. A value of ”1”
ends this registration process.
Normally, the default implementations given in the attached example can be used without further
adaptation.
Each user-defined DPL command must be implemented as a single function in the DLL provid-
ing the following signature:
DIGDPLFUN_API void FunctionName (DplArgList* argList, int checkonly,
ExtProcRes &result, ProcResTp &status)
Whenever such a user-defined function is called in a DPL script, the corresponding function in
DLL is executed. The parameters have the following meaning
• DplArgList* args: Delivers all arguments that are passed to the DPL command.
Please note that all function names are case-sensitive. Its not possible to overwrite a built-in
function.
Parameters passed to the DPL function call (e.g. function(param1, param2, )) are stored in
the structure DplArgList* args. For external DPL functions only parameters of type double and
string can be accessed (integers are always passed as doubles). The sequences of elements
are the same as in DPL function call.
When a script is executed, the DPL interpreter first performs a syntax check. For this check, all
functions are executed with flag checkonly set to 1. This means, the function should not do any
processing but just check the validity of given arguments. If the arguments seem to be okay, the
status must be set to ISOK or (if a result will be returned) to the type of the result delivered by
this function (e.g., a function that returns a double value must return ISDBL). If any argument is
detected as invalid, the status has to be set to ISARGERR.
A result is returned by setting the result parameter. It is possible to return an integer, a double or
a string (as defined in ExtProcRes struct). The status parameter is used to indicate the type of
the result value. Attention, for returning a string the characters must be copied into the allocated
memory of result struct. It is necessary to ensure, that the string is zero terminated and does
not exceed a maximum of 1024 characters
2.3.4 Status
First, it is used to indicate a fatal error to the DPL interpreter. This is done by setting the value
to ISERR.
Second, on success of execution, it indicates the type of the returned value. So the status must
be set to ISINT, ISDBL or ISSTR when returning a value. If no value is returned, it must be set
to ISOK.
In the initialization process, a function pointer is passed to the DLL. Via this function it is possible
to print messages to the output window of PowerFactory.
2.5 Directories
When the DLL is loaded into PowerFactory , it is informed about the PowerFactory main
directory and a temp directory that can be used for storing temporary data. These paths are
given full qualified.
A new function can be created by using attached example and following these steps:
When a DLL is loaded its never freed up to the termination of PowerFactory . This means,
the DLL file keeps locked and cannot be replaced by another version while PowerFactory is
running.
This can be quite cumbersome for developing. Therefore, a so called hidden PowerFactory
command is available to load or unload external DLLs manually. This command is called
ComDllmanager and can be accessed by typing in the command name in the Element Selection
when creating a new element (it is not shown in a selection list) (see Figure 2).
The DLL manager supports loading and unloading of external DPL and DSL libraries. On
loading, these libraries must be located in the PowerFactory installation directory and named as
digdplfun*.dll (DPL) or digexdyn*.dll (DSL).
Furthermore, the DLL manager shows a list of currently loaded DLLs depending on selected
DLL type.
5 Annexes
5.1 digdplarg.hpp
#define N_EXEPROC_ARG 64
typedef enum {
ISVOID=0, ///< return value is void
ISERR, ///< error in function
ISOK, ///< everything seems to be OK
ISARGERR, ///< function arguments are wrong
ISSTR, ///< return value is a string
ISDBL, ///< return value is a double
ISINT ///< return value is a int
} ProcResTp;
struct DplArg {
ProcResTp typ;
union {
char *pStr;
double d;
int i;
void *ptr1;
void *ptr2;
void *ptr3;
void *ptr4;
};
DplArg() { typ=ISVOID; };
};
struct DplArgList {
int nArg;
DplArg Arg[N_EXEPROC_ARG]; ///< max N_EXEPROC_ARG function arguments
};
typedef union {
double d;
int i;
char s[1024];
} ExtProcRes;
/***********************************************************************
* userfun.cpp: user-defined DPL functions
***********************************************************************/
/*
Defining new functions:
- add the function’s name to the array "fncNames"
- implement the function:
#include <stdio.h>
#include <string.h>
#include "digdplarg.hpp"
else{
return 1;
}
}
//----------------------------------------------------------------------------
//
// Implement your new DPL commands here !!
//
//----------------------------------------------------------------------------
// Example1
// The function doesn’t care for arguments. It just prints a message that it was
// called to the powerfactory output window.
DIGDPLFUN_API void Function1(DplArgList* argList, int checkonly, ExtProcRes &result,
ProcResTp &status)
{
status = ISOK; // set result type to everything ok
if (checkonly){
return;
}
pPrintFnc("Function1 called.",MSG_INFO);
}
// Example2
// The function shows how to access passed arguments.
DIGDPLFUN_API void Function2(DplArgList* argList, int checkonly, ExtProcRes &result,
ProcResTp &status)
{
status = ISOK;
pPrintFnc("Function2 called.",MSG_INFO);
char text[512];
sprintf(text, "Argument[%i]:", i);
switch(argList->Arg[i].typ){
case ISSTR:
strcat(text, " (string) ");
strncat(text, argList->Arg[i].pStr, 400);
break;
case ISDBL:
char tmp[400];
sprintf(tmp, " (double) %f", argList->Arg[i].d);
strcat(text, tmp);
break;
default:
strcat(text, "Unknown type.");
status = ISERR;
}
pPrintFnc(text,MSG_INFO);
}
}
// Example3
// The function expects a variable number of double values and returns the sum
// of them.
DIGDPLFUN_API void Function3(DplArgList* argList, int checkonly, ExtProcRes &result,
ProcResTp &status)
{
status = ISDBL; //set the status to double to indicate that a double value
//will be returned
result.d = 0;
for (int i=0; i < argList->nArg; i++){
result.d += argList->Arg[i].d;
}
}
// Example4
// The function shows how to return a string.
DIGDPLFUN_API void Function4(DplArgList* argList, int checkonly, ExtProcRes &result,
ProcResTp &status)
{
status = ISSTR; //set return type to string
status = ISARGERR;
}
return;
}