Using the UA Method Call

The system’s OPC UA Server supports the UA service set allowing for methods to be to be called from UA clients. This section shows you how to use the ExecFunction method that is available on the system OPC UA Server. This function allows you to call Lua functions that are stored in a Script Library on the Core Object.

It is recommended to follow the How to section on Connecting to the System OPC UA Server before following this section’s tutorial. It will explain about making an initial connection and configuring security and authentication settings that can be important when attempting to call methods from a UA client.
  1. UA methods are not available by default in the server and must be activated. To do this, select the OPC UA TCP Server object in the Server Model and open the Capabilities property compound in the Object Properties Panel. Check the checkbox for Enable Method Service Set and click Apply to confirm the changes.

    Enable Method Service Set
    Figure 1. Enable Method Service Set
  2. Open the OPC UA client that you wish to connect to the system OPC UA Server with (for this example, we will use Prosys OPC UA Browser).

  3. Connect to the OPC Server with the client (follow the Connecting to the System OPC UA Server for guidance if required).

    If you are using a User Name and Password to connect to the UA Endpoint (recommended), the Profile object that the User Name maps to should have sufficient permissions assigned to carry out the actions of an executed script. For this example, the Profile used should have List/Read/Inheritable permissions set on the Core that the Server is connected to. The General Authorization - Profile User Access should also allow "OPC UA Connections".
  4. After connection, expand the "Objects" node and then the "Server" node in the namespace explorer view, and select the "ExecFunction" method.

    .Server Node - ExecFunction
    Figure 2. Server Node - ExecFunction
    If you do not see the "ExecFunction" method return to the first step and check that Enable Method Service Set has been activated.

Method Call - Example 1

The "ExecFunction" method accepts a single string as an argument to input into a Lua function. This example demonstrates this with a simple Read function where the path of an object to be read is the input argument.

  1. Right-click on the "ExecFunction" method and select Call Method…​ from the context menu to open the Call Method dialog. Here the input arguments for the call can be added:

    • Library: Module Name of the Script Library on the Core.

    • Function: The name of a function contained in the aforementioned Script Library.

    • Arguments: The input argument for the function.

      Call Method Dialog
      Figure 3. Call Method Dialog
  2. We will now add a Script Library on the Core containing a function to read the value of a Generic Item that is generating numeric values (please create the Generic Item or use another item in your namespace that has generated data). Select the Core in the I/O Model of DataStudio and click the + button by the Script Library property compound. Fill in the Module Name (this will be used for the "Library" input argument in the Call Method dialog of the UA client) and in Lua Script Body, add the following Lua script:

    local lib ={}
    function lib:read(arg)
        local arg = arg or ""
    
        -- Check that the object exists
        local obj = syslib.getobject(arg)
        if obj == nil then
            error(("Object '%s' does not exist in the system"):format(arg)) -- raise lua error for execution exceptions
        end
    
        -- Read value and return
        local v = syslib.getvalue(arg);
    
        return v
    end
    return lib

    Click OK to close the script editor and then Apply to confirm the changes in the Object Properties panel.

    Library Structure - Structuring the Script Library with functions between the lib ={} declaration (and returning `lib at the end) allows for multiple functions to be defined in a single library.
    Error Messaging - Adding error handling within the script library means that any error will be returned as the output of the ExecFunction method call. This means that detailed error messaging can be added at script level to aid with troubleshooting.
    Script Library - Core
    Figure 4. Script Library - Core
  3. Once the Script Library is in place on the Core, return to the UA Client and enter the input values in the Call Method dialog. For Library, enter the Module Name of the Script Library (in this example "uamethodcall"). For Function, enter "read", and for the Arguments, enter the path to the Generic Item created in the earlier step.

    Call Method - Arguments
    Figure 5. Call Method - Arguments
  4. Click Call in the UA client - if configuration has been completed correctly the value of the Generic Item should be returned as the result of the call (with UA Status 0 - indicating that the call was successful).

    Call Method Success
    Figure 6. Call Method Success
  5. If the Profile being used to connect to the Server does not have sufficient permissions to read the object value then the call fails and an error will be returned (the UA Status code can be looked up here).

    Call Method - Permission Denied
    Figure 7. Call Method - Permission Denied
  6. As an example of the in script error handling, if the object path cannot be resolved, the error message will be returned as the output of the method call (again, the UA Status code can be looked up here).

    Call Method - Error Reporting
    Figure 8. Call Method - Error Reporting
  7. If the inputs in the Call Method dialog are invalid then the method call will fail. This includes if the Script Library does not exist on the Core or if the library does not contain the specified function.

    Call Method Fail
    Figure 9. Call Method Fail

Method Call - Example 2

In this example a function to create a Generic Item in the I/O Model will be demonstrated. To create the object, 2 input arguments are needed - the path to a parent object and an Object Name. The ExecFunction method only accepts a single string input argument so we will use a JSON string as input and process the component fields as part of the embedded Lua Script Library on the Core.

  1. Right-click on the "ExecFunction" method and select Call Method…​ from the context menu to open the Call Method dialog. Here the input arguments for the call can be added:

    • Library: Module Name of the Script Library on the Core.

    • Function: The name of a function contained in the aforementioned Script Library.

    • Arguments: The input argument for the function.

      Call Method Dialog
      Figure 10. Call Method Dialog
  2. We will now add a Script Library on the Core containing a function to read the value of a Generic Item that is generating numeric values (please create the Generic Item or use another item in your namespace that has generated data). Select the Core in the I/O Model of DataStudio and click the + button by the Script Library property compound. Fill in the Module Name (this will be used for the "Library" input argument in the Call Method dialog of the UA client) and in Lua Script Body, add the following Lua script:

    local lib ={}
    function lib:createobject(arg)
    	local json= require"rapidjson"
        local argTable = json.decode(arg)
        local objParentPath = argTable.parentpath
        local objName = argTable.name
    	local objClass = argTable.class
    
    	-- Check that parent object exists
    	local obj = syslib.getobject(objParentPath)
        	if obj == nil then
            	error(("Parent Path '%s' does not exist in the system"):format(objParentPath)) -- raise lua error for execution exceptions
        	end
    
    	--Create object with syslib.mass function
    	syslib.mass({
    		{
    			class = syslib.model.classes[objClass],
    			operation = syslib.model.codes.MassOp.UPSERT,
    			path =  objParentPath .. "/" .. objName,
    			["ObjectName"] = objName
    		}
    	})
    
        --Return message if successful
        return string.format("%s Object with Name %s has been created", objClass, objName)
    end
    return lib

    Click OK to close the script editor and then Apply to confirm the changes in the Object Properties panel.

    The createobject function can also be added to the same Script Library as in the first example, just the function should be added as the lib={} and return lib are already included.
    This function takes a JSON string as its argument and processes the constituent parts of the single string to be able to create the object in the I/O Model using the syslib.mass function.
  3. Once the Script Library is in place on the Core, return to the UA Client and enter the input values in the Call Method dialog. For Library, enter the Module Name of the Script Library (in this example "uamethodcall"). For Function, enter "createobject", and for the Arguments, enter the following JSON string:

    {"parentpath": "/System/Core", "name": "TestGenItem", "class": "GenItem"}
    Call Method Arguments - Create Object
    Figure 11. Call Method Arguments - Create Object
  4. Click Call in the UA client - if configuration has been completed correctly, a Generic Item named "TestGenItem" should be created beneath the Core. The returned result of the method call is the message configured in the createobject function.

    Call Method Success- Create Object
    Figure 12. Call Method Success - Create Object
  5. As an example of the in script error handling, if the object’s parent path cannot be resolved, the error message will be returned as the output of the method call (the UA Status code can be looked up here).

    Call Method Create Object - Error Reporting
    Figure 13. Call Method Create Object - Error Reporting
  6. If the inputs in the Call Method dialog are invalid then the method call will fail. This includes if the Script Library does not exist on the Core or if the library does not contain the specified function.

    Call Method Fail - Create Object
    Figure 14. Call Method Fail - Create Object

Method Call Timeout

The timeout for method calls can be configured on the Server side in the Call Timeout property (part of the Service Settings property compound) on the OPC UA TCP Server object.

If the method call is not completed within the configured timeout then the call will return a message saying that the timeout was exceeded (and the UA Status code for timeout).

Call Method - Timeout Exceeded
Figure 15. Call Method - Timeout Exceeded

If a longer (or shorter) method call timeout is configured on the client side then the Call Timeout on the Server is ignored and the client timeout used instead.

Method Call Performance Counters

The OPC UA TCP Server object also has Performance Counters (accessible in the Performance Tab of the Object Properties panel) to monitor the active/successful/failed UA method calls made on the server.

Method Call Performance Counters
Figure 16. Method Call Performance Counters

Diagnostic Logging

Enabling the Diagnostic Logging property on the OPC UA TCP Server object will write any failed UA method calls to the System Log. These can be accessed by opening a Log Display and filtered by dragging and dropping the UA server object into the display.

The diagnostic logging will not log method calls that failed due to timeout.
System Log - Method Call Errors
Figure 17. System Log - Method Call Errors