diff options
Diffstat (limited to 'src/BobinkNode.cpp')
| -rw-r--r-- | src/BobinkNode.cpp | 410 |
1 files changed, 0 insertions, 410 deletions
diff --git a/src/BobinkNode.cpp b/src/BobinkNode.cpp deleted file mode 100644 index 55e3b75..0000000 --- a/src/BobinkNode.cpp +++ /dev/null @@ -1,410 +0,0 @@ -/** - * @file BobinkNode.cpp - * @brief QML component representing a single OPC UA node. - */ -#include "BobinkNode.h" -#include "BobinkClient.h" - -#include <QOpcUaClient> -#include <QOpcUaMonitoringParameters> - -using namespace Qt::Literals::StringLiterals; - -static constexpr double DEFAULT_PUBLISHING_INTERVAL = 250.0; // ms - -/* ------------------------------------------------------------------ */ -/* Construction / destruction */ -/* ------------------------------------------------------------------ */ - -BobinkNode::BobinkNode (QQuickItem *parent) : QQuickItem (parent) {} - -BobinkNode::~BobinkNode () { stopMonitoring (); } - -/* ------------------------------------------------------------------ */ -/* Properties */ -/* ------------------------------------------------------------------ */ - -QString -BobinkNode::nodeId () const -{ - return m_nodeId; -} - -void -BobinkNode::setNodeId (const QString &id) -{ - if (m_nodeId == id) - return; - m_nodeId = id; - emit nodeIdChanged (); - - if (m_componentComplete && isVisible ()) - { - stopMonitoring (); - startMonitoring (); - } -} - -QVariant -BobinkNode::value () const -{ - return m_value; -} - -void -BobinkNode::setValue (const QVariant &value) -{ - if (m_opcuaNode) - m_opcuaNode->writeValueAttribute (value); -} - -BobinkNode::NodeStatus -BobinkNode::status () const -{ - return m_status; -} - -QDateTime -BobinkNode::sourceTimestamp () const -{ - return m_sourceTimestamp; -} - -QDateTime -BobinkNode::serverTimestamp () const -{ - return m_serverTimestamp; -} - -/* ------------------------------------------------------------------ */ -/* readAttribute */ -/* ------------------------------------------------------------------ */ - -void -BobinkNode::readAttribute (const QString &attributeName) -{ - if (!m_opcuaNode) - return; - - QOpcUa::NodeAttribute attr = attributeFromName (attributeName); - if (attr == QOpcUa::NodeAttribute::None) - return; - - m_pendingReads.insert (attr, attributeName); - m_opcuaNode->readAttributes (attr); -} - -/* ------------------------------------------------------------------ */ -/* QQuickItem lifecycle */ -/* ------------------------------------------------------------------ */ - -void -BobinkNode::componentComplete () -{ - QQuickItem::componentComplete (); - m_componentComplete = true; - - auto *client = BobinkClient::instance (); - if (client) - connect (client, &BobinkClient::connectedChanged, this, - &BobinkNode::handleClientConnectedChanged); - - if (isVisible ()) - startMonitoring (); -} - -void -BobinkNode::itemChange (ItemChange change, const ItemChangeData &data) -{ - QQuickItem::itemChange (change, data); - - if (change == ItemVisibleHasChanged && m_componentComplete) - { - if (data.boolValue) - startMonitoring (); - else - stopMonitoring (); - } -} - -/* ------------------------------------------------------------------ */ -/* Monitoring lifecycle */ -/* ------------------------------------------------------------------ */ - -void -BobinkNode::startMonitoring () -{ - if (m_opcuaNode || m_nodeId.isEmpty ()) - return; - - auto *client = BobinkClient::instance (); - if (!client || !client->connected ()) - return; - - QOpcUaClient *opcua = client->opcuaClient (); - if (!opcua) - return; - - m_opcuaNode = opcua->node (m_nodeId); - if (!m_opcuaNode) - return; - - connect (m_opcuaNode, &QOpcUaNode::dataChangeOccurred, this, - &BobinkNode::handleDataChange); - connect (m_opcuaNode, &QOpcUaNode::attributeUpdated, this, - &BobinkNode::handleAttributeUpdated); - connect (m_opcuaNode, &QOpcUaNode::attributeWritten, this, - &BobinkNode::handleAttributeWritten); - connect (m_opcuaNode, &QOpcUaNode::attributeRead, this, - &BobinkNode::handleAttributeReadFinished); - connect (m_opcuaNode, &QOpcUaNode::enableMonitoringFinished, this, - &BobinkNode::handleEnableMonitoringFinished); - connect (m_opcuaNode, &QOpcUaNode::disableMonitoringFinished, this, - &BobinkNode::handleDisableMonitoringFinished); - - QOpcUaMonitoringParameters params (DEFAULT_PUBLISHING_INTERVAL); - m_opcuaNode->enableMonitoring (QOpcUa::NodeAttribute::Value, params); -} - -void -BobinkNode::stopMonitoring () -{ - if (!m_opcuaNode) - return; - - m_pendingReads.clear (); - delete m_opcuaNode; - m_opcuaNode = nullptr; -} - -/* ------------------------------------------------------------------ */ -/* Signal handlers */ -/* ------------------------------------------------------------------ */ - -void -BobinkNode::handleDataChange (QOpcUa::NodeAttribute attr, const QVariant &val) -{ - if (attr != QOpcUa::NodeAttribute::Value) - return; - - if (m_value != val) - { - m_value = val; - emit valueChanged (); - } - - NodeStatus newStatus = statusFromCode (m_opcuaNode->valueAttributeError ()); - if (m_status != newStatus) - { - m_status = newStatus; - emit statusChanged (); - } - - QDateTime srcTs - = m_opcuaNode->sourceTimestamp (QOpcUa::NodeAttribute::Value); - if (m_sourceTimestamp != srcTs) - { - m_sourceTimestamp = srcTs; - emit sourceTimestampChanged (); - } - - QDateTime srvTs - = m_opcuaNode->serverTimestamp (QOpcUa::NodeAttribute::Value); - if (m_serverTimestamp != srvTs) - { - m_serverTimestamp = srvTs; - emit serverTimestampChanged (); - } -} - -void -BobinkNode::handleAttributeUpdated (QOpcUa::NodeAttribute attr, - const QVariant &val) -{ - auto it = m_pendingReads.find (attr); - if (it != m_pendingReads.end ()) - { - emit attributeRead (it.value (), val); - m_pendingReads.erase (it); - } -} - -void -BobinkNode::handleAttributeWritten (QOpcUa::NodeAttribute attr, - QOpcUa::UaStatusCode statusCode) -{ - if (attr != QOpcUa::NodeAttribute::Value) - return; - - if (statusCode != QOpcUa::UaStatusCode::Good) - emit writeError (QStringLiteral ("Write failed: 0x%1") - .arg (static_cast<quint32> (statusCode), 8, 16, - QLatin1Char ('0'))); -} - -void -BobinkNode::handleClientConnectedChanged () -{ - if (!BobinkClient::instance ()) - return; - - if (BobinkClient::instance ()->connected ()) - { - if (m_componentComplete && isVisible ()) - startMonitoring (); - } - else - { - stopMonitoring (); - } -} - -void -BobinkNode::handleAttributeReadFinished (QOpcUa::NodeAttributes attrs) -{ - if (!BobinkClient::instance () || !m_opcuaNode) - return; - - for (int bit = 0; bit < 27; ++bit) - { - auto attr = static_cast<QOpcUa::NodeAttribute> (1 << bit); - if (!attrs.testFlag (attr)) - continue; - - auto sc = m_opcuaNode->attributeError (attr); - QLatin1StringView name = nameFromAttribute (attr); - if (sc == QOpcUa::UaStatusCode::Good) - emit BobinkClient::instance () -> statusMessage ( - QStringLiteral ("Read %1.%2 = %3") - .arg (m_nodeId, name, - m_opcuaNode->attribute (attr).toString ())); - else - emit BobinkClient::instance () -> statusMessage ( - QStringLiteral ("Read %1.%2 failed: 0x%3") - .arg (m_nodeId, name) - .arg (static_cast<quint32> (sc), 8, 16, QLatin1Char ('0'))); - } -} - -void -BobinkNode::handleEnableMonitoringFinished (QOpcUa::NodeAttribute, - QOpcUa::UaStatusCode statusCode) -{ - if (!BobinkClient::instance ()) - return; - - if (statusCode == QOpcUa::Good) - emit BobinkClient::instance () -> statusMessage ( - QStringLiteral ("Monitoring started: %1").arg (m_nodeId)); - else - emit BobinkClient::instance () - -> statusMessage (QStringLiteral ("Monitoring failed for %1: 0x%2") - .arg (m_nodeId) - .arg (static_cast<quint32> (statusCode), 8, 16, - QLatin1Char ('0'))); -} - -void -BobinkNode::handleDisableMonitoringFinished (QOpcUa::NodeAttribute, - QOpcUa::UaStatusCode statusCode) -{ - if (!BobinkClient::instance ()) - return; - - if (statusCode == QOpcUa::Good) - emit BobinkClient::instance () -> statusMessage ( - QStringLiteral ("Monitoring stopped: %1").arg (m_nodeId)); - else - emit BobinkClient::instance () -> statusMessage ( - QStringLiteral ("Stop monitoring failed for %1: 0x%2") - .arg (m_nodeId) - .arg (static_cast<quint32> (statusCode), 8, 16, - QLatin1Char ('0'))); -} - -/* ------------------------------------------------------------------ */ -/* Helpers */ -/* ------------------------------------------------------------------ */ - -BobinkNode::NodeStatus -BobinkNode::statusFromCode (QOpcUa::UaStatusCode code) -{ - quint32 severity = static_cast<quint32> (code) >> 30; - switch (severity) - { - case 0: - return Good; - case 1: - return Uncertain; - default: - return Bad; - } -} - -QOpcUa::NodeAttribute -BobinkNode::attributeFromName (const QString &name) -{ - static const QHash<QString, QOpcUa::NodeAttribute> map = { - { QStringLiteral ("NodeId"), QOpcUa::NodeAttribute::NodeId }, - { QStringLiteral ("NodeClass"), QOpcUa::NodeAttribute::NodeClass }, - { QStringLiteral ("BrowseName"), QOpcUa::NodeAttribute::BrowseName }, - { QStringLiteral ("DisplayName"), QOpcUa::NodeAttribute::DisplayName }, - { QStringLiteral ("Description"), QOpcUa::NodeAttribute::Description }, - { QStringLiteral ("Value"), QOpcUa::NodeAttribute::Value }, - { QStringLiteral ("DataType"), QOpcUa::NodeAttribute::DataType }, - { QStringLiteral ("ValueRank"), QOpcUa::NodeAttribute::ValueRank }, - { QStringLiteral ("ArrayDimensions"), - QOpcUa::NodeAttribute::ArrayDimensions }, - { QStringLiteral ("AccessLevel"), QOpcUa::NodeAttribute::AccessLevel }, - { QStringLiteral ("UserAccessLevel"), - QOpcUa::NodeAttribute::UserAccessLevel }, - { QStringLiteral ("MinimumSamplingInterval"), - QOpcUa::NodeAttribute::MinimumSamplingInterval }, - { QStringLiteral ("Historizing"), QOpcUa::NodeAttribute::Historizing }, - { QStringLiteral ("Executable"), QOpcUa::NodeAttribute::Executable }, - { QStringLiteral ("UserExecutable"), - QOpcUa::NodeAttribute::UserExecutable }, - }; - - return map.value (name, QOpcUa::NodeAttribute::None); -} - -QLatin1StringView -BobinkNode::nameFromAttribute (QOpcUa::NodeAttribute attr) -{ - switch (attr) - { - case QOpcUa::NodeAttribute::NodeId: - return "NodeId"_L1; - case QOpcUa::NodeAttribute::NodeClass: - return "NodeClass"_L1; - case QOpcUa::NodeAttribute::BrowseName: - return "BrowseName"_L1; - case QOpcUa::NodeAttribute::DisplayName: - return "DisplayName"_L1; - case QOpcUa::NodeAttribute::Description: - return "Description"_L1; - case QOpcUa::NodeAttribute::Value: - return "Value"_L1; - case QOpcUa::NodeAttribute::DataType: - return "DataType"_L1; - case QOpcUa::NodeAttribute::ValueRank: - return "ValueRank"_L1; - case QOpcUa::NodeAttribute::ArrayDimensions: - return "ArrayDimensions"_L1; - case QOpcUa::NodeAttribute::AccessLevel: - return "AccessLevel"_L1; - case QOpcUa::NodeAttribute::UserAccessLevel: - return "UserAccessLevel"_L1; - case QOpcUa::NodeAttribute::MinimumSamplingInterval: - return "MinimumSamplingInterval"_L1; - case QOpcUa::NodeAttribute::Historizing: - return "Historizing"_L1; - case QOpcUa::NodeAttribute::Executable: - return "Executable"_L1; - case QOpcUa::NodeAttribute::UserExecutable: - return "UserExecutable"_L1; - default: - return "Unknown"_L1; - } -} |
