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:
triggerPointNameA string containing the fully qualified name of a data point that will cause this method to be called when the point value changes.
feedbackPointNameA 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.
parentNodeA 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")
methodNameA string containing the name of the method, like
"OpenCloseDoor".
triggerTypeA 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(:
The OPC UA method will be called only when the
args)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(:
The OPC UA method will be called whenever the
args)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.
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));
}