1

为了确定我使用 freeopcua (Python) 实现的 OPC-UA 可能存在的问题,我同时使用 node-opcua 和 freeopcua 创建了一个相同的最小示例。问题是我收到了订阅通知,尽管值没有改变,例如:值更改为 10、10、10、10、1、1、1 等。

最后我发现这其实是PLC软件的问题。在我的本地测试 PLC 上,我无法重现此问题。通过将 PLC 更新到生产环境中使用的固件,我也遇到了这种错误行为。降级后行为消失了。

我不明白的是 node-opcua 从未表现出这种行为。并排运行 node-opcua 正常工作,而 freeopcua 示例没有。

问题是:node-opcua 是否有任何内部机制不会将所有通知传递给我的客户端,尽管它是从服务器接收到它们的。但是因为价值实际上并没有改变它忽略它们?

这是我在示例中使用的代码,是我从 Github 页面上的客户端示例修改的。

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(){});
    }) ;
4

1 回答 1

0

这似乎是一个有趣的问题!我查看了client_subscription.ts文件的详细信息。

检查第 100 行:

# Monitoring a Value Change With a DataChange  Filter

然后检查第 118-122 行

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

DataChangeFilter 类:该类用于为 DataChange 监控项设置过滤

DataChangeTrigger:这是枚举。

DataChangeTrigger.StatusValue表示:如果值的状态代码或值本身发生更改,则触发。否则,如果值保持不变,则不会发出通知。

我希望这可以深入了解 node-opcua 的内部工作。

于 2020-05-27T00:41:36.240 回答