diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/BobinkNode.cpp | 410 | ||||
| -rw-r--r-- | src/BobinkNode.h | 111 | ||||
| -rw-r--r-- | src/CMakeLists.txt | 12 | ||||
| -rw-r--r-- | src/OpcUaAuth.cpp (renamed from src/BobinkAuth.cpp) | 32 | ||||
| -rw-r--r-- | src/OpcUaAuth.h (renamed from src/BobinkAuth.h) | 12 | ||||
| -rw-r--r-- | src/OpcUaClient.cpp (renamed from src/BobinkClient.cpp) | 110 | ||||
| -rw-r--r-- | src/OpcUaClient.h (renamed from src/BobinkClient.h) | 26 | ||||
| -rw-r--r-- | src/OpcUaMonitoredNode.cpp | 18 | ||||
| -rw-r--r-- | src/OpcUaMonitoredNode.h | 31 |
9 files changed, 145 insertions, 617 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; - } -} diff --git a/src/BobinkNode.h b/src/BobinkNode.h deleted file mode 100644 index c37a883..0000000 --- a/src/BobinkNode.h +++ /dev/null @@ -1,111 +0,0 @@ -/** - * @file BobinkNode.h - * @brief QML component representing a single OPC UA node. - * - * Inherits QQuickItem so that monitoring is automatically tied to - * visibility: when the item (or any ancestor) becomes invisible - * (e.g. StackView navigates away, Loader unloads), the monitored - * item is removed from the subscription. When visible again, - * monitoring resumes. - */ -#ifndef BOBINKNODE_H -#define BOBINKNODE_H - -#include <QDateTime> -#include <QHash> -#include <QOpcUaNode> -#include <QQuickItem> - -class BobinkNode : public QQuickItem -{ - Q_OBJECT - QML_ELEMENT - - Q_PROPERTY (QString nodeId READ nodeId WRITE setNodeId NOTIFY nodeIdChanged) - Q_PROPERTY (QVariant value READ value WRITE setValue NOTIFY valueChanged) - Q_PROPERTY (NodeStatus status READ status NOTIFY statusChanged) - Q_PROPERTY (QDateTime sourceTimestamp READ sourceTimestamp NOTIFY - sourceTimestampChanged) - Q_PROPERTY (QDateTime serverTimestamp READ serverTimestamp NOTIFY - serverTimestampChanged) - -public: - explicit BobinkNode (QQuickItem *parent = nullptr); - ~BobinkNode () override; - - /// Simplified OPC UA status severity. - enum NodeStatus - { - Good, - Uncertain, - Bad - }; - Q_ENUM (NodeStatus) - - QString nodeId () const; - void setNodeId (const QString &id); - - QVariant value () const; - /** Setting value writes to the server; the property updates when - * the server confirms via the monitored data change. */ - void setValue (const QVariant &value); - - NodeStatus status () const; - QDateTime sourceTimestamp () const; - QDateTime serverTimestamp () const; - - /** Read an attribute on demand (DisplayName, Description, DataType, …). - * Result arrives asynchronously via attributeRead(). */ - Q_INVOKABLE void readAttribute (const QString &attributeName); - -signals: - void nodeIdChanged (); - void valueChanged (); - void statusChanged (); - void sourceTimestampChanged (); - void serverTimestampChanged (); - - /** Emitted when a readAttribute() call completes. */ - void attributeRead (const QString &attributeName, const QVariant &value); - - /** Emitted when a write to the server fails. */ - void writeError (const QString &message); - -protected: - void componentComplete () override; - void itemChange (ItemChange change, const ItemChangeData &data) override; - -private: - void startMonitoring (); - void stopMonitoring (); - - void handleDataChange (QOpcUa::NodeAttribute attr, const QVariant &val); - void handleAttributeUpdated (QOpcUa::NodeAttribute attr, - const QVariant &val); - void handleAttributeWritten (QOpcUa::NodeAttribute attr, - QOpcUa::UaStatusCode statusCode); - void handleClientConnectedChanged (); - void handleAttributeReadFinished (QOpcUa::NodeAttributes attrs); - void handleEnableMonitoringFinished (QOpcUa::NodeAttribute attr, - QOpcUa::UaStatusCode statusCode); - void handleDisableMonitoringFinished (QOpcUa::NodeAttribute attr, - QOpcUa::UaStatusCode statusCode); - - static NodeStatus statusFromCode (QOpcUa::UaStatusCode code); - static QOpcUa::NodeAttribute attributeFromName (const QString &name); - static QLatin1StringView nameFromAttribute (QOpcUa::NodeAttribute attr); - - QString m_nodeId; - QVariant m_value; - NodeStatus m_status = Bad; - QDateTime m_sourceTimestamp; - QDateTime m_serverTimestamp; - - QOpcUaNode *m_opcuaNode = nullptr; - bool m_componentComplete = false; - - /** Tracks in-flight readAttribute() requests (enum → original name). */ - QHash<QOpcUa::NodeAttribute, QString> m_pendingReads; -}; - -#endif // BOBINKNODE_H diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1292194..b0781cd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,12 +7,12 @@ qt_add_qml_module( VERSION 1.0 SOURCES - BobinkAuth.h - BobinkAuth.cpp - BobinkClient.h - BobinkClient.cpp - BobinkNode.h - BobinkNode.cpp + OpcUaAuth.h + OpcUaAuth.cpp + OpcUaClient.h + OpcUaClient.cpp + OpcUaMonitoredNode.h + OpcUaMonitoredNode.cpp OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/qml/Bobink") diff --git a/src/BobinkAuth.cpp b/src/OpcUaAuth.cpp index 132e4be..258c9c7 100644 --- a/src/BobinkAuth.cpp +++ b/src/OpcUaAuth.cpp @@ -1,19 +1,19 @@ /** - * @file BobinkAuth.cpp - * @brief BobinkAuth implementation. + * @file OpcUaAuth.cpp + * @brief OpcUaAuth implementation. */ -#include "BobinkAuth.h" +#include "OpcUaAuth.h" -BobinkAuth::BobinkAuth (QObject *parent) : QObject (parent) {} +OpcUaAuth::OpcUaAuth (QObject *parent) : QObject (parent) {} -BobinkAuth::AuthMode -BobinkAuth::mode () const +OpcUaAuth::AuthMode +OpcUaAuth::mode () const { return m_mode; } void -BobinkAuth::setMode (AuthMode mode) +OpcUaAuth::setMode (AuthMode mode) { if (m_mode == mode) return; @@ -22,13 +22,13 @@ BobinkAuth::setMode (AuthMode mode) } QString -BobinkAuth::username () const +OpcUaAuth::username () const { return m_username; } void -BobinkAuth::setUsername (const QString &username) +OpcUaAuth::setUsername (const QString &username) { if (m_username == username) return; @@ -37,13 +37,13 @@ BobinkAuth::setUsername (const QString &username) } QString -BobinkAuth::password () const +OpcUaAuth::password () const { return m_password; } void -BobinkAuth::setPassword (const QString &password) +OpcUaAuth::setPassword (const QString &password) { if (m_password == password) return; @@ -52,13 +52,13 @@ BobinkAuth::setPassword (const QString &password) } QString -BobinkAuth::certPath () const +OpcUaAuth::certPath () const { return m_certPath; } void -BobinkAuth::setCertPath (const QString &path) +OpcUaAuth::setCertPath (const QString &path) { if (m_certPath == path) return; @@ -67,13 +67,13 @@ BobinkAuth::setCertPath (const QString &path) } QString -BobinkAuth::keyPath () const +OpcUaAuth::keyPath () const { return m_keyPath; } void -BobinkAuth::setKeyPath (const QString &path) +OpcUaAuth::setKeyPath (const QString &path) { if (m_keyPath == path) return; @@ -82,7 +82,7 @@ BobinkAuth::setKeyPath (const QString &path) } QOpcUaAuthenticationInformation -BobinkAuth::toAuthenticationInformation () const +OpcUaAuth::toAuthenticationInformation () const { QOpcUaAuthenticationInformation info; switch (m_mode) diff --git a/src/BobinkAuth.h b/src/OpcUaAuth.h index 2bd3c05..8d53c1d 100644 --- a/src/BobinkAuth.h +++ b/src/OpcUaAuth.h @@ -1,15 +1,15 @@ /** - * @file BobinkAuth.h + * @file OpcUaAuth.h * @brief QML component for OPC UA authentication configuration. */ -#ifndef BOBINKAUTH_H -#define BOBINKAUTH_H +#ifndef OPCUAAUTH_H +#define OPCUAAUTH_H #include <QObject> #include <QOpcUaAuthenticationInformation> #include <QQmlEngine> -class BobinkAuth : public QObject +class OpcUaAuth : public QObject { Q_OBJECT QML_ELEMENT @@ -34,7 +34,7 @@ public: }; Q_ENUM (AuthMode) - explicit BobinkAuth (QObject *parent = nullptr); + explicit OpcUaAuth (QObject *parent = nullptr); AuthMode mode () const; void setMode (AuthMode mode); @@ -72,4 +72,4 @@ private: QString m_keyPath; }; -#endif // BOBINKAUTH_H +#endif // OPCUAAUTH_H diff --git a/src/BobinkClient.cpp b/src/OpcUaClient.cpp index 41b7dbf..91ce47b 100644 --- a/src/BobinkClient.cpp +++ b/src/OpcUaClient.cpp @@ -1,9 +1,9 @@ /** - * @file BobinkClient.cpp - * @brief BobinkClient implementation. + * @file OpcUaClient.cpp + * @brief OpcUaClient implementation. */ -#include "BobinkClient.h" -#include "BobinkAuth.h" +#include "OpcUaClient.h" +#include "OpcUaAuth.h" #include <QDir> #include <QMetaEnum> @@ -35,17 +35,17 @@ ensurePkiDirs (const QString &base) } static QString -securityPolicyUri (BobinkClient::SecurityPolicy policy) +securityPolicyUri (OpcUaClient::SecurityPolicy policy) { switch (policy) { - case BobinkClient::Basic256Sha256: + case OpcUaClient::Basic256Sha256: return QStringLiteral ( "http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256"); - case BobinkClient::Aes128_Sha256_RsaOaep: + case OpcUaClient::Aes128_Sha256_RsaOaep: return QStringLiteral ( "http://opcfoundation.org/UA/SecurityPolicy#Aes128_Sha256_RsaOaep"); - case BobinkClient::Aes256_Sha256_RsaPss: + case OpcUaClient::Aes256_Sha256_RsaPss: return QStringLiteral ( "http://opcfoundation.org/UA/SecurityPolicy#Aes256_Sha256_RsaPss"); } @@ -56,7 +56,7 @@ securityPolicyUri (BobinkClient::SecurityPolicy policy) * Construction * ====================================== */ -BobinkClient::BobinkClient (QObject *parent) +OpcUaClient::OpcUaClient (QObject *parent) : QObject (parent), m_provider (new QOpcUaProvider (this)), m_pkiDir (defaultPkiDir ()) { @@ -66,56 +66,56 @@ BobinkClient::BobinkClient (QObject *parent) autoDetectPki (); applyPki (); connect (&m_discoveryTimer, &QTimer::timeout, this, - &BobinkClient::doDiscovery); + &OpcUaClient::doDiscovery); s_instance = this; } void -BobinkClient::setupClient () +OpcUaClient::setupClient () { m_client = m_provider->createClient (QStringLiteral ("open62541")); if (!m_client) { - qWarning () << "BobinkClient: failed to create open62541 backend"; + qWarning () << "OpcUaClient: failed to create open62541 backend"; return; } connect (m_client, &QOpcUaClient::stateChanged, this, - &BobinkClient::handleStateChanged); + &OpcUaClient::handleStateChanged); connect (m_client, &QOpcUaClient::endpointsRequestFinished, this, - &BobinkClient::handleEndpointsReceived); + &OpcUaClient::handleEndpointsReceived); connect (m_client, &QOpcUaClient::connectError, this, - &BobinkClient::handleConnectError); + &OpcUaClient::handleConnectError); connect (m_client, &QOpcUaClient::findServersFinished, this, - &BobinkClient::handleFindServersFinished); + &OpcUaClient::handleFindServersFinished); connect (m_client, &QOpcUaClient::errorChanged, this, - &BobinkClient::handleClientError); + &OpcUaClient::handleClientError); } /* ====================================== * Connection * ====================================== */ -BobinkClient * -BobinkClient::instance () +OpcUaClient * +OpcUaClient::instance () { return s_instance; } bool -BobinkClient::connected () const +OpcUaClient::connected () const { return m_connected; } QString -BobinkClient::serverUrl () const +OpcUaClient::serverUrl () const { return m_serverUrl; } void -BobinkClient::setServerUrl (const QString &url) +OpcUaClient::setServerUrl (const QString &url) { if (m_serverUrl == url) return; @@ -123,14 +123,14 @@ BobinkClient::setServerUrl (const QString &url) emit serverUrlChanged (); } -BobinkAuth * -BobinkClient::auth () const +OpcUaAuth * +OpcUaClient::auth () const { return m_auth; } void -BobinkClient::setAuth (BobinkAuth *auth) +OpcUaClient::setAuth (OpcUaAuth *auth) { if (m_auth == auth) return; @@ -139,13 +139,13 @@ BobinkClient::setAuth (BobinkAuth *auth) } QOpcUaClient * -BobinkClient::opcuaClient () const +OpcUaClient::opcuaClient () const { return m_client; } void -BobinkClient::connectToServer () +OpcUaClient::connectToServer () { if (!m_client) { @@ -175,7 +175,7 @@ BobinkClient::connectToServer () } void -BobinkClient::connectDirect (SecurityPolicy policy, SecurityMode mode) +OpcUaClient::connectDirect (SecurityPolicy policy, SecurityMode mode) { if (!m_client) { @@ -205,15 +205,15 @@ BobinkClient::connectDirect (SecurityPolicy policy, SecurityMode mode) { switch (m_auth->mode ()) { - case BobinkAuth::Anonymous: + case OpcUaAuth::Anonymous: tokenPolicy.setTokenType ( QOpcUaUserTokenPolicy::TokenType::Anonymous); break; - case BobinkAuth::UserPass: + case OpcUaAuth::UserPass: tokenPolicy.setTokenType ( QOpcUaUserTokenPolicy::TokenType::Username); break; - case BobinkAuth::Certificate: + case OpcUaAuth::Certificate: tokenPolicy.setTokenType ( QOpcUaUserTokenPolicy::TokenType::Certificate); break; @@ -231,14 +231,14 @@ BobinkClient::connectDirect (SecurityPolicy policy, SecurityMode mode) } void -BobinkClient::disconnectFromServer () +OpcUaClient::disconnectFromServer () { if (m_client) m_client->disconnectFromEndpoint (); } void -BobinkClient::acceptCertificate () +OpcUaClient::acceptCertificate () { m_certAccepted = true; if (m_certLoop) @@ -246,7 +246,7 @@ BobinkClient::acceptCertificate () } void -BobinkClient::rejectCertificate () +OpcUaClient::rejectCertificate () { m_certAccepted = false; if (m_certLoop) @@ -254,7 +254,7 @@ BobinkClient::rejectCertificate () } void -BobinkClient::handleStateChanged (QOpcUaClient::ClientState state) +OpcUaClient::handleStateChanged (QOpcUaClient::ClientState state) { bool nowConnected = (state == QOpcUaClient::Connected); if (m_connected != nowConnected) @@ -265,7 +265,7 @@ BobinkClient::handleStateChanged (QOpcUaClient::ClientState state) } void -BobinkClient::handleEndpointsReceived ( +OpcUaClient::handleEndpointsReceived ( const QList<QOpcUaEndpointDescription> &endpoints, QOpcUa::UaStatusCode statusCode, const QUrl &) { @@ -291,7 +291,7 @@ BobinkClient::handleEndpointsReceived ( } void -BobinkClient::handleConnectError (QOpcUaErrorState *errorState) +OpcUaClient::handleConnectError (QOpcUaErrorState *errorState) { if (errorState->connectionStep () == QOpcUaErrorState::ConnectionStep::CertificateValidation) @@ -324,7 +324,7 @@ BobinkClient::handleConnectError (QOpcUaErrorState *errorState) } void -BobinkClient::handleClientError (QOpcUaClient::ClientError error) +OpcUaClient::handleClientError (QOpcUaClient::ClientError error) { if (error == QOpcUaClient::NoError) return; @@ -340,13 +340,13 @@ BobinkClient::handleClientError (QOpcUaClient::ClientError error) * ====================================== */ QString -BobinkClient::discoveryUrl () const +OpcUaClient::discoveryUrl () const { return m_discoveryUrl; } void -BobinkClient::setDiscoveryUrl (const QString &url) +OpcUaClient::setDiscoveryUrl (const QString &url) { if (m_discoveryUrl == url) return; @@ -355,25 +355,25 @@ BobinkClient::setDiscoveryUrl (const QString &url) } bool -BobinkClient::discovering () const +OpcUaClient::discovering () const { return m_discovering; } const QList<QOpcUaApplicationDescription> & -BobinkClient::discoveredServers () const +OpcUaClient::discoveredServers () const { return m_discoveredServers; } QVariantList -BobinkClient::servers () const +OpcUaClient::servers () const { return m_serversCache; } void -BobinkClient::startDiscovery () +OpcUaClient::startDiscovery () { if (m_discoveryUrl.isEmpty () || !m_client) return; @@ -389,7 +389,7 @@ BobinkClient::startDiscovery () } void -BobinkClient::stopDiscovery () +OpcUaClient::stopDiscovery () { m_discoveryTimer.stop (); @@ -401,7 +401,7 @@ BobinkClient::stopDiscovery () } void -BobinkClient::doDiscovery () +OpcUaClient::doDiscovery () { if (!m_client || m_discoveryUrl.isEmpty ()) return; @@ -412,7 +412,7 @@ BobinkClient::doDiscovery () } void -BobinkClient::handleFindServersFinished ( +OpcUaClient::handleFindServersFinished ( const QList<QOpcUaApplicationDescription> &servers, QOpcUa::UaStatusCode statusCode, const QUrl &) { @@ -438,13 +438,13 @@ BobinkClient::handleFindServersFinished ( * ====================================== */ QString -BobinkClient::pkiDir () const +OpcUaClient::pkiDir () const { return m_pkiDir; } void -BobinkClient::setPkiDir (const QString &path) +OpcUaClient::setPkiDir (const QString &path) { if (m_pkiDir == path) return; @@ -454,13 +454,13 @@ BobinkClient::setPkiDir (const QString &path) } QString -BobinkClient::certFile () const +OpcUaClient::certFile () const { return m_certFile; } void -BobinkClient::setCertFile (const QString &path) +OpcUaClient::setCertFile (const QString &path) { if (m_certFile == path) return; @@ -469,13 +469,13 @@ BobinkClient::setCertFile (const QString &path) } QString -BobinkClient::keyFile () const +OpcUaClient::keyFile () const { return m_keyFile; } void -BobinkClient::setKeyFile (const QString &path) +OpcUaClient::setKeyFile (const QString &path) { if (m_keyFile == path) return; @@ -484,7 +484,7 @@ BobinkClient::setKeyFile (const QString &path) } void -BobinkClient::autoDetectPki () +OpcUaClient::autoDetectPki () { if (m_pkiDir.isEmpty ()) return; @@ -503,7 +503,7 @@ BobinkClient::autoDetectPki () } void -BobinkClient::applyPki () +OpcUaClient::applyPki () { if (!m_client || m_pkiDir.isEmpty ()) return; diff --git a/src/BobinkClient.h b/src/OpcUaClient.h index 7eb6c3c..1476911 100644 --- a/src/BobinkClient.h +++ b/src/OpcUaClient.h @@ -1,13 +1,13 @@ /** - * @file BobinkClient.h + * @file OpcUaClient.h * @brief QML singleton managing the OPC UA connection lifecycle. * * Wraps QOpcUaClient into a declarative interface: LDS discovery, * endpoint selection, PKI, and certificate trust flow. * Single connection at a time (app-wide singleton). */ -#ifndef BOBINKCLIENT_H -#define BOBINKCLIENT_H +#ifndef OPCUACLIENT_H +#define OPCUACLIENT_H #include <QEventLoop> #include <QObject> @@ -19,9 +19,9 @@ #include <QQmlEngine> #include <QTimer> -class BobinkAuth; +class OpcUaAuth; -class BobinkClient : public QObject +class OpcUaClient : public QObject { Q_OBJECT QML_SINGLETON @@ -31,7 +31,7 @@ class BobinkClient : public QObject Q_PROPERTY (bool connected READ connected NOTIFY connectedChanged) Q_PROPERTY (QString serverUrl READ serverUrl WRITE setServerUrl NOTIFY serverUrlChanged) - Q_PROPERTY (BobinkAuth *auth READ auth WRITE setAuth NOTIFY authChanged) + Q_PROPERTY (OpcUaAuth *auth READ auth WRITE setAuth NOTIFY authChanged) /* -- Discovery -- */ Q_PROPERTY (QString discoveryUrl READ discoveryUrl WRITE setDiscoveryUrl @@ -65,7 +65,7 @@ public: }; Q_ENUM (SecurityPolicy) - BobinkClient (QObject *parent = nullptr); + OpcUaClient (QObject *parent = nullptr); /* -- Connection -- */ @@ -74,8 +74,8 @@ public: QString serverUrl () const; void setServerUrl (const QString &url); - BobinkAuth *auth () const; - void setAuth (BobinkAuth *auth); + OpcUaAuth *auth () const; + void setAuth (OpcUaAuth *auth); /** @brief Discover endpoints, pick the most secure, connect. */ Q_INVOKABLE void connectToServer (); @@ -119,7 +119,7 @@ public: /* -- C++ only -- */ - static BobinkClient *instance (); + static OpcUaClient *instance (); QOpcUaClient *opcuaClient () const; signals: @@ -169,7 +169,7 @@ private: /* -- Connection -- */ QOpcUaProvider *m_provider = nullptr; QOpcUaClient *m_client = nullptr; - BobinkAuth *m_auth = nullptr; + OpcUaAuth *m_auth = nullptr; QString m_serverUrl; bool m_connected = false; QEventLoop *m_certLoop = nullptr; @@ -187,7 +187,7 @@ private: QString m_certFile; QString m_keyFile; - static inline BobinkClient *s_instance = nullptr; + static inline OpcUaClient *s_instance = nullptr; }; -#endif // BOBINKCLIENT_H +#endif // OPCUACLIENT_H diff --git a/src/OpcUaMonitoredNode.cpp b/src/OpcUaMonitoredNode.cpp new file mode 100644 index 0000000..da66e89 --- /dev/null +++ b/src/OpcUaMonitoredNode.cpp @@ -0,0 +1,18 @@ +/** + * @file OpcUaMonitoredNode.cpp + * @brief OpcUaMonitoredNode implementation. + */ +#include "OpcUaMonitoredNode.h" + +OpcUaMonitoredNode::OpcUaMonitoredNode (QObject *parent) : QObject (parent) {} + +void +OpcUaMonitoredNode::classBegin () +{ +} + +void +OpcUaMonitoredNode::componentComplete () +{ + m_componentComplete = true; +} diff --git a/src/OpcUaMonitoredNode.h b/src/OpcUaMonitoredNode.h new file mode 100644 index 0000000..ccf3444 --- /dev/null +++ b/src/OpcUaMonitoredNode.h @@ -0,0 +1,31 @@ +/** + * @file OpcUaMonitoredNode.h + * @brief QML component for monitoring a single OPC UA node. + * + * Inherits QObject + QQmlParserStatus so that initialisation is + * deferred until all QML bindings are applied (componentComplete). + */ +#ifndef OPCUAMONITOREDNODE_H +#define OPCUAMONITOREDNODE_H + +#include <QObject> +#include <QQmlEngine> +#include <QQmlParserStatus> + +class OpcUaMonitoredNode : public QObject, public QQmlParserStatus +{ + Q_OBJECT + Q_INTERFACES (QQmlParserStatus) + QML_ELEMENT + +public: + explicit OpcUaMonitoredNode (QObject *parent = nullptr); + + void classBegin () override; + void componentComplete () override; + +private: + bool m_componentComplete = false; +}; + +#endif // OPCUAMONITOREDNODE_H |
