How to integrate an external information model 

Note: This is an advanced topic which requires knowledge about OPC UA and XML file generation. In addition, some understanding of the tools UaExpert and UaModeler is required. 

This guide is based on the Process Automation Device Information Model (PA-DIM), a companion standard used in the process industry. For other information models the procedure would be similar. 

  1. Get the documents

    We'll need the companion specification and the NodeSet.xml file.

    1. The companion specification can be found on the OPC Foundation website. It contains a link to the NodeSet file, which is also available on the OPC website.
    2. For PA-DIM, an additional NodeSet.xml file with IRDI references is required. It can be found here on the OPC website.
  2. Add the NodeSets to the eUA server

    1. Copy the NodeSet.xml files into the /opt/plcnext/projects/Default/Services/OpcUA/NodeSets/ folder of the controller.
    2. The new type nodes will be available in the address space after downloading a new project, or restart of the PLC (where also the OPC server restarts). This can be seen in the namespace list of UaExpert.
      Note: There is no defined order in which the NodeSet files are loaded and therefore also no defined order of the namespace indices.
      PADIM-Namespaces.png
    3. Also the new types can be found in the address space, highlighted here in bold:
      PADIM-Types.png
      If there are issues loading the NodeSets, they are shown in the Notification Log in PLCnext Engineer. More detailed information for developers can be found in the log file.
  3. Create an instance NodeSet.xml file

    In this example, UaModeler from Unified Automation GmbH is used to create the new NodeSet manually. This is appropriate for very small projects, or to find out how the resulting NodeSet should look like. For most projects this XML file should be generated by some tool or script.
    After adding the NodeSet.xml files of DI, PADIM and IRDI, the project looks like this:

    PADIM-ModellerProject.png

    Now the first instance node can be created:

    1. Add a node named PADIMComponent of type PADIMType to the DeviceSet:
      PADIM-Modeller-AddComponent1.png
      PADIM-Modeller-AddComponent2.png
    2. Then, add some optional nodes from the base type that are required in later steps.
      PADIM-Modeller-AddOptions.png
      As a result, the address space looks like this:
      PADIM-Modeller-Component-AddressSpace.png
    3. The optionalSignalSet node is the container for the signal objects. Now add another object named DI1 of the object type TwoStateDiscreteSignalType to the SignalSet object:
      add DI1 to signal set
    4. Now test the new instance NodeSet file. Generate a NodeSet file for the new PA-DIM instance model:
      PADIM-Modeller-ExportXML.png
      As a result, there is a new padim.xml instance NodeSet file besides the UaModeler project.
    5. Copy the padim.xml instance NodeSet file to the controller into the NodeSet folder.
    6. To make the UA server reload the NodeSet files, either restart the PLC, or download some changes to the project.
      After restarting, the UaExpert shows an address space like this:
      PADIM-AddressSpace.png
      Note: The client needs to rebrowse the address space in order to reveal the changes.
      In the picture above, UaExpert is configured to highlight the namespacehttp://yourorganization.org/PADIM/. Therefore the new instance nodes are shown in bold.

    The new nodes are just static information. The next step is to get real data from PLC variables.

  4. Create a UA variable and get the value from a PLC variable

    In this step, we want to keep the node of the PA-DIM model but take the value from a PLC variable that we introduce for this purpose.

    1. To do this, extend the PLC project with a new boolean variable for the DI1 PA-DIM signal.
    2. Then determine the instance path of the variable. An easy way to do this is to look up the NodeId of the new variable in UaExpert: Download the changed PLC project and check the NodeId with UaExpert. Depending on the name and location of the variable the NodeId could look like this: "ns=4;s=Arp.Plc.Eclr/Main1.DI1.Value" The instance path is the identifier of this NodeId ("Arp.Plc.Eclr/Main1.DI1.Value").
    3. Now edit the NodeSet file again. Search for the variable with the BrowseName "3:TwoStateDiscreteSignal".
    4. Then add an extension element like this:
      <UAVariable DataType="Boolean" ParentNodeId="ns=1;i=5005" ValueRank="-2" NodeId="ns=1;i=6013" BrowseName="3:TwoStateDiscreteSignal" AccessLevel="3">
          <DisplayName>TwoStateDiscreteSignal</DisplayName>
          <References>
              <Reference ReferenceType="HasTypeDefinition">ns=3;i=1141</Reference>
              <Reference ReferenceType="HasComponent" IsForward="false">ns=1;i=5005</Reference>
              <Reference ReferenceType="Organizes" IsForward="false">ns=1;i=5005</Reference>
          </References>
          <Extensions>
              <Extension>
                  <AttributeSource xmlns="http://phoenixcontact.com/OpcUA/2019/NodeSetExtensions.xsd" GdsValueAttribute="Arp.Plc.Eclr/Main1.DI1.Value"/>
              </Extension>
          </Extensions>
      </UAVariable>
      
    5. Enter the instance path of the variable into the GdsValueAttribute.
    6. Copy the NodeSet file and restart the PLC (or download a changed project) in order to restart the OPC UA Server.
      The TwoStateDiscreteSignal variable node should have the same value as the PLC variable.
      Variable in UA Expert
      Note that the variable type is different: The PLC variable is of type BaseDataVariableType but the PA-DIM variable node is of type TwoStateDiscreteSignalVariableType which has additional properties and subvariables. A complete implementation would add similar extensions for the subvariables, and the PLC project could use a function block for the implementation that can be instantiated for all PA-DIM signals of this kind.
      Note: Since the additional properties and subvariables are optional, they need to be added to the address space manually if desired.
  5. Referencing DI properties

    Another option to get real values to the new instance space is to reference complete properties so that they appear in two places. The PADIMComponent has a SerialNumber property which is already defined in the AXC F 2152 device. In this step we want to change the NodeSet so that both objects point to the same property. Since UaModeler does not support this replacement we do it in the NodeSet.xml file directly:

    1. First, add the namespace for the Phoenix Contact devices ("http://phoenixcontact.com/OpcUA/PLCnext/Devices/") to the end of the namespace list. It is the 5th entry in the list so we get the namespace index 5.
    2. Then search for the old SerialNumber property (it has the NodeId "ns=1;i=6008") and remove it.
    3. Now replace the reference to the SerialNumber property:
      Find the Reference to the NodeId "ns=1;i=6008" and replace it with the AXC F 2152 SerialNumber property "ns=5;s=ThisDevice.SerialNumber" (its NodeId can be determined with UaExpert).
      Note: You have to change the namespace index to 5 since the namespace on the running server has a different position in the namespace array than the namespace in the document. As a result we see the serial number of the AXC F 2152 in the new PADIMComponent:
      SerialNumber in UAExpert
  6. Implementing a method as PLC function block

    Another big part of bringing the static information model to live is the support for methods. The PA-DIM example already has a method called "Factory reset". It gets a single input parameter which is an enumeration.

    1. To support this, add a new function block to the PLC project.
      It gets the input parameter of the method as input parameter with a compatible type (same binary representation).
    2. Additionally, some special variables need to be added:
      1. UA_MethodState for the state of the method execution; optionally the UA_StatusCode that the UA Method should return. The status code is of type UA_StatusCodeEnum which is already defined by the PLC. The variable declaration could look like this: PADIM-Method-Variables.png
        A minimal implementation of the function block looks like this:
        PADIM-Methd-Code.png
        When a UA client calls the method the UA_MethodState variable is set to 1 by the UA server. After that it can be freely used by the function block.
        If the variable is reset to 0 the UA server takes the status code and returns the method call to the UA client.
      2. Connecting the method of the PA-DIM model with this function block is similar to connecting variables: You just need to add an extension to the desired UAMethod element in the instance NodeSet file like this:
        <UAMethod ParentNodeId="ns=1;i=5002" NodeId="ns=1;i=7001" BrowseName="3:FactoryReset" 
              MethodDeclarationId="ns=3;i=1028">
            <DisplayName>Factory reset</DisplayName>
            <References>
                <Reference ReferenceType="HasComponent" IsForward="false">ns=1;i=5002</Reference>
                <Reference ReferenceType="HasDictionaryEntry">ns=4;s=0112/2///61987#ABN609#001</Reference>
                <Reference ReferenceType="HasProperty">ns=1;i=6012</Reference>
            </References>
            <Extensions>
                <Extension>
                    <MethodTarget xmlns="http://phoenixcontact.com/OpcUA/2019/NodeSetExtensions.xsd" 
                           FunctionBlock="Arp.Plc.Eclr/Main1.FactoryReset"/>
                </Extension>
            </Extensions>
        </UAMethod>
        
        Note: The FunctionBlock attribute needs to be the instance path to the function block instance.
    3. Restart (or download changes to the PLC) in order to restart the UA server.

So, that's it.

Use a UA client like UaExpert to call the method that is implemented in the PLC.


• Published/reviewed: 2024-09-24   ☀  Revision 073 •