libIEC61850 doc 5 IEC 61850 client tutorial

libIEC61850 doc 5 IEC 61850 client tutorial
libIEC61850 doc 5 IEC 61850 client tutorial

libIEC61850

open source library for IEC 61850

IEC 61850 client tutorial

The IEC 61850 client API contains functions to support model discovery, reading and writing data attributes, data set handling, configuration and reception of reports, file services and control operations. This client API is designed to be as close as possible to the IEC 61850 ACSI (abstract communication service interface) as defined in IEC 61850-7-2. But be aware that there are some points where there are some deviations from the ACSI due to practical reasons. Create a connection to a server

Before you can connect to a server you have to create an IedConnection object. A connection will be established with the IedConnection_connect method. The first argument is the newly created IedConnection instance. The second argument provides a pointer to a variable where the client stack can store error informations. This is also the case with most other client API functions (IedConnection_…) where errors can occur. The third argument is a string containing the IP address or hostname of the server to connect. The last argument provides the TCP port of the server. The default TCP port of MMS is 102. So you should always select this port.

Practical examples on how to use the IEC 61850 client API can be found in the examples folder in the libiec61850 source distributions. These examples start with “iec61850_client”.

IedClientError error;

IedConnection con = IedConnection_create();

IedConnection_connect(con, &error, "192.168.1.2", 102);

if (error == IED_ERROR_OK) {

// do some work

IedConnection_close(con);

}

IedConnection_destroy(con);

...

The code snippet above will connect to a server with IP address 192.168.1.2 listening on port 102 (the default MMS port). If you finished your task you have to call IedConnection_close to properly close the connection to the server. After you closed the connection you should also call IedConnection_destroy to release all resources allocated by the client stack. Control connection parameters

The IEC 61850/MMS protocol is a complex protocol consisting of a lot of OSI protocol layers. Most of them have their own parameters. Fortunately in most cases the default values of these parameters are sufficient to connect to a device. Some devices though have problems with default parameters and require a special treatment.

The IsoConnectionParameters object, that is associated with a MmsConnection can be used to set the lower layer parameters (below the MMS layer). It can also be used to set authentication values (e.g.

a password) if the server requires authentication.

For more details on how to change these parameters please have a look at the examples and the API reference documentation.

Data model discovery

IEC 61850 provides a wide range of functions to discover the data model present at the server. These functions are especially interesting if you want to write a generic client. If you know the data model of the device you want to communicate to you don’t need these functions.

To request the logical device list from the server you can call the IedConnection_getLogicalDeviceList method.

LinkedList deviceList = IedConnection_getLogicalDeviceList(con, &error);

The resulting linked list contains the names of all logical devices of the server as a list of C strings. The directory of a logical device can be retrieved by calling IedConnection_getLogicalDeviceDirectory with the name of the logical device as a parameter.

The following example iterates the list of logical devices and requests the logical node list for each logical device:

LinkedList device = LinkedList_getNext(deviceList);

while (device != NULL) {

printf("LD: %s\n", (char*) device->data);

LinkedList logicalNodes = IedConnection_getLogicalDeviceDirectory(con, &error,

(char*) device->data);

device = LinkedList_getNext(device);

}

Reading and writing data objects

You can read or write simple or complex data attributes/objects with the IedConnection_readObject and IedConnection_writeObject funtions. Before you can use these functions you have to establish a connection to a server as explained above. The parameter lists of both functions are similar. The first argument is the connection object of an established connection. The second argument is a pointer to an IedClientError variable. The third argument is the object reference of the data attribute/object you want to access. The fourth argument is the Functional Constraint (e.g. MX).

Note: You cannot access whole IEC 61850 data objects with these functions. For example a call to IedConnection_readObject will result in a single MMS read command. This is restricted to functional constraint data. So in order to read all values of an IEC 61850 data object you have to use multiple readObject calls for each functional constraint the data object has elements of. This seems as a restriction at the first but turns out to be very useful. E.g. you can read all measurement or status values (functional constraints MX or ST) of an IEC 61850 data object without reading configuration values or control variables (functional constraints CF or CO).

IedClientError error;

...

/* read an analog measurement value from server */

MmsValue* value = IedConnection_readObject(con, &error,

"simpleIOGenericIO/GGIO1.AnIn1.mag.f", MX);

if (value != NULL) {

float fval = MmsValue_toFloat(value);

printf("read float value: %f\n", fval);

MmsValue_delete(value);

}

/* write a variable to the server */

value = MmsValue_newVisibleString("https://www.360docs.net/doc/aa1218133.html,");

IedConnection_writeObject(con, &error,

"simpleIOGenericIO/GGIO1.NamPlt.vendor", DC, value);

if (error != IED_ERROR_OK)

printf("failed to write simpleIOGenericIO/GGIO1.NamPlt.vendor!\n");

The IedConnection_readObject and IedConnection_writeObject functions use instances of MmsValue as results or parameters. The benefit of these functions is that they are very flexible and can also be used to access complex (structured) data. Also the type of the result has not to be known in advance when using the readObject function. One other consequence is that for the read function the API user always have to free (by using MmsValue_delete) the data after processing. Also by using the writeObject functions you have to deal with MmsValue and its special setter functions. To avoid this the client API also contains some convenience functions that allow read and write with native data types as parameters. These functions are restricted to access simple (basic) data attributes. Also the type of the result has to be known in the read case.

An example for these functions is the IedConnection_readFloatValue function:

float magF = IedConnection_readFloatValue(con, &error,

"simpleIOGenericIO/GGIO1.AnIn1.mag.f", MX);

Handling data sets

Data sets are groups of data attributes (DA) or functional constraint data objects (FCDO). They are used to simplify access to functional related groups of variables. E.g. if you want to read the most important status values of a server you don’t have to ask the server for each individual variable. Instead you define a data set (or most probably use a predefined one) that contains all the required data and request them with a single read with the data set reference as an argument. Data sets are also intended to be used in relation with reports, GOOSE messages and logs (time series of data).

So far the IEC 61850 client API supports the following data set related services:

?read data set values

?define a new data set

?delete an existing data set

?read the directory (list of variables) of the data set

To represent a data set client side the library uses objects of type ClientDataSet. ClientDataSet can be considered as a container to store the values of a data set and consists of these functions:

void

ClientDataSet_destroy(ClientDataSet self);

MmsValue*

ClientDataSet_getValues(ClientDataSet self);

char*

ClientDataSet_getReference(ClientDataSet self);

int

ClientDataSet_getDataSetSize(ClientDataSet self);

The actual values of the data set are stored as MmsValue instance of type MMS_ARRAY. There is an array element for each member of the data set.

To access the data set related services these functions have to be used:

ClientDataSet

IedConnection_readDataSetValues(IedConnection self, IedClientError* error,

char* dataSetReference, ClientDataSet dataSet);

void

IedConnection_createDataSet(IedConnection self, IedClientError* error,

char* dataSetReference, LinkedList /* char* */ dataSetElements); void

IedConnection_deleteDataSet(IedConnection self, IedClientError* error,

char* dataSetReference);

LinkedList /* */

IedConnection_getDataSetDirectory(IedConnection self, IedClientError* error,

char* dataSetReference, bool* isDeletable);

The IedConnection_readDataSetValues creates a new instance of ClientDataSet if the last parameter (dataSet) is NULL. A call to this function triggers a request to the server. If you call the function multiple times you can provide the formerly received ClientDataSet instance as dataSet parameter. In this way you can reuse the container.

This example shows how to read the values of a data set:

ClientDataSet dataSet = IedConnection_readDataSetValues(con, &error,

"simpleIOGenericIO/LLN0.Events", NULL);

if (error == IED_ERROR_OK) {

printf("Read data set %s\n", ClientDataSet_getReference(dataSet));

IedConnection_readDataSetValues(con, &error, "simpleIOGenericIO/LLN0.Events", dataSe t);

}

To create a new data set you have to build a list containing the object references to the functional constraint data that should become the data set members. Please note that the FC has to be present in squared brackets as shown below:

LinkedList dataSetItems = LinkedList_create();

LinkedList_add(dataSetItems, "simpleIOGenericIO/GGIO1.SPCSO1.stVal[ST]"); LinkedList_add(dataSetItems, "simpleIOGenericIO/GGIO1.SPCSO1.t[ST]"); LinkedList_add(dataSetItems, "simpleIOGenericIO/GGIO1.SPCSO2.stVal[ST]"); LinkedList_add(dataSetItems, "simpleIOGenericIO/GGIO1.SPCSO2.t[ST]"); IedConnection_createDataSet(con, &error, "simpleIOGenericIO/LLN0.newDataSet", dataSetIt ems);

This example will create a new data set with the name simpleIOGenericIO/LLN0.newDataSet containing four different elements.

Receiving reports

Reports are used for event based message transmission. If you need to be updated with the states of certain variables reporting provides the means without forcing you to periodically send read requests to the server. This preserves network bandwidth especially in cases where values only change sporadically.

Reports are defined for data sets. A server typically contains preconfigured Report Control Blocks (RCB). A client has to reserve, configure and activate such a RCB prior to receiving report messages from the server.

To handle reports client side these data types are involved:?ClientReportControlBlock – is the data container to hold the RCB values client side

?ClientReport – represents a received report

?ClientDataSet – container for the data values of a received report ?ReportCallbackFunction – callback function when a report is received ?ReasonForInclusion – enumeration to indicate the reason for the inclusion of a data set member into the report

To get started with reports you need to configure and enable a RCB at the server. You can start by reading the values of the RCB with the IedConnection_getRCBValues function:

You have to specify the RCB by a special reference as the third argument of the function. Please not the “RP” inserted between the LN name and the RCB name. This has to be used for unbuffered reports. If you want to enable a buffered report you have to use “BR” instead. The function reads all values of the RCB from the server and creates a new instance of ClientReportControlBlock. If you want to use an existing instance of ClientReportControlBlock you can specify the instance as the last argument of the function.

If you want to write to the RCB you can also create a new instance with the ClientReportControlBlock_create function. Set the values with the setter functions and use the IedConnection_setRCBValues function to write the changed or new values to the server:

Please note that in contrast to the IedConnection_getRCBValues function that always reads all RCB values the setRCBValues only write the requested values. These values need to be specified by using the fourth argument of the function.

Prepare the client to receive reports:

In order to receive reports and access the report data you have to provide a callback function to the client API. A very simple callback function and the other required preparation steps can look like this:

static void

reportHandler (void* parameter, ClientReport report)

{

printf("report received\n");

}

ClientDataSet dataSet = IedConnection_readDataSetValues(con,

&error, dataSetReference, NULL);

IedConnection_installReportHandler(con, "simpleIOGenericIO/LLN0.RP.EventsRCB",

reportHandler, NULL, dataSet);

First it is required to get a ClientDataSet instance that can be used by the report receiver part of the client stack to store the report data. The second step is to connect the report callback function and the data set representation to the RCB. This is done by calling the IedConnection_installReportHandler

Then reporting can be enabled by using the IedConnection_setRCBValues function:

ClientReportControlBlock_setRptEna(rcb, true);

IedConnection_setRCBValues(con, &error, rcb, RCB_ELEMENT_RPT_ENA, true);

There is also a convenience function to do all these steps by a single function

call:IedConnection_enableReporting . This function can be used to select the RCB to use, to define the trigger conditions for report transmissions:

IedConnection_enableReporting(con, &error, "

simpleIOGenericIO/LLN0.RP.EventsRCB",

clientDataSet,

TRG_OPT_DATA_UPDATE | TRG_OPT_INTEGRITY,

reportCallbackFunction,

ClientDataSet_getDataSetValues(clientDataSet));

If you no longer want to receive reports from a RCB you can use the IedConnection_setRCBValues function with rptEna set to false or the IedConnection_disableReporting function. Controlling a device

Please have a look at the separate control tutorial.

Using file services

TBD

Access to the underlying MMS API

If you need to perform some advanced tasks that are not supported by the IEC 61850 client API you can also get access to the underlying MMS API. Be aware that by using this API it is not guaranteed that the resulting behavior is compliant with the IEC 61850 specification. It is in the responsibility of the application programmer to ensure that the resulting program is compliant with the specification if this is required. You can get the underlying MmsConnection object by calling the IedConnetion_getMmsConnection function.

Using authentication

Currently the client stack only supports basic password authentication. Work on certificate based authentication is in progress.

To use authentication it is required to access the MmsConnection object:

16 thoughts on “IEC 61850 client tutorial”

Hi,

I want to use authentication in the application which server example shall i run to create a server which requires validation frm the client, i tried with mms_client_example4, its not able to crete the

server please help.

Thanks Bikash The server_example4 uses password authentication. If you want to use some of the example clients

(like iec61850_client_example5) you have to change the password to match the server.

bikash

December 24, 2014 at 7:01 am

Michael Zillgith January 7, 2015 at 12:48 pm Post author

Hi,

Please help on this, I am connecting with the actual device P14NB model, the client example is not able to connect gives an error ” Connection rejected by server”.

Thanks,

Bikash

bikash

December 26, 2014 at 10:44 am

bikash December 27, 2014 at 6:12 am

Hi,while establishing connection with the IED getting error in method static CotpIndication parseCotpMessage(CotpConnection* self), here tpduType returning as 128.

Thanks in advance,Bikash

Bikash, do you got a solution for this? I got also 128 as pdutype when try conneting to a server

Hi Bikash, Hi Jens,can you please send me a wireshark capture file (to the email at the contact page) of the connection

attempt? I guess it is some problem with the connection parameters (maybe T selector).

Jens

January 7, 2015 at 12:26 pm

Michael Zillgith January 7, 2015 at 12:42 pm Post author

Hello, I have trouble using the reporting with the C# API and ABB relay protections. I have followed the Reporting exmple and my code looks like this:

string rc_ref = "AA1J1Q11LD0/LLN0.BR.rcb_StatUrg"; //Report is Buffered ReportControlBlock rcb = connection.GetReportControlBlock(rc_ref);rcb.GetRCBValues();

The GetRCBValues(); function throws exception with code 99 after calling

IedConnection_getRCBValues (connection, out error, objectReference, self);

Mladen March 25, 2015 at 12:55 pm

The RCB path in the protection is AA1J1Q11LD0/LLN0.rcb_StatUrg.

I have tried calling GetBufTm(); GetIntgPd(); GetTrgOps(); GetDataSetReference(); they all return 0 or

Null.I have managed to solve the issue. It is working now.

Hey Mladen,

I’m also working ABB protection equipment and I’m running into the same error you described, except I’m using the C api. How did you solve your error? My erroneous line looks like:

ClientReportControlBlock rcb = IedConnection_getRCBValues(con, &error, “REL_90LD0/LLN0.RP.rcbMeasFlt”, NULL); // Unbuffered report

I assume it is the reference string that is the issue but, if not, maybe how you solved it in C# could help me also. I’ve tried several variations of this reference string, with combinations of ‘$’, ‘/’, and ‘.’ as separators, but nothing seems to work. The best I’ve gotten is no error returned but rcb was returned as NULL,

breaking any following code.

Thanks,Chris

Hi Chris,

Mladen

April 9, 2015 at 7:43 am

Chris

June 8, 2015 at 3:15 pm

Michael Zillgith June 8, 2015 at 3:40 pm Post author

your reference string seems to be correct for me. Can you send me a wireshark capture file (e.g. by email) so I can see what the server answers? Then it should be easy to determine the problem.Regards,Michael

Hi,Please help me i stucked one error like Failed to create data set from the function in Client API C#.IedConnection_createDataSet(connection, out error, dataSetReference, linkedList);out error is giving= 20Thanks in advance,Manoj

Some server devices don’t support the CreateDataSet service. Information about that can be found in the PICS document of the server. Anyway the error code is misleading. I will change this in the upcoming version.

HI..i unable to load the iec61850 Dll file when my applicaton run.. its not taking the module iec61850 i copied this in sys32 folder…

Thnks in Advance

Manoj

August 17, 2015 at 11:05 am

Michael Zillgith August 18, 2015 at 11:41 am

Post author

Manoj September 3, 2015 at 1:30 pm

Hi Any idea why this is failed?I am not able to write value to server using following:write fail due to IED_ERROR_ACCESS_DENIED = 21/* write a variable to the server */

value = MmsValue_newVisibleString(“https://www.360docs.net/doc/aa1218133.html,”);IedConnection_writeObject(con, &error,

“simpleIOGenericIO/GGIO1.NamPlt.vendor”, DC, value);if (error != IED_ERROR_OK)printf(“failed to write simpleIOGenericIO/GGIO1.NamPlt.vendor!\n”);

Hi,if you are using this code with the server examples of libiec61850 then this is prevented by the default access rights. Per default access to variables with FC=DC and FC=CF is not allowed. To change this you have to add this code to the server:

IedServer_setWriteAccessPolicy(iedServer, IEC61850_FC_DC, ACCESS_POLICY_ALLOW);

Thank you Michael.

It works Fine for me !!Regards,

Ashwin Ashwin

October 9, 2015 at 3:38 pm

Michael Zillgith October 9, 2015 at 6:20 pm

Post author

Ashwin October 10, 2015 at 5:25 am

相关主题
相关文档
最新文档