summaryrefslogtreecommitdiffstats
path: root/src/BobinkNode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/BobinkNode.cpp')
-rw-r--r--src/BobinkNode.cpp410
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;
- }
-}