/** * @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 #include #include #include #include #include /** * @brief Metadata bundle for a monitored OPC UA node. * * Exposed as a single Q_PROPERTY on OpcUaMonitoredNode so that * the QML API stays simple (only `value` is top-level). * Advanced users can access fields via dot notation: * node.info.displayName, node.info.status, etc. */ struct OpcUaNodeInfo { Q_GADGET Q_PROPERTY (QString displayName MEMBER displayName) Q_PROPERTY (QString description MEMBER description) Q_PROPERTY (QString nodeClass MEMBER nodeClass) Q_PROPERTY (QString dataType MEMBER dataType) Q_PROPERTY (quint32 accessLevel MEMBER accessLevel) Q_PROPERTY (QString status MEMBER status) Q_PROPERTY (QDateTime sourceTimestamp MEMBER sourceTimestamp) Q_PROPERTY (QDateTime serverTimestamp MEMBER serverTimestamp) public: QString displayName; QString description; QString nodeClass; QString dataType; quint32 accessLevel = 0; QString status; QDateTime sourceTimestamp; QDateTime serverTimestamp; }; Q_DECLARE_METATYPE (OpcUaNodeInfo) class OpcUaMonitoredNode : public QObject, public QQmlParserStatus { Q_OBJECT Q_INTERFACES (QQmlParserStatus) QML_ELEMENT Q_PROPERTY (QString nodeId READ nodeId WRITE setNodeId NOTIFY nodeIdChanged) Q_PROPERTY ( bool monitored READ monitored WRITE setMonitored NOTIFY monitoredChanged) Q_PROPERTY (QVariant value READ value NOTIFY valueChanged) Q_PROPERTY (OpcUaNodeInfo info READ info NOTIFY infoChanged) public: explicit OpcUaMonitoredNode (QObject *parent = nullptr); QString nodeId () const; void setNodeId (const QString &id); bool monitored () const; void setMonitored (bool monitored); QVariant value () const; OpcUaNodeInfo info () const; void classBegin () override; void componentComplete () override; signals: void nodeIdChanged (); void monitoredChanged (); void valueChanged (); void infoChanged (); private slots: void handleAttributeUpdated (QOpcUa::NodeAttribute attr, const QVariant &value); void handleValueUpdated (const QVariant &value); void handleClientConnectedChanged (); private: void setupNode (); void teardownNode (); QString m_nodeId; bool m_monitored = true; bool m_componentComplete = false; QOpcUaNode *m_node = nullptr; QVariant m_value; OpcUaNodeInfo m_info; }; #endif // OPCUAMONITOREDNODE_H