#### 6.1.4 OPC UA Server and Client  
Since we want to offer the values from the production line to other users who may have OPC UA clients, it was necessary to implement an OPC UA server in Node-RED to provide these data. As already mentioned, OpenPLC runtime cannot function as an OPC UA server, as it is a free open-source tool. This is the domain of more advanced PLC solutions such as  
Figure 11: Node-RED as Modbus client. CODESYS or Siemens TIA Portal. Therefore, the OPC UA server will be created using Node-RED, to which the data arrive from OpenPLC runtime via Modbus protocol. Library _node-red-contrib-opcua 0.2.256_ was used to create OPC UA server. To **create a server**, it is necessary to use the **OPC UA server node**, where the port (in our case 53,880) and optionally its name are set. We use the default name. It is also possible to set authentication options, as OPC UA communication standard supports multiple security profiles. We use anonymous access for clarity (and since we are running on localhost). The creation of the server is also related to the creation of **address space**, i.e., variables that will initially be empty or have a predefined value, and later we will fill these variables with values that OpenPLC runtime sends using Modbus protocol. To keep our inputs and outputs clearly separated in the address space, we have created folders _FIOOutputs_ and _FIOInputs_ in it. It should be noted that the individual directives that we send to the OPC UA server node are sent using the _Inject_ node type. Thus, these directives need to be set to execute automatically when the Node-RED program is started, and it is logical that the timing needs to be set so that the directives that create the folders are executed first, and then the variables are created. This will successfully create an OPC UA server with the desired address space. We will use the following directives (but there are several supported): **addFolder**, **setFolder** and **addVariable**. The directives are bound to the _msg.payload_ of messages in Node-RED and the content itself to the msg.topic of messages. This can be seen in Figure 12, which shows the creation of the _FIOOutputs_ folder. In _msg.payload_ there is a command to add the folder and in _msg.topic_ there is the defined namespace and folder name. Adding the _RetroreflectiveSensor1_ variable would look like this, and it is obvious that the variable's data type is also set:  
* msg.payload: {\"opcuaCommand\":\"addVariable\"};  
Figure 12: Creating OPC UA server and its address space in Node-RED. msg.topic: ns=1;s=RetroreflectiveSensor1;datatype=Boolean. In order to be able to populate variables with data, we needed to create a custom function in JavaScript, since in Node-RED it is not necessary to use only the built-in nodes, it is also possible to create your own. Notice in Figure 11 the node named **Function: Modbus to OPC UA namespace**, i.e., the node representing our own function. Specifically, we will describe the node that is connected to the node _Modbus Read- %QX0.0-7_. The _Modbus Read- %QX0.0-7_ node sends an array of 8 values (of type BOOL) to the _Function: Modbus to OPC UA namespace_ node. Figure 13 shows the contents of the node. For each value received from Modbus, we have pre-prepared an empty variable (_msg0, msg1, msg2,..._) where we store the elements of the array. In their payload we store the value itself (of type BOOL), but the more interesting part is _msg.topic_. Here, according to the documentation of the OPC UA client installed in Node-RED, we need to define which variable in the OPC UA address space the variable will go to. Thus, we have defined the namespace ID (abbreviated _ns_), the variable name and the data type that matches the input variables obtained from Modbus server. Then the _Function: Modbus to OPC UA namespace_ node is connected to **OPC UA client** node, which stores the values in our OPC UA server. We can also provide values from our OPC UA server to clients other than the client installed in Node-RED.