QtOpcUa仅单个节点值可被监控的问题排查求助
Qt6 OPC UA客户端仅监控到单个节点的问题
环境与需求
Ubuntu 22.04下运行Qt6控制台应用,连接多个支持OPC UA的PLC,目标是监控多个variable类型节点的值。注:无法提供完整可运行示例(无实际远程设备模拟),可补充细节。
节点处理结构体与插入逻辑
typedef struct { QOpcUaNode *node; // OPC UA节点实例 QVariant value; // 内部存储值 bool updated; // 更新标记(与问题无关) bool enableRead; // 是否启用读取 } Node_t; void MyOpcUa::insertNode(QString key, QString id, bool enableRead) { Node_t node; // 自定义节点结构体实例 node.node = _opcUaClient->node(id); // 获取OPC UA节点 node.value = QVariant(); node.updated = false; node.enableRead = enableRead; Q_ASSERT(node.node); // 校验节点有效性 _mapOpcNodes.insert(key, node); connect(node.node, &QOpcUaNode::attributeRead, this, &MyOpcUa::handleAttributes); connect(node.node, &QOpcUaNode::attributeUpdated, this, &MyOpcUa::handleAttributes); // 预期读取属性时触发handleAttributes }
OPC UA客户端连接逻辑
void MyOpcUa::createClient() { if (_opcUaClient) { delete _opcUaClient; _opcUaClient = nullptr; } Q_ASSERT(_opcUaClient == nullptr); if (_opcUaClient == nullptr) { _opcUaClient = _opcUaProvider->createClient(OPC_UA_BACKEND); if (!_opcUaClient) { qInfo() << ID << _name << "Connection to server failed:" << _opcUaClient->error(); return; } connect(_opcUaClient, &QOpcUaClient::connectError, this, &MyOpcUa::connectError); _opcUaClient->setApplicationIdentity(_identity); _opcUaClient->setPkiConfiguration(*_pkiConfig); if (_opcUaClient->supportedUserTokenTypes().contains(QOpcUaUserTokenPolicy::TokenType::Certificate)) { QOpcUaAuthenticationInformation authInfo; authInfo.setCertificateAuthentication(); _opcUaClient->setAuthenticationInformation(authInfo); } connect(_opcUaClient, &QOpcUaClient::connected, this, &MyOpcUa::clientConnected); connect(_opcUaClient, &QOpcUaClient::disconnected, this, &MyOpcUa::clientDisconnected); connect(_opcUaClient, &QOpcUaClient::errorChanged, this, &MyOpcUa::clientError); connect(_opcUaClient, &QOpcUaClient::stateChanged, this, &MyOpcUa::clientState); connect(_opcUaClient, &QOpcUaClient::endpointsRequestFinished, this, &MyOpcUa::getEndpointsComplete); connect(_opcUaClient, &QOpcUaClient::findServersFinished, this, &MyOpcUa::findServersComplete); } }
节点监控启用逻辑
void MyOpcUa::enableMonitoring() { QMapIterator<QString, Node_t> i(_mapOpcNodes); while (i.hasNext()) { i.next(); Node_t node = i.value(); if (node.enableRead) { qDebug() << node.node->enableMonitoring(QOpcUa::NodeAttribute::Value, QOpcUaMonitoringParameters(1000)); } } }
问题现象
enableMonitoring返回值全为true,但仅单个节点能被周期性读取。- 处理函数日志仅打印一个节点的
key,手动触发读取时所有节点均正常响应。 - 用OPC UA查看器检查目标节点,未发现节点间属性差异,目前仅
udiActualOrderLengthRT节点监控正常。
属性处理函数代码
void MyOpcUa::handleAttributes() { QOpcUaNode *node = qobject_cast<QOpcUaNode*>(sender()); QString key = retrieveNode(node->nodeId()); if (key.isEmpty()) { qWarning() << ID << "Key not found" << key; } QVariant value = node->attribute(QOpcUa::NodeAttribute::Value); qDebug() << key; // 打印被读取的节点key if (_mapOpcNodes.contains(key)) { _mapOpcNodes[key].updated = true; _mapOpcNodes[key].value = value; emit valueChanged(key, value); } }
更新:监控启用结果校验
新增enableMonitoringFinished信号处理函数:
void MyOpcUa::enableMonitoringFinished(QOpcUa::NodeAttribute attr, QOpcUa::UaStatusCode statusCode) { qDebug() << attr << statusCode; }
日志输出显示所有节点的监控启用均成功:
QOpcUa::NodeAttribute::Value QOpcUa::Good
疑问
代码或实现方法是否存在错误?导致仅单个节点被周期性监控的可能原因是什么?
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

