You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js下OPC UA客户端多节点监控数据值缺失问题求助

问题:Node.js监控OPC UA多节点时值丢失

通过Node.js监控OPC UA多个节点时,发现多节点场景下无法获取节点的实际值,输出结果为监控项的元数据;但单节点监控时能正常拿到包含值的DataValue对象。


单节点监控代码

const parameters = {
    samplingInterval: 100,
    discardOldest: true,
    queueSize: 100,
};

const itemToMonitor = {
    nodeId: nodeIdToMonitor,
    attributeId: AttributeIds.Value,
};
const monitoredItem = await subscription.monitor(
    itemToMonitor,
    parameters,
    TimestampsToReturn.Both
);

monitoredItem.on("changed", (dataValue) => {
 console.log(dataValue);
});

单节点监控结果(正常)

DataValue {
  statusCode: ConstantStatusCode {
    _value: 0,
    _description: 'The operation succeeded.',
    _name: 'Good'
  },
  sourceTimestamp: 2022-11-05T09:32:53.592Z {
    high_low: [ 30994681, -1803996084 ],
    picoseconds: 378800000
  },
  sourcePicoseconds: 378800000,
  serverTimestamp: 2022-11-05T09:46:55.741Z {
    high_low: [ 30994683, -1972436892 ],
    picoseconds: 757200000
  },
  serverPicoseconds: 757200000,
  value: Variant {
    dataType: 12,
    arrayType: 0,
    value: 'VALUE 1',
    dimensions: null
  }
}

多节点监控代码(原异常代码)

const parameters = {
    samplingInterval: 100,
    discardOldest: true,
    queueSize: 100,
};

const multiNodes = [{
        nodeId:'ns=2;s=XXXXXXXX',
        attributeId: 13
    },{
        nodeId:'ns=2;s=YYYYYYYY',
        attributeId: 13
    },{
        nodeId:'ns=2;s=ZZZZZZZZ',
        attributeId: 13
}]

const monitoredItem = await subscription.monitorItems(
    multiNodes,
    parameters,
    TimestampsToReturn.Both
);

多节点监控下某节点的输出结果(异常)

<ref *1> ClientMonitoredItemImpl {
  _events: [Object: null prototype] { changed: [Function (anonymous)] },
  _eventsCount: 1,
  _maxListeners: undefined,
  statusCode: ConstantStatusCode {
    _value: 0,
    _description: 'The operation succeeded.',
    _name: 'Good'
  },
  subscription: ClientSubscriptionImpl {
    _events: [Object: null prototype] {
      error: [Function (anonymous)],
      started: [Function (anonymous)],
      keepalive: [Function (anonymous)],
      terminated: [Function (anonymous)]
    },
    _eventsCount: 4,
    _maxListeners: undefined,
    monitoredItemGroups: [ [ClientMonitoredItemGroupImpl] ],
    timeoutHint: 15000,
    _nextClientHandle: 3,
    publishEngine: ClientSidePublishEngine {
      session: [ClientSessionImpl],
      subscriptionAcknowledgements: [Array],
      subscriptionMap: [Object],
      timeoutHint: 15000,
      activeSubscriptionCount: 1,
      nbPendingPublishRequests: 4,
      nbMaxPublishRequestsAcceptedByServer: 1000,
      isSuspended: false
    },
    lastSequenceNumber: 1,
    publishingInterval: 250,
    lifetimeCount: 6000,
    maxKeepAliveCount: 50,
    maxNotificationsPerPublish: 1000,
    publishingEnabled: true,
    priority: 10,
    subscriptionId: 3904530469,
    monitoredItems: {
      '1': [Circular *1],
      '2': [ClientMonitoredItemImpl],
      '3': [ClientMonitoredItemImpl]
    },
    lastRequestSentTime: 1906-06-23T23:00:00.000Z,
    hasTimedOut: false,
    [Symbol(kCapture)]: false
  },
  itemToMonitor: ReadValueId {
    nodeId: NodeId {
      identifierType: 2,
      value: 'XXXXXXXX',
      namespace: 2
    },
    attributeId: 13,
    indexRange: NumericRange { type: 0, value: '<invalid>' },
    dataEncoding: QualifiedName { namespaceIndex: 0, name: null }
  },
  monitoringParameters: MonitoringParameters {
    clientHandle: 1,
    samplingInterval: 100,
    filter: null,
    queueSize: 100,
    discardOldest: true
  },
  monitoringMode: 2,
  timestampsToReturn: 2,
  result: MonitoredItemCreateResult {
    statusCode: ConstantStatusCode {
      _value: 0,
      _description: 'The operation succeeded.',
      _name: 'Good'
    },
    monitoredItemId: 1,
    revisedSamplingInterval: 100,
    revisedQueueSize: 100,
    filterResult: null
  },
  monitoredItemId: 1,
  filterResult: undefined,
  [Symbol(kCapture)]: false
}

问题原因与解决方法

核心原因

subscription.monitorItems()返回的是**ClientMonitoredItemImpl对象数组**,而非单个对象。原代码未为每个节点绑定changed事件,直接输出监控对象本身,导致显示的是节点元数据而非值变化。

修正后的多节点监控代码

const parameters = {
    samplingInterval: 100,
    discardOldest: true,
    queueSize: 100,
};

const multiNodes = [{
        nodeId:'ns=2;s=XXXXXXXX',
        attributeId: 13
    },{
        nodeId:'ns=2;s=YYYYYYYY',
        attributeId: 13
    },{
        nodeId:'ns=2;s=ZZZZZZZZ',
        attributeId: 13
}]

// monitorItems返回数组,需接收为数组类型
const monitoredItems = await subscription.monitorItems(
    multiNodes,
    parameters,
    TimestampsToReturn.Both
);

// 遍历每个监控项,单独绑定changed事件
monitoredItems.forEach(item => {
    item.on("changed", (dataValue) => {
        // 通过nodeId区分不同节点,输出包含实际值的DataValue
        console.log(`节点 ${item.itemToMonitor.nodeId.value} 变化值:`, dataValue);
    });
});

修正后即可和单节点场景一致,在值变化时获取到包含具体值的DataValue对象。


内容的提问来源于stack exchange,提问作者user1636103

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 13:20:31