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

使用QOpcUaClient接收OPC UA服务器事件失败求助

问题解决:QOpcUaClient事件订阅失败及indexRange说明

一、事件订阅失败(BadInternalError)的修复方案

1. 移除无效的indexRange设置

你的代码中monitoringParams.setIndexRange("0:20");是错误操作:EventNotifier是单值枚举属性,不支持indexRange参数,该参数仅适用于数组/字符串类型的属性。移除这一行代码可消除部分内部错误。

2. 修正EventFilter的属性操作数

OPC UA的事件过滤器要求明确指定属性所属的事件类型节点(如标准的BaseEventType),否则服务器无法解析属性路径。修改后的过滤器代码如下:

m_eventNode.reset(mOpcUaClient->node("ns=2;s=testObject"));
QOpcUaMonitoringParameters monitoringParams(1000);

QOpcUaMonitoringParameters::EventFilter filter;

// 构造Select Clause:指定BaseEventType下的Message属性
QOpcUaSimpleAttributeOperand messageOperand;
messageOperand.setNodeId(QOpcUa::nodeIdFromNumeric(0, QOpcUa::BaseEventType)); // 标准BaseEventType的NodeId
messageOperand.setAttributeId(QOpcUa::NodeAttribute::Value);
messageOperand.setBrowsePath({QStringLiteral("Message")});
filter << messageOperand;

// 构造Where Clause:Severity >=10
QOpcUaContentFilterElement condition;
condition << QOpcUaContentFilterElement::FilterOperator::GreaterThanOrEqual;

QOpcUaSimpleAttributeOperand severityOperand;
severityOperand.setNodeId(QOpcUa::nodeIdFromNumeric(0, QOpcUa::BaseEventType));
severityOperand.setAttributeId(QOpcUa::NodeAttribute::Value);
severityOperand.setBrowsePath({QStringLiteral("Severity")});
condition << severityOperand;

condition << QOpcUaLiteralOperand(10, QOpcUa::Types::UInt16);
filter << condition;

monitoringParams.setFilter(filter);

// 检查enableMonitoring的返回值,确认订阅是否成功
bool success = m_eventNode->enableMonitoring(QOpcUa::NodeAttribute::EventNotifier, monitoringParams);
qDebug() << "订阅事件结果:" << success;

QObject::connect(m_eventNode.data(), &QOpcUaNode::eventOccurred, [](const QOpcUaEventData &eventData) {
    qDebug() << "OPC UA Event occurred";
    // 可打印事件详情,比如Message和Severity
    qDebug() << "事件消息:" << eventData.value(QStringLiteral("Message")).toString();
    qDebug() << "事件等级:" << eventData.value(QStringLiteral("Severity")).toUInt();
});

3. 确认节点的EventNotifier权限

用UA Expert检查ns=2;s=testObject节点的EventNotifier属性,确保其值包含SubscribeToEvents(十六进制0x01)。如果该属性值为0,则节点不允许订阅事件,需要修改服务器配置。

二、indexRange参数说明

setIndexRange()用于指定数组、字符串或字节串类型节点属性的读取/订阅范围,格式为start:end(0起始索引):

  • 0:20:表示读取数组第0到第20个元素(包含两端)
  • 5::表示读取从第5个元素到末尾的所有元素
  • :3:表示读取从开头到第3个元素的所有元素
  • 仅当节点属性是数组、字符串或字节串时,该参数才有效;对于单值类型(如EventNotifier、普通数值),设置此参数会引发错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 05:10:18