Chapter 12. Calling OPC UA Methods from DataHub Scripts

OPC UA defines a node type called a Method that allows a client application to synchronously execute a predefined function on the server. The client calls the OPC UA method with zero or more arguments and waits for it to complete. OPC UA servers may use methods as an alternative to executing their internal functions in response to a data value change.

OPC UA methods are synchronous, and normally cannot be executed through a DataHub tunnel, because data flow through a tunnel is always asynchronous. You can, however, use a Gamma script to convert an asynchronous data change into a synchronous OPC UA method call.

Method calls are provided through a class called OpcUaSupport. You can include this in your script by adding the following line to the top of your script:

require ("OpcUaSupport");

The OpcUaSupport.g file is located in the require folder of your DataHub installation.

In your script, you can now create an instance of the OpcUaSupport class:

opcua = new OpcUaSupport(self, "UaClientConnectionLabel");

You must supply a reference to an instance of a class that derives from Application, and the label of an active OPC UA client connection on which the method will be called. This label is configured in the DataHub OPC UA properties option. The instance reference is commonly self, referring to your script instance itself.

This instance of OpcUaSupport can now be used to attach method calls to data point changes:

opcua.AddMethod(triggerPointName, feedbackPointName, parentNode, 
                methodName, triggerType, arguments…);

where:

triggerPointName

A string containing the fully qualified name of a data point that will cause this method to be called when the point value changes.

feedbackPointName

A string containing the fully qualified name of a data point to which a feedback value will be written. This point will be set to 1 if the method succeeds. If this value is nil then no feedback will be provided.

parentNode

A string or list that contains the identification of the OPC UA node that contains this method. It can be one of:

  • NodeId, a string containing the NodeId of the parent, like "ns=2;i=253".

  • BrowsePath as a string containing a dot-separated OPC UA browse path, like ""Objects.Refrigerators.Refrigerator #1""

  • BrowsePath as a list of browse names forming a BrowsePath, like ("Objects" "Refrigerators" "Refrigerator #1")

methodName

A string containing the name of the method, like "OpenCloseDoor".

triggerType

A symbol for the name of a method of the class OpcUaTriggeredMethod. This method is called to determine whether to call the OPC UA method according to logic that you supply. Two triggerType methods have been supplied for you:

  • risingTrigger(args): The OPC UA method will be called only when the triggerPoint value changes from any value to 1. This is typically used with boolean trigger points. Before the OPC UA method is called, the value of the feedbackPoint is set to 0. If the call to the OPC UA method encounters an error, the feedbackPoint will be set to -1. Finally, the value of the triggerPoint will be set to 0.

  • toggleTrigger(args): The OPC UA method will be called whenever the triggerPoint value changes. This will act as a toggle when applied to a boolean trigger point, and as an event generator when applied to a numeric or string point. If the call to the OPC UA method encounters an error, the feedbackPoint will be set to -1. Otherwise, the feedbackPoint will be set to the value of the triggerPoint.

arguments...

One or more arguments that will be passed to the OPC UA method. You must provide the number of arguments that the OPC UA method expects. These arguments are limited to numbers and strings. Methods that require complex argument types cannot be called through this mechanism. If an argument is defined a #eval(expression) then that expression will be evaluated in the context of the trigger method and supplied as the argument value.

You can add additional trigger methods by adding your own method to OpcUaTriggeredMethod, like this:

method OpcUaTriggeredMethod.myTriggerFunction(args)
{
    // Implement your logic here.  Somewhere in this code you should 
    // call .uaMethod.call(args);
    // The following variables are defined automatically 
    // in this method:
    // this – the name of the data point that triggered this method
    // value – the value of the data point that triggered this method
    // previous – the previous value of the data point that 
    //            triggered this method
}

You can add your trigger method in your own script, so long as the call to require("OpcUaSupport") is made before your trigger definition. Do not alter OpcUaSupport.g, since it will be overwritten when you upgrade the DataHub application. Look at the definitions of risingTrigger and toggleTrigger in OpcUaSupport.g for examples of how your code can be written.

Example:

The following code will call a method called OpenCloseDoor on the OPC UA node Objects.Refrigerators.Refrigerator #1 whenever the point default:fridge changes value. The feedback will be written to default:fridge_fb. The trigger function will be toggleTrigger, a method defined in OpcUaSupport.g. The value of default:fridge will be passed to the OPC UA method as the only argument.

method MyApp.constructor()
{
local opcua = new OpcUaSupport(self, "UaClientConnectionLabel");
opcua.AddMethod("default:fridge", "default:fridge_fb", 
                "Objects.Refrigerators.Refrigerator #1", 
                "OpenCloseDoor", #toggleTrigger, #eval(value));
}