node-opcua / node-opcua

Unlocking the Full Potential of OPC UA with Typescript and NodeJS - http://node-opcua.github.io/
MIT License
1.47k stars 481 forks source link

Strange behaviour browsing and subscribe Ignition OPC server #366

Closed sanlop73 closed 6 years ago

sanlop73 commented 7 years ago

Hi:

I am trying to create an small script to browse and subscribe the browse result. Could you please help me to identify if i m doing something wrong? Script is giving this error in every item, just once, then the script continues. The problem is i am using async.series and the tasks defined after this one are not being executed due the error.

Thanks in advance for your help.

Error is 👍 Exception raised inside the event handler called by ClientMonitoredItem.on('change') TypeError: Cannot read property 'value' of null
    at ClientMonitoredItem.<anonymous> (/usr/local/src/opc-client-kafka/test2.js:154:117)
    at emitOne (events.js:96:13)
    at ClientMonitoredItem.emit (events.js:188:7)
    at ClientMonitoredItemBase._notify_value_change (/usr/local/src/opc-client-kafka/node_modules/node-opcua/lib/client/client_monitored_item_base.js:45:13)
    at /usr/local/src/opc-client-kafka/node_modules/node-opcua/lib/client/client_subscription.js:194:32
    at Array.forEach (native)
    at ClientSubscription.__on_publish_response_DataChangeNotification (/usr/local/src/opc-client-kafka/node_modules/node-opcua/lib/client/client_subscription.js:186:20)
    at /usr/local/src/opc-client-kafka/node_modules/node-opcua/lib/client/client_subscription.js:296:26
    at Array.forEach (native)
    at ClientSubscription.onNotificationMessage (/usr/local/src/opc-client-kafka/node_modules/node-opcua/lib/client/client_subscription.js:291:26)
Please verify the application using this node-opcua client

Result of Folder browse is an array:

[ 'ns=2;s=[default]EA6/ambientHum',
  'ns=2;s=[default]EA6/ambientHum 3',
  'ns=2;s=[default]EA6/RefrigerationAcumulatorLevel 5',
  'ns=2;s=[default]EA6/RefrigerationAcumulatorLevel 2',
  'ns=2;s=[default]EA6/RefrigerationAcumulatorLevel 1',
  'ns=2;s=[default]EA6/RefrigerationAcumulatorLevel 4',
  'ns=2;s=[default]EA6/ambientHum 1',
  'ns=2;s=[default]EA6/RefrigerationAcumulatorLevel 3',
  'ns=2;s=[default]EA6/RefrigerationAcumulatorLevel',
  'ns=2;s=[default]EA6/RefrigerationambientTemp',
  'ns=2;s=[default]EA6/ambientHum 2' ]

And here is my code.

//Usage 
//node opc-client.js --OPCServer "opc.tcp://172.25.48.10:4096" --OPCPath "ns=2;s=[default]A-FAGOR5" --KafkaServer "172.25.48.10:9092" --KafkaTopic "0013-CM" --Plant "0013" --Fl "0815471108154711" --Equ "XXXX"
var stdio = require('stdio');
var options = stdio.getopt({
    'OPCServer': {description: 'OPC server URL opc.tcp://<IP address>:<port> , example "opc.tcp://172.24.16.177:4096"', mandatory: true, args: 1},
    'OPCPath': {description: 'OPC server path  , example "ns=1;s=[Demo]_Meta:Refrigeration", Ensure sub folder Subscription is created', mandatory: true, args: 1}, 
    'KafkaServer': {description: 'Kafka server <IP address>:<port> , example "172.24.16.177:9092"', mandatory: true, args: 1},
    'KafkaTopic': {description: 'Kafka Topic  ', mandatory: true, args: 1},
    'Plant': {description: 'BAT Global Plant Number', mandatory: true, args: 1},
    'Fl': {description: 'BAT Cost Center', mandatory: true, args: 1}, 
    'Equ': {description: 'BAT Workcenter/Equipment', mandatory: true, args: 1}, 
});

require('events').EventEmitter.defaultMaxListeners = Infinity;
var opcua = require("node-opcua");
var async = require("async");
var Kafka = require('node-rdkafka');
var splitArray = require('split-array');
var arrayCompare = require("array-compare");
var sleep = require('sleep');
var fs  = require("fs");
var moment = require("moment");
var tagsreadini = [];
var tagsubscriptionini = [];
var tagsreadpos = [];
var tagsubscriptionpos = [];
var tagsreadSplit = [];
var tagssubscriptionSplit = [];

var opcpath = options.OPCPath;
var opcpathsubscription = options.OPCPath + "/Subscription";
//var opcpathsubscription = options.OPCPath;

var datatype = [];

var plant = options.Plant;
var fl = options.Fl;
var equ = options.Equ;
var comment = 'dummy2134'

var now = new Date();

var message = "";

var optionsopc = {
    connectionStrategy: {
        maxRetry: 100000
    }
  };

var client = new opcua.OPCUAClient(optionsopc);
var endpointUrl = options.OPCServer;
var the_session, the_subscription;

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

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

    callback(err);
    });
    }

// step 3B : Browse Subscription INI

   // step 3 : browse
    function browse(callback) {
        the_session.browse(opcpath, function (err, browse_result) {
            if (!err) {
                console.log('Result of browsing: ', browse_result);
                browse_result[0].references.forEach(function (reference) {
                        //console.log("**************************************");
            //console.log('browsing: ', reference.nodeId.value);
            //console.log('browsing: ', reference.nodeId.namespace);
            //console.log(reference.nodeId.identifierType);
            //console.log(reference.typeDefinition);       
            //console.log(reference.displayName);
            //console.log(reference.browseName);
            //console.log(reference.isForward);
            //console.log(reference.referenceTypeId);
            //console.log('browsing: ', reference.nodeId.namespace + " " + reference.nodeId.value + " " + reference.nodeId.identifierType);
            //console.log('browsing: ', "ns=" + reference.nodeId.namespace + ";s=" + reference.nodeId.value);
                        //console.log('browsing: ', reference.nodeClass);   
                        tagdef = "ns=" + reference.nodeId.namespace + ";s=" + reference.nodeId.value;
            if (reference.nodeClass == "2"){
                    tagsreadini.push(tagdef);
                }
                });
                       console.log(tagsreadini);
            }
            callback(err);
        });
    }

// step 5' : Subscription 1

    function subscription1(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("subscription started - subscriptionId=",the_subscription.subscriptionId);
     }).on("keepalive",function(){
        console.log("keepalive");
     }).on("terminated",function(){
    callback();
    });

    // install monitored item
    async.each(tagsreadini, function(nodeid, callback) {
       var monitoredItem  = the_subscription.monitor({
           nodeId: opcua.resolveNodeId(nodeid),
           attributeId: 13
       },
       {
           samplingInterval: 1000,
           discardOldest: true,
           queueSize: 10
       },
       opcua.read_service.TimestampsToReturn.Both
       );
       monitoredItem.on("changed",function(dataValue){
                var readmessage = JSON.stringify({'timestamp':dataValue.serverTimestamp,'value':dataValue.value.value});
                console.log(readmessage);

        });
    }); // Fin Async Each
  }

async.series([connect,createSession,browse,subscription1]);
erossignon commented 6 years ago

It looks like dataValue.value is null, this causes the exception in the monitoredItem.on("change",..) event handler function in this line:

var readmessage = JSON.stringify({'timestamp':dataValue.serverTimestamp,'value':dataValue.value.value});

I would try:

       monitoredItem.on("changed",function(dataValue){
                var readmessage = dataValue.toString();
                console.log(readmessage);
        });

Please check carefully the dataValue.statusCode which is probably not StatusCodes.Good , this will give you some hint about why the dataValue.value is null.