summaryrefslogtreecommitdiffstats
path: root/src/BobinkNode.cpp
diff options
context:
space:
mode:
authorThomas Vanbesien <tvanbesi@proton.me>2026-02-19 12:29:05 +0100
committerThomas Vanbesien <tvanbesi@proton.me>2026-02-19 12:29:05 +0100
commit50c62c35463b62a3a7acebf9ebe22d44f1c6dca2 (patch)
treec56ff15619acf72448b93df218bf36286bc774b3 /src/BobinkNode.cpp
parent0c1df583acba434e2d7f6905a30fdefe288d0f9d (diff)
downloadBobinkQtOpcUa-50c62c35463b62a3a7acebf9ebe22d44f1c6dca2.tar.gz
BobinkQtOpcUa-50c62c35463b62a3a7acebf9ebe22d44f1c6dca2.zip
Log attribute reads to debug console and replace raw C++ types with Qt equivalents
Connect QOpcUaNode::attributeRead signal to new handler that logs read results (value or error code) to the debug console via BobinkClient::statusMessage. Add nameFromAttribute() helper. Replace const char* arrays with QLatin1StringView, bare string literals with QStringLiteral, uint with quint32, int with qint32. Rename statusLog to debugLog in Main.qml for consistency.
Diffstat (limited to 'src/BobinkNode.cpp')
-rw-r--r--src/BobinkNode.cpp147
1 files changed, 132 insertions, 15 deletions
diff --git a/src/BobinkNode.cpp b/src/BobinkNode.cpp
index 241b9c5..a39c195 100644
--- a/src/BobinkNode.cpp
+++ b/src/BobinkNode.cpp
@@ -8,6 +8,8 @@
#include <QOpcUaClient>
#include <QOpcUaMonitoringParameters>
+using namespace Qt::Literals::StringLiterals;
+
static constexpr double DEFAULT_PUBLISHING_INTERVAL = 250.0; // ms
/* ------------------------------------------------------------------ */
@@ -153,6 +155,12 @@ BobinkNode::startMonitoring ()
&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);
@@ -252,6 +260,72 @@ BobinkNode::handleClientConnectedChanged ()
}
}
+void
+BobinkNode::handleAttributeReadFinished (QOpcUa::NodeAttributes attrs)
+{
+ auto *client = BobinkClient::instance ();
+ if (!client || !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 client->statusMessage (
+ QStringLiteral ("Read %1.%2 = %3")
+ .arg (m_nodeId, name,
+ m_opcuaNode->attribute (attr).toString ()));
+ else
+ emit client->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)
+{
+ auto *client = BobinkClient::instance ();
+ if (!client)
+ return;
+
+ if (statusCode == QOpcUa::Good)
+ emit client->statusMessage (
+ QStringLiteral ("Monitoring started: %1").arg (m_nodeId));
+ else
+ emit client->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)
+{
+ auto *client = BobinkClient::instance ();
+ if (!client)
+ return;
+
+ if (statusCode == QOpcUa::Good)
+ emit client->statusMessage (
+ QStringLiteral ("Monitoring stopped: %1").arg (m_nodeId));
+ else
+ emit client->statusMessage (
+ QStringLiteral ("Stop monitoring failed for %1: 0x%2")
+ .arg (m_nodeId)
+ .arg (static_cast<quint32> (statusCode), 8, 16,
+ QLatin1Char ('0')));
+}
+
/* ------------------------------------------------------------------ */
/* Helpers */
/* ------------------------------------------------------------------ */
@@ -275,23 +349,66 @@ QOpcUa::NodeAttribute
BobinkNode::attributeFromName (const QString &name)
{
static const QHash<QString, QOpcUa::NodeAttribute> map = {
- { "NodeId", QOpcUa::NodeAttribute::NodeId },
- { "NodeClass", QOpcUa::NodeAttribute::NodeClass },
- { "BrowseName", QOpcUa::NodeAttribute::BrowseName },
- { "DisplayName", QOpcUa::NodeAttribute::DisplayName },
- { "Description", QOpcUa::NodeAttribute::Description },
- { "Value", QOpcUa::NodeAttribute::Value },
- { "DataType", QOpcUa::NodeAttribute::DataType },
- { "ValueRank", QOpcUa::NodeAttribute::ValueRank },
- { "ArrayDimensions", QOpcUa::NodeAttribute::ArrayDimensions },
- { "AccessLevel", QOpcUa::NodeAttribute::AccessLevel },
- { "UserAccessLevel", QOpcUa::NodeAttribute::UserAccessLevel },
- { "MinimumSamplingInterval",
+ { 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 },
- { "Historizing", QOpcUa::NodeAttribute::Historizing },
- { "Executable", QOpcUa::NodeAttribute::Executable },
- { "UserExecutable", QOpcUa::NodeAttribute::UserExecutable },
+ { 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;
+ }
+}