1

To identify a possible problem with my OPC-UA implementation using freeopcua (Python) I created simultaneously an identical minimal example using node-opcua and freeopcua. The issue is that I received notifications for subscriptions although the value did not change, e. g.: value change to 10, 10 10, 10, 1, 1, 1 etc.

At the end, I found that this is in fact a PLC software issue. On my local testing PLC, I was not able to reproduce this issue. By updating the PLC to the firmware that was used in the productive environment I also got this faulty behavior. After downgrading the behavior was gone.

What I do not understand is that node-opcua did never show this behavior. Running side by side node-opcua worked correctly while the freeopcua example did not.

The question is: does node-opcua have any kind of internal mechanism that does not pass all notifications to my client although it received them from the server. But because the value did actually not change it disregards them?

This is the code I used in my example that I modified from the client example on the Github page.

var opcua = require("node-opcua");
var async = require("async");
var endpointUrl = "opc.tcp://<ip>:4840";

var client = new opcua.OPCUAClient({ endpoint_must_exist: false });
var the_session = null;
var sub_node = "ns=3;s=Path.To.Node"

async.series([
    function(callback)  {
        client.connect(endpointUrl,function (err) {
            if(err) {
                console.log(" cannot connect to endpoint :" , endpointUrl );
            } else {
                console.log("connected !");
            }
            callback(err);
        });
    },

    function(callback) {
        client.createSession( function(err,session) {
            if(!err) {
                the_session = session;
            }
            callback(err);
        });

    },

    function(callback) {
        the_subscription=new opcua.ClientSubscription(the_session,{
            requestedPublishingInterval: 1000,
            requestedLifetimeCount: 10,
            requestedMaxKeepAliveCount: 2,
            maxNotificationsPerPublish: 10,
            publishingEnabled: true,
            priority: 10
        });
        the_subscription.on("started",function(){
            console.log("started");
        }).on("keepalive",function(){
            console.log("keepalive");
        }).on("terminated",function(){
            callback();
        });
        setTimeout(function(){
            the_subscription.terminate();
        }, 1000000);

        var monitoredItem  = the_subscription.monitor({
            nodeId: opcua.resolveNodeId(sub_node),
            attributeId: opcua.AttributeIds.Value
        }, {
            samplingInterval: 100,
            discardOldest: true,
            queueSize: 10
        });

        monitoredItem.on("changed",function(value){
           console.log(new Date(), "- Data Change -", value.value.value);
        });

    },

    function(callback) {
        console.log(" closing session");
        the_session.close(function(err){
            console.log(" session closed");
            callback();
        });
    },
],
    function(err) {
        if (err) {
            console.log(" failure ",err);
        } else {
            console.log("done!")
        }
        client.disconnect(function(){});
    }) ;
ap0
  • 1,083
  • 1
  • 12
  • 37

1 Answers1

0

This seems to be interesting question! I looked into details of client_subscription.ts file.

Check line number 100:

# Monitoring a Value Change With a DataChange  Filter

Then check lines 118-122

filter: new DataChangeFilter({
              trigger: DataChangeTrigger.StatusValue,
              deadbandType: DeadbandType.Absolute,
              deadbandValue: 0.1
         }),

DataChangeFilter class : This class is used to set up filtering for a DataChange monitored item

DataChangeTrigger : This is Enum.

DataChangeTrigger.StatusValue means: Triggers if the value's status code or the value itself changes. Otherwise there is no notification if value stays the same.

I hope this gives insight into internal working of node-opcua.