blob: 3e86cb4deaeaefc547e21c9e4253c39cfd7e349e (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
/**
* @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 <QDateTime>
#include <QObject>
#include <QOpcUaNode>
#include <QQmlEngine>
#include <QQmlParserStatus>
#include <QVariant>
/**
* @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 (QString 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;
QString accessLevel;
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 (double publishingInterval READ publishingInterval WRITE
setPublishingInterval NOTIFY publishingIntervalChanged)
Q_PROPERTY (QVariant value READ value NOTIFY valueChanged)
Q_PROPERTY (bool writable READ writable NOTIFY writableChanged)
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);
double publishingInterval () const;
void setPublishingInterval (double interval);
QVariant value () const;
bool writable () const;
OpcUaNodeInfo info () const;
/**
* @brief Write a value to the OPC UA node.
*
* Coerces @a value to the node's data type (auto-detected from the
* server's DataType attribute). For array nodes, a comma-separated
* string is split and each element coerced individually.
* Result is reported asynchronously via writeCompleted().
*/
Q_INVOKABLE void writeValue (const QVariant &value);
void classBegin () override;
void componentComplete () override;
signals:
void nodeIdChanged ();
void monitoredChanged ();
void publishingIntervalChanged ();
void valueChanged ();
void writableChanged ();
void infoChanged ();
void writeCompleted (bool success, const QString &message);
private slots:
void handleAttributeUpdated (QOpcUa::NodeAttribute attr,
const QVariant &value);
void handleValueUpdated (const QVariant &value);
void handleClientConnectedChanged ();
void handleAttributeWritten (QOpcUa::NodeAttribute attr,
QOpcUa::UaStatusCode statusCode);
void handleEnableMonitoringFinished (QOpcUa::NodeAttribute attr,
QOpcUa::UaStatusCode statusCode);
void handleDisableMonitoringFinished (QOpcUa::NodeAttribute attr,
QOpcUa::UaStatusCode statusCode);
private:
void setupNode ();
void teardownNode ();
void startMonitoring ();
void stopMonitoring ();
QVariant coerceValue (const QVariant &input) const;
QString m_nodeId;
bool m_monitored = true;
double m_publishingInterval = 100.0;
bool m_componentComplete = false;
QOpcUaNode *m_node = nullptr;
QOpcUa::Types m_valueType = QOpcUa::Types::Undefined;
bool m_writable = false;
QVariant m_value;
OpcUaNodeInfo m_info;
};
#endif // OPCUAMONITOREDNODE_H
|