Node-RED Module¶
Configuration Example¶
Example section from configuration file:
<node-red>
<executable>node-red</executable>
<settings-path>/etc/node-red.js</settings-path>
<theme>dark</theme>
<flow-path>/etc/node-red.json</flow-path>
<authentiation>
<editor username="admin" password="admin"></editor>
<ui username="admin" password="admin"></ui>
</authentication>
<endpoint host="0.0.0.0" port="1880"></endpoint>
</node-red>
In this example, we run a Node-RED server listening on port 1880
on all
interfaces with authentication enabled and loading the existing flow described
in the JSON file located at /etc/node-red.json
. Except for flow-path
and
authentication
, all of the settings in this example are the defaults. The
default value for flow-path
is an empty string, causing Node-RED to load an
empty flow when it starts up. The authentication
setting is empty by default,
causing the editor and UI to be accessible without credentials.
To use all the default settings, just add <node-red></node-red>
to the OT-sim
configuration file.
Node-RED Module Overview¶
OT-sim is capable of integrating with Node-RED using custom Node-RED nodes
distributed as part of the OT-sim source code. The Node-RED integration is
enabled and configured using the OT-sim node-red
module as described above,
which runs a Node-RED server alongside OT-sim for users to access.
Two custom OT-sim Node-RED nodes are available, ot-sim in
and ot-sim out
.
Each node is automatically configured with the correct OT-sim message bus
endpoints to connect to via the Node-RED settings file that is generated by the
OT-sim module.
There are at least two ways the Node-RED integration can prove useful:
- Using Node-RED flows to provide an HMI
- Using Node-RED flows as a replacement for the logic module
Demo Video¶
This video demonstrates the use of Node-RED with OT-sim as a simple Human Machine Interface (HMI) that monitors the per-unit voltage of Bus 692 and controls the breaker status of Line 650632.
The Procfile.single
process file is used in the video, which starts a HELICS
broker, an OpenDSS federate running a simulation of the IEEE 13 bus system, and
an OT-sim device using the config/single-device/device.xml
configuration file.
This configuration file starts, among other things, the I/O module (a HELICS
federate) and the Node-RED module.
To recreate the environment in the video, execute the following steps:
- Build the
ot-sim
Docker image:docker build -t ot-sim .
- Run an
ot-sim
Docker container:docker run -it --rm --net host ot-sim bash
- Execute the process file in the container:
hivemind Procfile.single
- Browse to Node-RED: http://localhost:1880
- Press
ctrl-i
in the Node-RED editor and import the following flow
[
{
"id": "172c64bad7a4e035",
"type": "tab",
"label": "Flow 1",
"disabled": false,
"info": "",
"env": []
},
{
"id": "42fb9f9b2e9aae42",
"type": "ot-sim in",
"z": "172c64bad7a4e035",
"tag": "bus-692.voltage",
"updates": false,
"x": 200,
"y": 320,
"wires": [
[
"2ea9878d91da5797"
]
]
},
{
"id": "2ea9878d91da5797",
"type": "ui_gauge",
"z": "172c64bad7a4e035",
"name": "",
"group": "cd530edaea3a5672",
"order": 1,
"width": 0,
"height": 0,
"gtype": "gage",
"title": "Bus 692 Voltage",
"label": "p.u.",
"format": "{{value | number:3}}",
"min": "0.9",
"max": "1.35",
"colors": [
"#ca3838",
"#00b500",
"#ca3838"
],
"seg1": "0.96",
"seg2": "1.1",
"diff": false,
"className": "",
"x": 860,
"y": 320,
"wires": []
},
{
"id": "1b2b2a5122909a56",
"type": "ot-sim out",
"z": "172c64bad7a4e035",
"tag": "line-650632.closed",
"x": 870,
"y": 480,
"wires": []
},
{
"id": "0abc55bd5a667739",
"type": "ui_button",
"z": "172c64bad7a4e035",
"name": "",
"group": "cd530edaea3a5672",
"order": 2,
"width": 0,
"height": 0,
"passthru": false,
"label": "Trip",
"tooltip": "",
"color": "",
"bgcolor": "green",
"className": "",
"icon": "",
"payload": "0",
"payloadType": "str",
"topic": "topic",
"topicType": "msg",
"x": 570,
"y": 400,
"wires": [
[
"1b2b2a5122909a56"
]
]
},
{
"id": "3bea0bd21f09d964",
"type": "ui_button",
"z": "172c64bad7a4e035",
"name": "",
"group": "cd530edaea3a5672",
"order": 3,
"width": 0,
"height": 0,
"passthru": false,
"label": "Close",
"tooltip": "",
"color": "",
"bgcolor": "red",
"className": "",
"icon": "",
"payload": "1",
"payloadType": "str",
"topic": "topic",
"topicType": "msg",
"x": 570,
"y": 540,
"wires": [
[
"1b2b2a5122909a56"
]
]
},
{
"id": "9c5eaebffe2ff15e",
"type": "ot-sim in",
"z": "172c64bad7a4e035",
"tag": "line-650632.closed",
"updates": false,
"x": 130,
"y": 480,
"wires": [
[
"5350b0834d821a9d",
"104a4cdbed5f1039"
]
]
},
{
"id": "5350b0834d821a9d",
"type": "change",
"z": "172c64bad7a4e035",
"name": "Trip Enabled",
"rules": [
{
"t": "set",
"p": "enabled",
"pt": "msg",
"to": "msg.payload = 1",
"tot": "jsonata"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 350,
"y": 440,
"wires": [
[
"0abc55bd5a667739"
]
]
},
{
"id": "104a4cdbed5f1039",
"type": "change",
"z": "172c64bad7a4e035",
"name": "Close Enabled",
"rules": [
{
"t": "set",
"p": "enabled",
"pt": "msg",
"to": "msg.payload = 0",
"tot": "jsonata"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 360,
"y": 520,
"wires": [
[
"3bea0bd21f09d964"
]
]
},
{
"id": "cd530edaea3a5672",
"type": "ui_group",
"name": "Default",
"tab": "893465dd7a980296",
"order": 1,
"disp": true,
"width": "6",
"collapse": false,
"className": ""
},
{
"id": "893465dd7a980296",
"type": "ui_tab",
"name": "Home",
"icon": "dashboard",
"disabled": false,
"hidden": false
}
]
ot-sim in
¶
The ot-sim in
node subscribes to the RUNTIME
topic on the OT-sim message bus
and processes Status
messages published by OT-sim devices. The node is
configured with a tag, and outputs the tag name as the message topic and the tag
value as the message payload to other nodes it's connected to in the flow. This
node can be configured to also process Update
messages via the Include
Updates
checkbox in the node editor.
ot-sim out
¶
The ot-sim out
node pushes Update
messages to the RUNTIME
topic on the
OT-sim message bus. The node is configured with a tag, and pushes incoming
values from nodes connected to it in the flow as updates for the tag.