Recipe for NodeJS with IEC61850

The proliferation of distributed energy resources like photo-voltaic or wind turbines, results in increasing complexity of the power grid which in turn poses new challenges in terms of system synchronization and overall management. Consequently the European Network Code Requirements for Generators (RfG NC) had been specified, which specifies the rules and requirements for integrating power generation sources by grid operators in Europe. Based on these guidelines EU member states (along with some other countries not belonging to the EU) shall specify nation-level rules for integration of DERs.

This article describes implementation of IEC61850 protocol for the needs of real time interface (RTI) used by System Operators in the Netherlands. The goal is to orchestrate the operation of the grid with increasing number of DERs which are connected to the system. Specifically RTI shall offer to system operators a way to reduce active power output as required by RfG 2016. The following sections provide more details on the solution created by JPEmbedded in collaboration with our customer.

Application overview

In order to meet the requirements of both system operators and prosumers, a flexible and robust solution is needed, which would allow to meet the following goals:

  • reduce the risk of negative electricity prices by solar and wind turbine curtailment.
  • generate more revenue by optimal managing of storage systems charging and discharging schedules.
  • manage solar production and storage (maximization of use and peak shaving).
  • manage self-consumption to lower energy costs and increase revenue.

One of the key components of the system is the Teleport gateway. The gateway supports various communication standards such as Modbus, MQTT, SunSpec, OCPP and offers standardized JSON REST API to control all types of renewable assets. The Teleport is also secure because it establishes only encrypted, outbound connections.

In order to meet the RfG interface requirements recommended by Dutch System Operators (Netbeheer Nederland) teleport gateway has to support the IEC 61850 protocol. The 61850 Real Time Interface (RTI) is required in every renewable asset above 1 MW for its control in cases of emergency.

Java script is a massively popular programming language which at the beginning was used just for the client-side applications. With NodeJS, developers can implement also back-end applications in JavaScript. This paragraph from https://kinsta.com/knowledgebase/what-is-node-js/ captures the essence of NodeJS

“Node.js is a single-threaded, open-source, cross-platform runtime environment for building fast and scalable server-side and networking applications. It runs on the V8 JavaScript runtime engine, and it uses event-driven, non-blocking I/O architecture, which makes it efficient and suitable for real-time applications”.

JavaScript offers great deal of flexibility e.g. in using data types and variables, however when implementing IT solutions for critical infrastructure, functional safety or cyber-security are paramount, and this is why more ‘structured’ approach might be required. The answer, offering the best of both worlds, could be TypeScript. It is a super-set of JavaScript with features like typing or object oriented programming.

Integration of the IEC61850 library with NodeJS / TypeScript

For the implementation of the IEC61850 server side, software library by JPEmbedded was selected. The library is originally written in C++ language, so the task at hand was to integrate C++ component with NodeJS application. Communication between IEC61850 library and NodeJS shall realize function of reading and writing values of data model attributes,  and provide notification mechanism of user application (NodeJS) about the changes in IEC61850 data model e.g. as a result of updates by MMS client application.

At the beginning of the project different approaches were considered for integration of C++ library with NodeJS. As it is often the case, there is more than one way to skin this cat, and our initial idea was to take advantage of the framework which promises to automate the process and make the resulting interface layer more generic and reusable with other languages. The first candidate we evaluated, was Swig, but it turned out that setup of the development environment and the project itself was more troublesome than expected based on the description by the tutorial pages.

The other reason why decided not to use the ‘full-fledged framework’ is that we are an embedded software engineers and we wanted the solution to be resource efficient and have a good control over what is going on inside . Consequently, we decided to develop interface layer between NodeJS and IEC61850 library using Node-API with node-addon-api.

Node-API was introduced in Node 8.0.0 and it is a set of C language type definitions and functions for interfacing C/C++ code and NodeJS applications. Node-addon-api module is a collection of C++ classes implemented  on top of the Node-API which offers reasonable overhead / performance trade-off for developing the proxy between IEC61850 library and user application in NodeJS.

Another requirement of the customer was that user code running under NodeJS be written in TypeScript, which is a strict syntactical superset of JavaScript. The idea is that it imposes some strict rules e.g. on types of the variables used in the code, since JavaScript doesn’t really care.

There are tons of information on the Internet about Node-API, node-addon-api and JavaScript/TypeScript, and more detailed description of these, is beyond the scope of this article.

From NodeJS application point of view, there are four basic use-cases which must be supported, and all of them are briefly described below.

1 Initialization of the IEC61850 server

As a very first step, object of the interface class Iec61850ServerAPI must be created. On the NodeJS / TypeScript application side this is done with the following code:

const iec61850inst = new Iec61850ServerAPI(“./nonsecure.cfg”);

as a result, node-addon-api creates a C++ singleton object, which constructor executes the initial setup. Actual initialization of the IEC61850 server library is done by calling the method CGenServer::InitIEC61850, which takes path to the CID file as a parameter. Based on the provided CID file, IEC61850 server data model is created and MMS server thread is started listening for the incoming connections.

2 Reading the value of IEC61850 data model attribute

For reading the value of data model attribute, NodeJS application shall call Iec61850ServerAPI::IEC_attrGetValue method of the interface.

iec61850inst.iecAttrGetValue(attrHndl, attrGetV_CB)

The first argument of this call is either handle or a reference of the attribute. Second argument is callback function defined by the NodeJS application, which is called by Iec61850ServerAPI::IEC_attrGetValue, to provide the value of requested attribute. The reason for this is that there is no something like output parameter, which would return the  value from C++ function called via NodeAPI.  The return value of the C++ function is propagated to NodeJS application, but this is integer number which is used for all interface functions to provide the information about the status of the execution, 0 for success or error code in case of the failure.

3 Writing the value of IEC61850 data model attribute

To update the value of data model attribute, NodeJS application shall call Iec61850ServerAPI::IEC_attrSetValue method of the interface:

iec61850inst.iecAttrSetValue(attrHndl, attrType, attrVal)

The first parameter of this method is handle or reference of the IEC61850 attribute, the second parameter specifies data type of the value (bool, integer, float string), and the third argument contains the value itself. Value returned by the call specifies the status of the operation (success or error code)

4 Notifications of IEC61850 client activity

For the sake of performance it is very important that IEC61850 server application is promptly notified about the access of data model attributes by IEC61850 client. To address this, the IEC61850 library by JPEmbedded offers the user possibility to define callback functions which could be assigned to any attribute within the data model. There are two types of callbacks: read and write.

Read callback is invoked by the library when the value of the attribute is read by the MMS client. In some cases (it is application specific) rather than updating the value of the attribute in the data model when the change occurred, it makes more sense for the user application to register read callback, assign it to the attribute and provide the most recent value of the attribute (which might change quickly as a result of some process), when it is requested by the client.

Likewise, when the value of the attribute is updated by MMS client, IEC61850 server application shall be notified that some control operation must be executed or value of some setting on the device has changed. User defined callback is the most efficient way to do this.

Since user application is defined in NodeJS, implementation of callbacks is two-steps. First ‘regular’ read and write callbacks are implemented by C++ interface module. These are ‘generic’ callbacks which are assigned by the attributes selected by the user. On the other hand NodeJS application callbacks are defined by the user and their ‘pointers / handlers’ are passed to C++ interface module by the method Iec61850ServerAPI::IEC_cbSet. When IEC61850 client reads or writes the attribute with callback function assigned, first generic callback from C++ interface module is invoked and then it uses node-addon-api to invoke callback defined by NodeJS.

IEC61850, C++, node-addon-api, NodeJs

5 GOOSE

GOOSE is a very popular protocol defined by IEC61850-8-1 part of the standard. It provides information about the states (binary or double-binary) of settings and switches controlled by the devices (e.g. within substation). It operates according to publisher-subscriber model, with publisher sending multicast messages which are delivered as Ethernet  or UDP (routable GOOSE version) multicast.

From NodeJS application stand point, operation of GOOSE publisher is fully transparent. GOOSE publisher could be activated either by MMS client or by NodeJS application by writing to appropriate attribute. Once it is enabled, multicast GOOSE messages will be sent either periodically or after the update of the attribute which is part of the data-set associated with given GOOSE control block.

On the subscriber side, the IED could be configured with CID file, to update attributes of the data model with the values from received GOOSE messages, and the new values might be ‘delivered’ to NodeJS application using mechanisms described above.

Containerization with docker

As described so far, the whole solution depends on number of components like NodeJS, TypeScript,  node-addon-api, IEC61850 library, and user application. In order to make the package easily portable and executable across different platforms, the container technology was used. The idea behind containers is to be a light-weight form of virtualization offering application developers sand-box or namespace, where the application could run in the same environment. Container is defined by specific version of OS binaries, libraries, configuration files and application itself. Once containerized application was tested, running it under different platforms (like cloud) should work out of the box.

Probably the most popular platform for containerization is Docker, and this is the solution we used for the project. While detailed description of Docker is beyond the scope of this article, it is worth mentioning that creating the package is pretty simple, and could be summarized in three steps:

  1. Prepare ‘Dockerfile’ with information on base OS image, and software packages which must be installed on top of it.
  2. Building everything into single image with the command:

sudo docker build

  1. Running the container created with the above command

sudo docker run -i -t containerName  containerId

Conclusions

The choice of the programming language used for some project is determined by different factors like simplicity, feature-set, resource efficiency or skill-set of developers. In this article, I wanted to show our approach for developing NodeJS/TypeScript application, that uses IEC61850 server written in C++, since this seems not very common setup, at least in the embedded world.

So if you have an idea for a product featuring protocols like DNP3, IEC61850, ICCP in some ‘strange’ configuration or environment, feel free to let us know. We already have some of these under our belt, and the chances are we will be able to help.