1// Copyright (C) 2016 basysKom GmbH, opensource@basyskom.com
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QOPCUANODE_P_H
5#define QOPCUANODE_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtOpcUa/qopcuaclient.h>
19#include <QtOpcUa/qopcuanode.h>
20#include <QtOpcUa/qopcuaeventfilterresult.h>
21#include <private/qopcuanodeimpl_p.h>
22
23#include <private/qobject_p.h>
24#include <QtCore/qpointer.h>
25#include <QtCore/qscopedpointer.h>
26#include <QtCore/qhash.h>
27
28QT_BEGIN_NAMESPACE
29
30class QOpcUaNodePrivate : public QObjectPrivate
31{
32 Q_DECLARE_PUBLIC(QOpcUaNode)
33
34public:
35 QOpcUaNodePrivate(QOpcUaNodeImpl *impl, QOpcUaClient *client)
36 : m_impl(impl)
37 , m_client(client)
38 {
39 m_attributesReadConnection = QObject::connect(sender: impl, signal: &QOpcUaNodeImpl::attributesRead,
40 slot: [this](QList<QOpcUaReadResult> attr, QOpcUa::UaStatusCode serviceResult)
41 {
42 QOpcUa::NodeAttributes updatedAttributes;
43 Q_Q(QOpcUaNode);
44
45 for (auto &entry : std::as_const(t&: attr)) {
46 if (serviceResult == QOpcUa::UaStatusCode::Good)
47 m_nodeAttributes[entry.attribute()] = entry;
48 else {
49 QOpcUaReadResult temp = entry;
50 temp.setStatusCode(serviceResult);
51 temp.setValue(QVariant());
52 m_nodeAttributes[entry.attribute()] = temp;
53 }
54
55 updatedAttributes |= entry.attribute();
56 emit q->attributeUpdated(attr: entry.attribute(), value: entry.value());
57 }
58
59 emit q->attributeRead(attributes: updatedAttributes);
60 });
61
62 m_attributeWrittenConnection = QObject::connect(sender: impl, signal: &QOpcUaNodeImpl::attributeWritten,
63 slot: [this](QOpcUa::NodeAttribute attr, QVariant value, QOpcUa::UaStatusCode statusCode)
64 {
65 m_nodeAttributes[attr].setStatusCode(statusCode);
66 Q_Q(QOpcUaNode);
67
68 if (statusCode == QOpcUa::UaStatusCode::Good) {
69 m_nodeAttributes[attr].setValue(value);
70 emit q->attributeUpdated(attr, value);
71 }
72
73 emit q->attributeWritten(attribute: attr, statusCode);
74 });
75
76 m_dataChangeOccurredConnection = QObject::connect(sender: impl, signal: &QOpcUaNodeImpl::dataChangeOccurred,
77 slot: [this](QOpcUa::NodeAttribute attr, QOpcUaReadResult value)
78 {
79 this->m_nodeAttributes[attr] = value;
80 Q_Q(QOpcUaNode);
81 emit q->dataChangeOccurred(attr, value: value.value());
82 emit q->attributeUpdated(attr, value: value.value());
83 });
84
85 m_monitoringEnableDisableConnection = QObject::connect(sender: impl, signal: &QOpcUaNodeImpl::monitoringEnableDisable,
86 slot: [this](QOpcUa::NodeAttribute attr, bool subscribe, QOpcUaMonitoringParameters status)
87 {
88 if (subscribe == true) {
89 if (status.statusCode() != QOpcUa::UaStatusCode::BadEntryExists) // Don't overwrite a valid entry
90 m_monitoringStatus[attr] = status;
91 Q_Q(QOpcUaNode);
92 emit q->enableMonitoringFinished(attr, statusCode: status.statusCode());
93 }
94 else {
95 m_monitoringStatus.remove(key: attr);
96 Q_Q(QOpcUaNode);
97 emit q->disableMonitoringFinished(attr, statusCode: status.statusCode());
98 }
99 });
100
101 m_monitoringStatusChangedConnection = QObject::connect(sender: impl, signal: &QOpcUaNodeImpl::monitoringStatusChanged,
102 slot: [this](QOpcUa::NodeAttribute attr, QOpcUaMonitoringParameters::Parameters items, QOpcUaMonitoringParameters param)
103 {
104 auto it = m_monitoringStatus.find(key: attr);
105 if (param.statusCode() == QOpcUa::UaStatusCode::Good && it != m_monitoringStatus.end()) {
106 if (items & QOpcUaMonitoringParameters::Parameter::PublishingEnabled)
107 it->setPublishingEnabled(param.isPublishingEnabled());
108 if (items & QOpcUaMonitoringParameters::Parameter::PublishingInterval)
109 it->setPublishingInterval(param.publishingInterval());
110 if (items & QOpcUaMonitoringParameters::Parameter::LifetimeCount)
111 it->setLifetimeCount(param.lifetimeCount());
112 if (items & QOpcUaMonitoringParameters::Parameter::MaxKeepAliveCount)
113 it->setMaxKeepAliveCount(param.maxKeepAliveCount());
114 if (items & QOpcUaMonitoringParameters::Parameter::MaxNotificationsPerPublish)
115 it->setMaxNotificationsPerPublish(param.maxNotificationsPerPublish());
116 if (items & QOpcUaMonitoringParameters::Parameter::Priority)
117 it->setPriority(param.priority());
118 if (items & QOpcUaMonitoringParameters::Parameter::SamplingInterval)
119 it->setSamplingInterval(param.samplingInterval());
120 if (items & QOpcUaMonitoringParameters::Parameter::Filter) {
121 if (param.filter().canConvert<QOpcUaMonitoringParameters::DataChangeFilter>())
122 it->setFilter(param.filter().value<QOpcUaMonitoringParameters::DataChangeFilter>());
123 else if (param.filter().canConvert<QOpcUaMonitoringParameters::EventFilter>())
124 it->setFilter(param.filter().value<QOpcUaMonitoringParameters::EventFilter>());
125 else if (param.filter().isNull())
126 it->clearFilter();
127 if (param.filterResult().canConvert<QOpcUaEventFilterResult>())
128 it->setFilterResult(param.filterResult().value<QOpcUaEventFilterResult>());
129 else if (param.filterResult().isNull())
130 it->clearFilterResult();
131 }
132 if (items & QOpcUaMonitoringParameters::Parameter::QueueSize)
133 it->setQueueSize(param.queueSize());
134 if (items & QOpcUaMonitoringParameters::Parameter::DiscardOldest)
135 it->setDiscardOldest(param.discardOldest());
136 if (items & QOpcUaMonitoringParameters::Parameter::MonitoringMode)
137 it->setMonitoringMode(param.monitoringMode());
138 }
139
140 Q_Q(QOpcUaNode);
141 emit q->monitoringStatusChanged(attr, items, statusCode: param.statusCode());
142 });
143
144
145 m_methodCallFinishedConnection = QObject::connect(sender: impl, signal: &QOpcUaNodeImpl::methodCallFinished,
146 slot: [this](QString methodNodeId, QVariant result, QOpcUa::UaStatusCode statusCode)
147 {
148 Q_Q(QOpcUaNode);
149 emit q->methodCallFinished(methodNodeId, result, statusCode);
150 });
151
152 m_browseFinishedConnection = QObject::connect(sender: impl, signal: &QOpcUaNodeImpl::browseFinished,
153 slot: [this](QList<QOpcUaReferenceDescription> children, QOpcUa::UaStatusCode statusCode)
154 {
155 Q_Q(QOpcUaNode);
156 emit q->browseFinished(children, statusCode);
157 });
158
159 m_resolveBrowsePathFinishedConnection = QObject::connect(sender: impl, signal: &QOpcUaNodeImpl::resolveBrowsePathFinished,
160 slot: [this](QList<QOpcUaBrowsePathTarget> targets, QList<QOpcUaRelativePathElement> path,
161 QOpcUa::UaStatusCode statusCode)
162 {
163 Q_Q(QOpcUaNode);
164 emit q->resolveBrowsePathFinished(targets, path, statusCode);
165 });
166
167 m_eventOccurredConnection = QObject::connect(sender: impl, signal: &QOpcUaNodeImpl::eventOccurred,
168 slot: [this](QVariantList eventFields)
169 {
170 Q_Q(QOpcUaNode);
171 emit q->eventOccurred(eventFields);
172 });
173 }
174
175 ~QOpcUaNodePrivate()
176 {
177 QObject::disconnect(m_attributesReadConnection);
178 QObject::disconnect(m_attributeWrittenConnection);
179 QObject::disconnect(m_dataChangeOccurredConnection);
180 QObject::disconnect(m_monitoringEnableDisableConnection);
181 QObject::disconnect(m_monitoringStatusChangedConnection);
182 QObject::disconnect(m_methodCallFinishedConnection);
183 QObject::disconnect(m_browseFinishedConnection);
184 QObject::disconnect(m_resolveBrowsePathFinishedConnection);
185 QObject::disconnect(m_eventOccurredConnection);
186
187 // Disable remaining monitorings
188 QOpcUa::NodeAttributes attr;
189 for (auto it = m_monitoringStatus.constBegin(); it != m_monitoringStatus.constEnd(); ++it) {
190 if (it->statusCode() == QOpcUa::UaStatusCode::Good)
191 attr |= it.key();
192 }
193 if (attr != 0 && m_impl) {
194 m_impl->disableMonitoring(attr);
195 }
196 }
197
198 QScopedPointer<QOpcUaNodeImpl> m_impl;
199 QPointer<QOpcUaClient> m_client;
200
201 QHash<QOpcUa::NodeAttribute, QOpcUaReadResult> m_nodeAttributes;
202 QHash<QOpcUa::NodeAttribute, QOpcUaMonitoringParameters> m_monitoringStatus;
203
204 QMetaObject::Connection m_attributesReadConnection;
205 QMetaObject::Connection m_attributeWrittenConnection;
206 QMetaObject::Connection m_dataChangeOccurredConnection;
207 QMetaObject::Connection m_monitoringEnableDisableConnection;
208 QMetaObject::Connection m_monitoringStatusChangedConnection;
209 QMetaObject::Connection m_methodCallFinishedConnection;
210 QMetaObject::Connection m_browseFinishedConnection;
211 QMetaObject::Connection m_resolveBrowsePathFinishedConnection;
212 QMetaObject::Connection m_eventOccurredConnection;
213};
214
215QT_END_NAMESPACE
216
217#endif // QOPCUANODE_P_H
218

source code of qtopcua/src/opcua/client/qopcuanode_p.h