node opc-ua - how do i discover a variable in a server?
Asked Answered
O

1

6

I am learning node opc-ua and have followed the example provided in the GitHub page for the sample_server.js and simple_client.js.

In the sample_server I add a variable when constructing the address space of the server such as:

//this code is in the server    
addressSpace.addVariable({
        componentOf: device,
        nodeId: "ns=1;s=variable_1",
        browseName: "MyVariable1",
        dataType: "Double",
        value: {
            get: function () {
                return new opcua.Variant({ dataType: opcua.DataType.Double, value: variable1 });
            }
        }
    });

Here is the whole server code for reference:

var opcua = require("node-opcua");

var server = new opcua.OPCUAServer({
    port: 4334, // the port of the listening socket of the server
    resourcePath: "UA/MyLittleServer", // this path will be added to the endpoint resource name
    buildInfo: {
        productName: "MySampleServer1",
        buildNumber: "7658",
        buildDate: new Date(2014, 5, 2)
    }
});

server.initialize(post_initialize);

function post_initialize() {
    console.log("initialized");
    construct_my_address_space(server, function () {
        server.start(function () {
            console.log("Server is now listening ... ( press CTRL+C to stop)");
            console.log("port ", server.endpoints[0].port);
            var endpointUrl = server.endpoints[0].endpointDescriptions()[0].endpointUrl;
            console.log(" the primary server endpoint url is ", endpointUrl);
        });
    });

}

function construct_my_address_space(server, callback) {

    var addressSpace = server.engine.addressSpace;

    // declare a new object
    var device = addressSpace.addObject({
        organizedBy: addressSpace.rootFolder.objects,
        browseName: "MyDevice"
    });

    // add a variable named MyVariable1 to the newly created folder "MyDevice"
    var variable1 = 1;

    // emulate variable1 changing every 500 ms
    setInterval(function () { variable1 += 1; }, 500);

    addressSpace.addVariable({
        componentOf: device,
        nodeId: "ns=1;s=variable_1",
        browseName: "MyVariable1",
        dataType: "Double",
        value: {
            get: function () {
                return new opcua.Variant({ dataType: opcua.DataType.Double, value: variable1 });
            }
        }
    });

    callback();
}

Now, in the client i want to discover this variable by name or the full nodeId. I am using the sample provided to browse the session to the server but in the return i only see FolderType, Objects, Types and Views and can not locate this variable anywhere.

Here is the client code:

var opcua = require("node-opcua");
var async = require("async");

var client = new opcua.OPCUAClient();
var endpointUrl = "opc.tcp://" + require("os").hostname() + ":4334/UA/MyLittleServer";

var the_session, the_subscription;

async.series([

    // step 1 : connect to
    function (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 (callback) {
        client.createSession(function (err, session) {
            if (!err) {
                the_session = session;
            }
            callback(err);
        });
    },

    // step 3 : browse
    function (callback) {
        the_session.browse("RootFolder", function (err, browse_result) {
            if (!err) {
                console.log('Result of browsing: ', browse_result);
                browse_result[0].references.forEach(function (reference) {
                    console.log('browsing: ', reference.browseName);
                    console.log(reference);
                    console.log("**************************************");
                });
            }
            callback(err);
        });
    },

    /* step 4 : read a variable with readVariableValue
    function (callback) {
        the_session.readVariableValue("ns=1;s=variable_1", function (err, dataValue) {
            if (!err) {
                console.log(" var 1 = ", dataValue.toString());
            }
            callback(err);
        });
    },

    // step 4' : read a variable with read
    function (callback) {
        var max_age = 0;
        var nodes_to_read = [
            { nodeId: "ns=1;s=variable_1", attributeId: opcua.AttributeIds.Value }
        ];
        the_session.read(nodes_to_read, max_age, function (err, nodes_to_read, dataValues) {
            if (!err) {
                console.log(" variable 1 = ", dataValues[0]);
            }
            callback(err);
        });
    },
    */
    // step 5: install a subscription and install a monitored item for 10 seconds
    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("subscription started for 2 seconds - subscriptionId=", the_subscription.subscriptionId);
        }).on("keepalive", function () {
            console.log("keepalive");
        }).on("terminated", function () {
            callback();
        });

        setTimeout(function () {
            the_subscription.terminate();
        }, 10000);

        // install monitored item
        var monitoredItem = the_subscription.monitor({
            nodeId: opcua.resolveNodeId("ns=1;s=variable_1"),
            attributeId: opcua.AttributeIds.Value
        },
            {
                samplingInterval: 100,
                discardOldest: true,
                queueSize: 10
            },
            opcua.read_service.TimestampsToReturn.Both
        );
        console.log("-------------------------------------");

        monitoredItem.on("changed", function (dataValue) {
            console.log("variable_1 = ", dataValue.value.value);
        });
    },

    // close session
    function (callback) {
        the_session.close(function (err) {
            if (err) {
                console.log("session closed failed ?");
            } else{
                console.log("session closed!");
            }
            callback();
        });
    }

],
    function (err) {
        if (err) {
            console.log(" failure ", err);
        } else {
            console.log("done!");
        }
        client.disconnect(function () { });
    });

Thanks in advance

Ossieossietzky answered 19/5, 2016 at 20:12 Comment(0)
L
11

You need to drill down from from the rootFolder and investigate the various objects until you find the variable you want to monitor, with a series of browseNode. The best option is to use a free OPCUA client from a commercial vendor such as UAExpert or Prosys OPC UA Client to name a few.

You can also use opcua-commander: opcua-commander This little utility will allow you to explore the address space of the server and find the node you're looking for. ( source code available on github )

Loot answered 19/5, 2016 at 21:32 Comment(2)
Thank you Etienne. Got it working now! Appreciate the help.Ossieossietzky
opcua-commander is great - much easier than writing code to discover nodes!Gap

© 2022 - 2024 — McMap. All rights reserved.