什么可以阻止对QtOpcUa值的监控

问题描述 投票:0回答:0

我有一个在 Ubuntu 22.04 上运行的 Qt6 控制台应用程序。 该应用程序连接到多个支持 Opcua 的 PLC。目标是监视一些节点值(所有类别

variable
)。

请注意:我尝试向您展示我的代码,当然我无法提供“完整”示例,因为无法模拟实际的远程计算机。当然,请随时询问任何可能有帮助的更多详细信息。

首先是我的结构来处理节点:

typedef struct
{
    QOpcUaNode *node; // the actual OpcUa node
    QVariant value;   // some internal variables,
    bool updated;     // not important for the question
    bool enableRead;
} Node_t;

void MyOpcUa::insertNode(QString key, QString id, bool enableRead)
{
    Node_t node; // my internal struct
    node.node = _opcUaClient->node(id); // retrieve the actual node
    node.value = QVariant();
    node.updated = false;
    node.enableRead = enableRead;

    Q_ASSERT(node.node); // check the node is valid

    _mapOpcNodes.insert(key, node);
    connect(node.node, &QOpcUaNode::attributeRead, this, &MyOpcUa::handleAttributes);
    connect(node.node, &QOpcUaNode::attributeUpdated, this, &MyOpcUa::handleAttributes);
    // when it reads the attributes I expect `handleAttributes` is called
}

这是我如何连接到远程计算机:

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
。 问题是实际上只有一个节点被定期读取。我知道这一点,因为这是处理程序:

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; // print which node has been read

    if (_mapOpcNodes.contains(key))
    {
        _mapOpcNodes[key].updated = true;
        _mapOpcNodes[key].value = value;
        emit valueChanged(key, value);
    }
}

并且仅打印一个

key
。当然,如果我手动触发读取,我可以全部读取。 使用 OpcUa 查看器,我检查了一些所需的节点:

我没有发现它们之间有任何区别。顺便说一句,我唯一可以成功监控的节点是

udiActualOrderLengthRT

我搜索了其他问题,发现了this。但是,老实说,我不确定答案是否也适用于我的框架。

我还阅读了 QOpcUaNode::enableMonitoringQOpcUaMonitoringParameters 文档,如果我理解正确,我可以使用默认的

SubscriptionType::Shared
模式,因为我希望以相同的间隔读取所有数据。

我的代码或方法中是否有任何错误的证据? 什么会导致这种行为?

qt opc-ua qt6 qtopcua
© www.soinside.com 2019 - 2024. All rights reserved.