summaryrefslogtreecommitdiffstats
path: root/src/BobinkNode.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/BobinkNode.h')
-rw-r--r--src/BobinkNode.h105
1 files changed, 105 insertions, 0 deletions
diff --git a/src/BobinkNode.h b/src/BobinkNode.h
new file mode 100644
index 0000000..0fa1678
--- /dev/null
+++ b/src/BobinkNode.h
@@ -0,0 +1,105 @@
+/**
+ * @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 ();
+
+ static NodeStatus statusFromCode (QOpcUa::UaStatusCode code);
+ static QOpcUa::NodeAttribute attributeFromName (const QString &name);
+
+ 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