summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Keller <Rainer.Keller@qt.io>2019-04-30 11:19:57 +0200
committerRainer Keller <Rainer.Keller@qt.io>2019-05-20 08:14:07 +0200
commit0b31dca3dc0c892987d3e3d6cf7e50245bb7f93b (patch)
tree77f7c4cdcae8a5e8f28f5debbb3fcef555bff4a3
parent03672e4d7801cc927f68083f0d0bbceb82c4ed20 (diff)
qml: Event filter support
Change-Id: I0631f4c4f23ef2f5e7665861d14c2c168502c1ae Reviewed-by: Jannis Völker <jannis.voelker@basyskom.com> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
-rw-r--r--src/imports/opcua/opcua.pro14
-rw-r--r--src/imports/opcua/opcua_plugin.cpp12
-rw-r--r--src/imports/opcua/opcuaattributeoperand.cpp250
-rw-r--r--src/imports/opcua/opcuaattributeoperand.h96
-rw-r--r--src/imports/opcua/opcuaelementoperand.cpp141
-rw-r--r--src/imports/opcua/opcuaelementoperand.h65
-rw-r--r--src/imports/opcua/opcuaeventfilter.cpp254
-rw-r--r--src/imports/opcua/opcuaeventfilter.h94
-rw-r--r--src/imports/opcua/opcuafilterelement.cpp175
-rw-r--r--src/imports/opcua/opcuafilterelement.h103
-rw-r--r--src/imports/opcua/opcualiteraloperand.cpp116
-rw-r--r--src/imports/opcua/opcualiteraloperand.h72
-rw-r--r--src/imports/opcua/opcuanode.cpp89
-rw-r--r--src/imports/opcua/opcuanode.h10
-rw-r--r--src/imports/opcua/opcuaoperandbase.cpp58
-rw-r--r--src/imports/opcua/opcuaoperandbase.h58
-rw-r--r--src/imports/opcua/opcuasimpleattributeoperand.cpp247
-rw-r--r--src/imports/opcua/opcuasimpleattributeoperand.h91
-rw-r--r--src/opcua/client/qopcuacontentfilterelement.cpp6
-rw-r--r--tests/auto/declarative/MonitoringFilterTest.qml181
-rw-r--r--tests/auto/declarative/tst_monitoringFilterTest.qml41
21 files changed, 2169 insertions, 4 deletions
diff --git a/src/imports/opcua/opcua.pro b/src/imports/opcua/opcua.pro
index dd3cc01..8326c1f 100644
--- a/src/imports/opcua/opcua.pro
+++ b/src/imports/opcua/opcua.pro
@@ -23,6 +23,13 @@ SOURCES += \
opcuawriteitem.cpp \
opcuawriteresult.cpp \
opcuadatachangefilter.cpp \
+ opcuaelementoperand.cpp \
+ opcualiteraloperand.cpp \
+ opcuasimpleattributeoperand.cpp \
+ opcuaattributeoperand.cpp \
+ opcuafilterelement.cpp \
+ opcuaeventfilter.cpp \
+ opcuaoperandbase.cpp \
HEADERS += \
opcua_plugin.h \
@@ -47,6 +54,13 @@ HEADERS += \
opcuawriteitem.h \
opcuawriteresult.h \
opcuadatachangefilter.h \
+ opcuaelementoperand.h \
+ opcualiteraloperand.h \
+ opcuasimpleattributeoperand.h \
+ opcuaattributeoperand.h \
+ opcuafilterelement.h \
+ opcuaeventfilter.h \
+ opcuaoperandbase.h \
load(qml_plugin)
diff --git a/src/imports/opcua/opcua_plugin.cpp b/src/imports/opcua/opcua_plugin.cpp
index 4c2c51b..c46be14 100644
--- a/src/imports/opcua/opcua_plugin.cpp
+++ b/src/imports/opcua/opcua_plugin.cpp
@@ -51,6 +51,12 @@
#include "opcuaserverdiscovery.h"
#include "opcuawriteitem.h"
#include "opcuawriteresult.h"
+#include "opcuaelementoperand.h"
+#include "opcualiteraloperand.h"
+#include "opcuasimpleattributeoperand.h"
+#include "opcuaattributeoperand.h"
+#include "opcuafilterelement.h"
+#include "opcuaeventfilter.h"
#include <QLoggingCategory>
#include <QOpcUaUserTokenPolicy>
@@ -147,6 +153,12 @@ void OpcUaPlugin::registerTypes(const char *uri)
qmlRegisterType<OpcUaServerDiscovery>(uri, major, minor, "ServerDiscovery");
qmlRegisterUncreatableType<QOpcUaUserTokenPolicy>(uri, major, minor, "UserTokenPolicy", "This type can not be created.");
qmlRegisterType<OpcUaDataChangeFilter>(uri, major, minor, "DataChangeFilter");
+ qmlRegisterType<OpcUaElementOperand>(uri, major, minor, "ElementOperand");
+ qmlRegisterType<OpcUaLiteralOperand>(uri, major, minor, "LiteralOperand");
+ qmlRegisterType<OpcUaSimpleAttributeOperand>(uri, major, minor, "SimpleAttributeOperand");
+ qmlRegisterType<OpcUaAttributeOperand>(uri, major, minor, "AttributeOperand");
+ qmlRegisterType<OpcUaFilterElement>(uri, major, minor, "FilterElement");
+ qmlRegisterType<OpcUaEventFilter>(uri, major, minor, "EventFilter");
// insert new versions here
diff --git a/src/imports/opcua/opcuaattributeoperand.cpp b/src/imports/opcua/opcuaattributeoperand.cpp
new file mode 100644
index 0000000..3223651
--- /dev/null
+++ b/src/imports/opcua/opcuaattributeoperand.cpp
@@ -0,0 +1,250 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt OPC UA module.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "opcuaattributeoperand.h"
+#include "opcuanodeid.h"
+#include "universalnode.h"
+#include "opcuarelativenodepath.h"
+#include <QOpcUaRelativePathElement>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype AttributeOperand
+ \inqmlmodule QtOpcUa
+ \brief The OPC UA AttributeOperand type.
+ \since QtOpcUa 5.13
+
+ The AttributeOperand is defined in OPC-UA part 4, 7.4.4.4.
+ It has the same purpose as \l SimpleAttributeOperand but has more configurable options.
+*/
+
+/*!
+ \qmlproperty list<OpcUaNodeId> AttributeOperand::browsePath
+
+ Browse path to the node holding the attribute.
+
+ \code
+ import QtOpcUa 5.13 as QtOpcUa
+
+ QtOpcUA.AttributeOperand {
+ ...
+ browsePath: [
+ QtOpcUa.NodeId {
+ identifier: "Message"
+ ns: "http://opcfoundation.org/UA/"
+ }
+ ...
+ ]
+ }
+*/
+
+/*!
+ \qmlproperty string AttributeOperand::indexRange
+
+ Index range string used to identify a single value or subset of the attribute's value.
+
+ \code
+ import QtOpcUa 5.13 as QtOpcUa
+
+ QtOpcUa.AttributeOperand {
+ ...
+ indexRange: "0:2"
+ }
+ \endcode
+*/
+
+/*!
+ \qmlproperty Constants.NodeAttribute AttributeOperand::nodeAttribute
+
+ Attribute of the node \l browsePath is pointing to.
+ The default value is \c Constants.NodeAttribute.Value.
+
+ \code
+ import QtOpcUa 5.13 as QtOpcUa
+
+ QtOpcUa.AttributeOperand {
+ ...
+ nodeAttribute: QtOpcUa.Constants.NodeAttribute.Value
+ }
+ \endcode
+*/
+
+/*!
+ \qmlproperty string AttributeOperand::typeId
+
+ Node id of the type definition node. The operand will be of the type or one of its subtypes.
+
+ \code
+ import QtOpcUa 5.13 as QtOpcUa
+
+ QtOpcUa.AttributeOperand {
+ ...
+ typeId: "ns=0;i=2041"
+ }
+ \endcode
+*/
+
+/*!
+ \qmlproperty string AttributeOperand::alias
+
+ Alias name for the operand. This allows using this instance
+ as operand for other operations in the filter.
+*/
+
+OpcUaAttributeOperand::OpcUaAttributeOperand(QObject *parent)
+ : OpcUaOperandBase(parent)
+{
+}
+
+OpcUaAttributeOperand::~OpcUaAttributeOperand() = default;
+
+QVariant OpcUaAttributeOperand::toCppVariant(QOpcUaClient *client) const
+{
+ QOpcUaAttributeOperand value(*this);
+
+ if (m_nodeId) {
+ UniversalNode un(m_nodeId);
+ un.resolveNamespace(client);
+ value.setAlias(un.fullNodeId());
+ }
+
+ for (const auto &i : m_browsePath)
+ value.browsePathRef().append(i->toRelativePathElement(client));
+ return value;
+}
+
+QString OpcUaAttributeOperand::indexRange() const
+{
+ return QOpcUaAttributeOperand::indexRange();
+}
+
+void OpcUaAttributeOperand::setIndexRange(const QString &indexRange)
+{
+ if (indexRange != QOpcUaAttributeOperand::indexRange()) {
+ QOpcUaAttributeOperand::setIndexRange(indexRange);
+ emit dataChanged();
+ }
+}
+
+QOpcUa::NodeAttribute OpcUaAttributeOperand::nodeAttribute() const
+{
+ return QOpcUaAttributeOperand::attributeId();
+}
+
+void OpcUaAttributeOperand::setNodeAttribute(QOpcUa::NodeAttribute nodeAttribute)
+{
+ if (nodeAttribute != QOpcUaAttributeOperand::attributeId()) {
+ QOpcUaAttributeOperand::setAttributeId(nodeAttribute);
+ emit dataChanged();
+ }
+}
+
+OpcUaNodeId *OpcUaAttributeOperand::typeId() const
+{
+ return m_nodeId;
+}
+
+void OpcUaAttributeOperand::setTypeId(OpcUaNodeId *typeId)
+{
+ if (typeId != m_nodeId) {
+ m_nodeId = typeId;
+ emit dataChanged();
+ }
+}
+
+QQmlListProperty<OpcUaRelativeNodePath> OpcUaAttributeOperand::browsePath()
+{
+ return QQmlListProperty<OpcUaRelativeNodePath>(this, this,
+ &OpcUaAttributeOperand::appendBrowsePathElement,
+ &OpcUaAttributeOperand::browsePathSize,
+ &OpcUaAttributeOperand::browsePathElement,
+ &OpcUaAttributeOperand::clearBrowsePath);
+}
+
+void OpcUaAttributeOperand::appendBrowsePathElement(OpcUaRelativeNodePath *nodeId)
+{
+ m_browsePath.append(nodeId);
+ emit dataChanged();
+}
+
+int OpcUaAttributeOperand::browsePathSize() const
+{
+ return m_browsePath.size();
+}
+
+OpcUaRelativeNodePath *OpcUaAttributeOperand::browsePathElement(int index) const
+{
+ return m_browsePath.at(index);
+}
+
+void OpcUaAttributeOperand::clearBrowsePath()
+{
+ m_browsePath.clear();
+ emit dataChanged();
+}
+
+void OpcUaAttributeOperand::appendBrowsePathElement(QQmlListProperty<OpcUaRelativeNodePath> *list, OpcUaRelativeNodePath *nodeId)
+{
+ reinterpret_cast<OpcUaAttributeOperand*>(list->data)->appendBrowsePathElement(nodeId);
+}
+
+int OpcUaAttributeOperand::browsePathSize(QQmlListProperty<OpcUaRelativeNodePath> *list)
+{
+ return reinterpret_cast<OpcUaAttributeOperand*>(list->data)->browsePathSize();
+}
+
+OpcUaRelativeNodePath *OpcUaAttributeOperand::browsePathElement(QQmlListProperty<OpcUaRelativeNodePath> *list, int index)
+{
+ return reinterpret_cast<OpcUaAttributeOperand*>(list->data)->browsePathElement(index);
+}
+
+void OpcUaAttributeOperand::clearBrowsePath(QQmlListProperty<OpcUaRelativeNodePath> *list)
+{
+ reinterpret_cast<OpcUaAttributeOperand*>(list->data)->clearBrowsePath();
+}
+
+QString OpcUaAttributeOperand::alias() const
+{
+ return QOpcUaAttributeOperand::alias();
+}
+
+void OpcUaAttributeOperand::setAlias(const QString &alias)
+{
+ QOpcUaAttributeOperand::setAlias(alias);
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/opcua/opcuaattributeoperand.h b/src/imports/opcua/opcuaattributeoperand.h
new file mode 100644
index 0000000..de2f332
--- /dev/null
+++ b/src/imports/opcua/opcuaattributeoperand.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt OPC UA module.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OPCUAATTRIBUTEOPERAND
+#define OPCUAATTRIBUTEOPERAND
+
+#include "opcuaoperandbase.h"
+#include <QOpcUaAttributeOperand>
+#include <QQmlListProperty>
+
+QT_BEGIN_NAMESPACE
+
+class OpcUaNodeId;
+class OpcUaRelativeNodePath;
+class QOpcUaClient;
+
+class OpcUaAttributeOperand : public OpcUaOperandBase, private QOpcUaAttributeOperand {
+ Q_OBJECT
+ Q_PROPERTY(QQmlListProperty<OpcUaRelativeNodePath> browsePath READ browsePath)
+ Q_PROPERTY(QString indexRange READ indexRange WRITE setIndexRange)
+ Q_PROPERTY(QOpcUa::NodeAttribute nodeAttribute READ nodeAttribute WRITE setNodeAttribute)
+ Q_PROPERTY(OpcUaNodeId* typeId READ typeId WRITE setTypeId)
+ Q_PROPERTY(QString alias READ alias WRITE setAlias)
+
+public:
+ explicit OpcUaAttributeOperand(QObject *parent = nullptr);
+ ~OpcUaAttributeOperand();
+ virtual QVariant toCppVariant(QOpcUaClient *client) const override;
+
+ OpcUaNodeId *typeId() const;
+ void setTypeId(OpcUaNodeId *nodeId);
+
+ QString alias() const;
+ void setAlias(const QString &alias);
+
+ QString indexRange() const;
+ void setIndexRange(const QString &indexRange);
+
+ QOpcUa::NodeAttribute nodeAttribute() const;
+ void setNodeAttribute(QOpcUa::NodeAttribute nodeAttribute);
+
+ QQmlListProperty<OpcUaRelativeNodePath> browsePath();
+ void appendBrowsePathElement(OpcUaRelativeNodePath *nodeId);
+ int browsePathSize() const;
+ OpcUaRelativeNodePath *browsePathElement(int index) const;
+ void clearBrowsePath();
+
+signals:
+ void dataChanged();
+
+private:
+ static void appendBrowsePathElement(QQmlListProperty<OpcUaRelativeNodePath> *list, OpcUaRelativeNodePath *nodeId);
+ static int browsePathSize(QQmlListProperty<OpcUaRelativeNodePath> *list);
+ static OpcUaRelativeNodePath* browsePathElement(QQmlListProperty<OpcUaRelativeNodePath> *list, int index);
+ static void clearBrowsePath(QQmlListProperty<OpcUaRelativeNodePath> *list);
+
+ QVector<OpcUaRelativeNodePath*> m_browsePath;
+ OpcUaNodeId *m_nodeId = nullptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // OPCUASIMPLEATTRIBUTEOPERAND
diff --git a/src/imports/opcua/opcuaelementoperand.cpp b/src/imports/opcua/opcuaelementoperand.cpp
new file mode 100644
index 0000000..b499f62
--- /dev/null
+++ b/src/imports/opcua/opcuaelementoperand.cpp
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt OPC UA module.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "opcuaelementoperand.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype ElementOperand
+ \inqmlmodule QtOpcUa
+ \brief The OPC UA ElementOperand type.
+ \since QtOpcUa 5.13
+
+ The ElementOperand is defined in OPC-UA part 4, 7.4.4.2.
+ It is used to identify another element in the filter by its index
+ (the first element has the index 0).
+
+ This is required to create complex filters, for example to reference
+ the two operands of the AND operation in ((Severity > 500) AND (Message == "TestString")).
+ The first step is to create content filter elements for the two conditions (Severity > 500)
+ and (Message == "TestString"). A third content filter element is required to create an AND
+ combination of the two conditions. It consists of the AND operator and two element operands
+ with the indices of the two conditions created before:
+
+ \code
+ import QtOpcUa 5.13 as QtOpcUa
+
+ QtOpcUa.EventFilter {
+ select : [ ... ]
+ where: [
+ QtOpcUa.FilterElement {
+ operator: QtOpcUa.FilterElement.GreaterThan
+ firstOperand: QtOpcUA.SimpleAttributeOperand {
+ browsePath: [
+ QtOpcUa.NodeId {
+ identifier: "Severity"
+ ns: "http://opcfoundation.org/UA/"
+ }
+ ]
+ }
+ secondOperand: QtOpcUa.LiteralOperand {
+ value: 500
+ type: QtOpcUa.Constants.UInt16
+ }
+ }
+ QtOpcUa.FilterElement {
+ operator: QtOpcUa.FilterElement.Equals
+ firstOperand: QtOpcUA.SimpleAttributeOperand {
+ browsePath: [
+ QtOpcUa.NodeId {
+ identifier: "Message"
+ ns: "http://opcfoundation.org/UA/"
+ }
+ ]
+ }
+ secondOperand: QtOpcUa.LiteralOperand {
+ value: "TestString"
+ type: QtOpcUa.Constants.String
+ }
+ }
+ QtOpcUa.FilterElement {
+ operator: QtOpcUa.FilterElement.And
+ firstOperand: QtOpcUA.ElementOperand {
+ index: 0
+ }
+ secondOperand: QtOpcUa.ElementOperand {
+ index: 1
+ }
+ }
+ ]
+ }
+ \endcode
+*/
+
+/*!
+ \qmlproperty int ElementOperand::index
+
+ Index of the filter element that is going to be used as operand.
+*/
+
+OpcUaElementOperand::OpcUaElementOperand(QObject *parent)
+ : OpcUaOperandBase(parent)
+{
+}
+
+OpcUaElementOperand::~OpcUaElementOperand() = default;
+
+QVariant OpcUaElementOperand::toCppVariant(QOpcUaClient* client) const
+{
+ Q_UNUSED(client);
+ QOpcUaElementOperand value(*this);
+ return value;
+}
+
+quint32 OpcUaElementOperand::index() const
+{
+ return QOpcUaElementOperand::index();
+}
+
+void OpcUaElementOperand::setIndex(quint32 index)
+{
+ if (index != QOpcUaElementOperand::index()) {
+ QOpcUaElementOperand::setIndex(index);
+ emit dataChanged();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/opcua/opcuaelementoperand.h b/src/imports/opcua/opcuaelementoperand.h
new file mode 100644
index 0000000..33c442c
--- /dev/null
+++ b/src/imports/opcua/opcuaelementoperand.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt OPC UA module.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OPCUAELEMENTOPERAND
+#define OPCUAELEMENTOPERAND
+
+#include "opcuaoperandbase.h"
+#include <QOpcUaElementOperand>
+
+QT_BEGIN_NAMESPACE
+
+class QOpcUaClient;
+
+class OpcUaElementOperand : public OpcUaOperandBase, private QOpcUaElementOperand {
+ Q_OBJECT
+ Q_PROPERTY(quint32 index READ index WRITE setIndex)
+
+public:
+ explicit OpcUaElementOperand(QObject *parent = nullptr);
+ ~OpcUaElementOperand();
+ virtual QVariant toCppVariant(QOpcUaClient *client) const override;
+
+ quint32 index() const;
+ void setIndex(quint32 index);
+
+signals:
+ void dataChanged();
+};
+
+QT_END_NAMESPACE
+
+#endif // OPCUAELEMENTOPERAND
diff --git a/src/imports/opcua/opcuaeventfilter.cpp b/src/imports/opcua/opcuaeventfilter.cpp
new file mode 100644
index 0000000..7002732
--- /dev/null
+++ b/src/imports/opcua/opcuaeventfilter.cpp
@@ -0,0 +1,254 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt OPC UA module.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "opcuaeventfilter.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype EventFilter
+ \inqmlmodule QtOpcUa
+ \brief Defines an EventFilter for a monitored item.
+ \since QtOpcUa 5.13
+
+ An event filter is required for monitoring events on the server.
+ It consists of \c select clauses and a \c where clause.
+
+ The \c select clauses are used to specify the data the user wants to receive when an event occurs.
+ It consists of \l {SimpleAttributeOperand} simple attribute operands which select
+ attributes of child nodes of an event type, for example the value attribute of the "Message"
+ property of BaseEventType.
+
+ The \c where clause is used to restrict the reported events by matching against certain criteria.
+ Several operators and four different operand types allow filtering based on the values of the
+ attributes of the child nodes of an event type.
+
+ The select clause consists of an array of \l SimpleAttributeOperand.
+ The where clause consists of an array of \l SimpleAttributeOperand, \l LiteralOperand, \l ElementOperand or \l AttributeOperand.
+
+ The following EventFilter tells the server to report the value of the "Message" field for events that have a "Severity" field with value >= 500:
+
+ \code
+ import QtOpcUa 5.13 as QtOpcUa
+ QtOpcUa.Node {
+ ...
+
+ eventFilter: QtOpcUa.EventFilter {
+ select: [
+ QtOpcUa.SimpleAttributeOperand {
+ browsePath: [
+ QtOpcUa.NodeId {
+ identifier: "Severity"
+ ns: "http://opcfoundation.org/UA/"
+ }
+ ]
+ },
+ QtOpcUa.SimpleAttributeOperand {
+ browsePath: [
+ QtOpcUa.NodeId {
+ identifier: "Message"
+ ns: "http://opcfoundation.org/UA/"
+ }
+ ]
+ }
+ ]
+
+ where: [
+ QtOpcUa.FilterElement {
+ operator: QtOpcUa.FilterElement.GreaterThanOrEqual
+ firstOperand: QtOpcUa.SimpleAttributeOperand {
+ browsePath: [
+ QtOpcUa.NodeId {
+ identifier: "Severity"
+ ns: "http://opcfoundation.org/UA/"
+ }
+ ]
+ }
+ secondOperand: QtOpcUa.LiteralOperand {
+ value: 700
+ type: QtOpcUa.Constants.UInt16
+ }
+ }
+ ]
+ }
+ }
+ \endcode
+
+ For a more complex example with two conditions, see \l QOpcUaElementOperand.
+
+ \sa FilterElement
+*/
+
+/*!
+ \qmlproperty list<FilterElement> EventFilter::where
+
+ Content filter used to restrict the reported events to events matching certain criteria.
+*/
+
+/*!
+ \qmlproperty list<SimpleAttributeOperand::select
+
+ Selected event fields that shall be included when a new event is reported.
+*/
+
+OpcUaEventFilter::OpcUaEventFilter(QObject *parent)
+ : QObject(parent)
+{
+}
+
+OpcUaEventFilter::~OpcUaEventFilter() = default;
+
+bool OpcUaEventFilter::operator==(const OpcUaEventFilter &other) const
+{
+ return this->m_filterElements == other.m_filterElements
+ && this->m_selectors == other.m_selectors;
+}
+
+QOpcUaMonitoringParameters::EventFilter OpcUaEventFilter::filter(QOpcUaClient *client) const
+{
+ QOpcUaMonitoringParameters::EventFilter filterValue;
+ for (const auto &i : qAsConst(m_selectors))
+ filterValue.selectClausesRef().append(i->toSimpleAttributeOperand(client));
+
+ for (const auto &i : qAsConst(m_filterElements))
+ filterValue.whereClauseRef().append(i->toFilterElement(client));
+
+ return filterValue;
+}
+
+QQmlListProperty<OpcUaFilterElement> OpcUaEventFilter::filterElements()
+{
+ return QQmlListProperty<OpcUaFilterElement>(this, this,
+ &OpcUaEventFilter::appendFilterElement,
+ &OpcUaEventFilter::filterElementCount,
+ &OpcUaEventFilter::filterElement,
+ &OpcUaEventFilter::clearFilterElements);
+}
+
+void OpcUaEventFilter::appendFilterElement(OpcUaFilterElement *nodeId)
+{
+ m_filterElements.append(nodeId);
+ emit dataChanged();
+}
+
+int OpcUaEventFilter::filterElementCount() const
+{
+ return m_filterElements.size();
+}
+
+OpcUaFilterElement *OpcUaEventFilter::filterElement(int index) const
+{
+ return m_filterElements.at(index);
+}
+
+void OpcUaEventFilter::clearFilterElements()
+{
+ m_filterElements.clear();
+ emit dataChanged();
+}
+
+void OpcUaEventFilter::appendFilterElement(QQmlListProperty<OpcUaFilterElement> *list, OpcUaFilterElement *nodeId)
+{
+ reinterpret_cast<OpcUaEventFilter*>(list->data)->appendFilterElement(nodeId);
+}
+
+int OpcUaEventFilter::filterElementCount(QQmlListProperty<OpcUaFilterElement> *list)
+{
+ return reinterpret_cast<OpcUaEventFilter*>(list->data)->filterElementCount();
+}
+
+OpcUaFilterElement *OpcUaEventFilter::filterElement(QQmlListProperty<OpcUaFilterElement> *list, int index)
+{
+ return reinterpret_cast<OpcUaEventFilter*>(list->data)->filterElement(index);
+}
+
+void OpcUaEventFilter::clearFilterElements(QQmlListProperty<OpcUaFilterElement> *list)
+{
+ reinterpret_cast<OpcUaEventFilter*>(list->data)->clearFilterElements();
+}
+
+QQmlListProperty<OpcUaSimpleAttributeOperand> OpcUaEventFilter::selectors()
+{
+ return QQmlListProperty<OpcUaSimpleAttributeOperand>(this, this,
+ &OpcUaEventFilter::appendSelector,
+ &OpcUaEventFilter::selectorCount,
+ &OpcUaEventFilter::selector,
+ &OpcUaEventFilter::clearSelectors);
+}
+
+void OpcUaEventFilter::appendSelector(OpcUaSimpleAttributeOperand *nodeId)
+{
+ m_selectors.append(nodeId);
+ emit dataChanged();
+}
+
+int OpcUaEventFilter::selectorCount() const
+{
+ return m_selectors.size();
+}
+
+OpcUaSimpleAttributeOperand *OpcUaEventFilter::selector(int index) const
+{
+ return m_selectors.at(index);
+}
+
+void OpcUaEventFilter::clearSelectors()
+{
+ m_selectors.clear();
+ emit dataChanged();
+}
+
+void OpcUaEventFilter::appendSelector(QQmlListProperty<OpcUaSimpleAttributeOperand> *list, OpcUaSimpleAttributeOperand *nodeId)
+{
+ reinterpret_cast<OpcUaEventFilter*>(list->data)->appendSelector(nodeId);
+}
+
+int OpcUaEventFilter::selectorCount(QQmlListProperty<OpcUaSimpleAttributeOperand> *list)
+{
+ return reinterpret_cast<OpcUaEventFilter*>(list->data)->selectorCount();
+}
+
+OpcUaSimpleAttributeOperand *OpcUaEventFilter::selector(QQmlListProperty<OpcUaSimpleAttributeOperand> *list, int index)
+{
+ return reinterpret_cast<OpcUaEventFilter*>(list->data)->selector(index);
+}
+
+void OpcUaEventFilter::clearSelectors(QQmlListProperty<OpcUaSimpleAttributeOperand> *list)
+{
+ reinterpret_cast<OpcUaEventFilter*>(list->data)->clearSelectors();
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/opcua/opcuaeventfilter.h b/src/imports/opcua/opcuaeventfilter.h
new file mode 100644
index 0000000..2ef0f9f
--- /dev/null
+++ b/src/imports/opcua/opcuaeventfilter.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt OPC UA module.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OPCUAEVENTFILTER
+#define OPCUAEVENTFILTER
+
+#include <QQmlListProperty>
+
+#include "opcuasimpleattributeoperand.h"
+#include "opcuafilterelement.h"
+#include <QOpcUaMonitoringParameters>
+
+QT_BEGIN_NAMESPACE
+
+class OpcUaNodeId;
+class OpcUaRelativeNodePath;
+
+class OpcUaEventFilter : public QObject {
+ Q_OBJECT
+ Q_PROPERTY(QQmlListProperty<OpcUaFilterElement> where READ filterElements)
+ Q_PROPERTY(QQmlListProperty<OpcUaSimpleAttributeOperand> select READ selectors)
+
+public:
+ explicit OpcUaEventFilter(QObject *parent = nullptr);
+ ~OpcUaEventFilter();
+ bool operator==(const OpcUaEventFilter &other) const;
+ QOpcUaMonitoringParameters::EventFilter filter(QOpcUaClient *client) const;
+
+ QQmlListProperty<OpcUaSimpleAttributeOperand> selectors();
+ void appendSelector(OpcUaSimpleAttributeOperand *selector);
+ int selectorCount() const;
+ OpcUaSimpleAttributeOperand *selector(int index) const;
+ void clearSelectors();
+
+ QQmlListProperty<OpcUaFilterElement> filterElements();
+ void appendFilterElement(OpcUaFilterElement *filterElement);
+ int filterElementCount() const;
+ OpcUaFilterElement *filterElement(int index) const;
+ void clearFilterElements();
+
+signals:
+ void dataChanged();
+
+private:
+ static void appendSelector(QQmlListProperty<OpcUaSimpleAttributeOperand> *list, OpcUaSimpleAttributeOperand *);
+ static int selectorCount(QQmlListProperty<OpcUaSimpleAttributeOperand> *list);
+ static OpcUaSimpleAttributeOperand* selector(QQmlListProperty<OpcUaSimpleAttributeOperand> *list, int index);
+ static void clearSelectors(QQmlListProperty<OpcUaSimpleAttributeOperand> *list);
+
+ static void appendFilterElement(QQmlListProperty<OpcUaFilterElement> *list, OpcUaFilterElement *nodeId);
+ static int filterElementCount(QQmlListProperty<OpcUaFilterElement> *list);
+ static OpcUaFilterElement* filterElement(QQmlListProperty<OpcUaFilterElement> *list, int index);
+ static void clearFilterElements(QQmlListProperty<OpcUaFilterElement> *list);
+
+ QVector<OpcUaFilterElement*> m_filterElements;
+ QVector<OpcUaSimpleAttributeOperand*> m_selectors;
+};
+
+QT_END_NAMESPACE
+
+#endif // OPCUAEVENTFILTER
diff --git a/src/imports/opcua/opcuafilterelement.cpp b/src/imports/opcua/opcuafilterelement.cpp
new file mode 100644
index 0000000..502f59c
--- /dev/null
+++ b/src/imports/opcua/opcuafilterelement.cpp
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt OPC UA module.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "opcuafilterelement.h"
+
+#include "opcuaoperandbase.h"
+
+#include <QOpcUaContentFilterElement>
+#include <QLoggingCategory>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype FilterElement
+ \inqmlmodule QtOpcUa
+ \brief The OPC UA ContentFilterElement.
+ \since QtOpcUa 5.13
+
+ A content filter element contains an operator and operands.
+ There are four different operator types which contain literal values, references to
+ attributes of nodes or to other content filter elements.
+
+ A combination of one or more content filter elements makes a content filter which is used
+ by the server to filter data for the criteria defined by the content filter elements.
+ For example, the \c where clause of an event filter is a content filter which is used to decide
+ if a notification is generated for an event.
+
+ \code
+ QtOpcUa.FilterElement {
+ operator: QtOpcUa.FilterElement.GreaterThanOrEqual
+ firstOperand: QtOpcUa.SimpleAttributeOperand { ... }
+ secondOperand: QtOpcUa.LiteralOperand { ... }
+ }
+ \endcode
+
+ \sa EventFilter
+*/
+
+/*!
+ \qmlproperty FilterElement::FilterOperator
+
+ FilterOperator enumerates all possible operators for a FilterElement that are specified in
+ OPC-UA part 4, Tables 115 and 116.
+
+ \value FilterElement.Equals
+ \value FilterElement.IsNull
+ \value FilterElement.GreaterThan
+ \value FilterElement.LessThan
+ \value FilterElement.GreaterThanOrEqual
+ \value FilterElement.LessThanOrEqual
+ \value FilterElement.Like
+ \value FilterElement.Not
+ \value FilterElement.Between
+ \value FilterElement.InList
+ \value FilterElement.And
+ \value FilterElement.Or
+ \value FilterElement.Cast
+ \value FilterElement.InView
+ \value FilterElement.OfType
+ \value FilterElement.RelatedTo
+ \value FilterElement.BitwiseAnd
+ \value FilterElement.BitwiseOr
+*/
+
+/*!
+ \qmlproperty FilterElement::FilterOperator FilterElement::operatorType
+
+ The filter operator.
+*/
+
+/*!
+ \qmlproperty variant FilterElement::firstOperand
+
+ First operand to be used with the operator.
+ This can be one of \l SimplateAttributeOperand, \l AttributeOperand,
+ \l LiteralOperal or \l ElementOperand.
+*/
+
+/*!
+ \qmlproperty variant FilterElement::secondOperand
+
+ Second operand to be used with the operator.
+ This can be one of \l SimplateAttributeOperand, \l AttributeOperand,
+ \l LiteralOperal or \l ElementOperand.
+*/
+
+
+Q_DECLARE_LOGGING_CATEGORY(QT_OPCUA_PLUGINS_QML)
+
+OpcUaFilterElement::OpcUaFilterElement(QObject *parent)
+ : QObject(parent)
+{
+}
+
+OpcUaFilterElement::~OpcUaFilterElement() = default;
+
+QOpcUaContentFilterElement OpcUaFilterElement::toFilterElement(QOpcUaClient *client)
+{
+ QOpcUaContentFilterElement value;
+ value.setFilterOperator(static_cast<QOpcUaContentFilterElement::FilterOperator>(operatorType()));
+ value.filterOperandsRef().append(m_firstOperand->toCppVariant(client));
+ value.filterOperandsRef().append(m_secondOperand->toCppVariant(client));
+ return value;
+}
+
+OpcUaFilterElement::FilterOperator OpcUaFilterElement::operatorType() const
+{
+ return m_filterOperator;
+}
+
+void OpcUaFilterElement::setOperatorType(OpcUaFilterElement::FilterOperator filterOperator)
+{
+ m_filterOperator = filterOperator;
+}
+
+OpcUaOperandBase *OpcUaFilterElement::firstOperand() const
+{
+ return m_firstOperand;
+}
+
+void OpcUaFilterElement::setFirstOperand(OpcUaOperandBase *operand)
+{
+ if (m_firstOperand != operand) {
+ m_firstOperand = operand;
+ emit dataChanged();
+ }
+}
+
+OpcUaOperandBase *OpcUaFilterElement::secondOperand() const
+{
+ return m_secondOperand;
+}
+
+void OpcUaFilterElement::setSecondOperand(OpcUaOperandBase *operand)
+{
+ if (m_secondOperand != operand) {
+ m_secondOperand = operand;
+ emit dataChanged();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/opcua/opcuafilterelement.h b/src/imports/opcua/opcuafilterelement.h
new file mode 100644
index 0000000..5bf4eb4
--- /dev/null
+++ b/src/imports/opcua/opcuafilterelement.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt OPC UA module.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OPCUAFILTERELEMENT
+#define OPCUAFILTERELEMENT
+
+#include <QObject>
+#include <QOpcUaContentFilterElement>
+
+QT_BEGIN_NAMESPACE
+
+class QOpcUaClient;
+class OpcUaOperandBase;
+
+class OpcUaFilterElement : public QObject {
+ Q_OBJECT
+ Q_PROPERTY(FilterOperator operator READ operatorType WRITE setOperatorType)
+ Q_PROPERTY(OpcUaOperandBase* firstOperand READ firstOperand WRITE setFirstOperand)
+ Q_PROPERTY(OpcUaOperandBase* secondOperand READ secondOperand WRITE setSecondOperand)
+
+public:
+ // Same as in qopcuacontentfilterelement.h
+ // Specified in OPC-UA part 4, Tables 115 and 116
+ enum class FilterOperator : quint32 {
+ Equals = 0,
+ IsNull = 1,
+ GreaterThan = 2,
+ LessThan = 3,
+ GreaterThanOrEqual = 4,
+ LessThanOrEqual = 5,
+ Like = 6,
+ Not = 7,
+ Between = 8,
+ InList = 9,
+ And = 10,
+ Or = 11,
+ Cast = 12,
+ InView = 13,
+ OfType = 14,
+ RelatedTo = 15,
+ BitwiseAnd = 16,
+ BitwiseOr = 17
+ };
+ Q_ENUM(FilterOperator);
+
+ explicit OpcUaFilterElement(QObject *parent = nullptr);
+ ~OpcUaFilterElement();
+ QOpcUaContentFilterElement toFilterElement(QOpcUaClient *);
+
+ FilterOperator operatorType() const;
+ void setOperatorType(FilterOperator filterOperator);
+
+ OpcUaOperandBase *firstOperand() const;
+ void setFirstOperand(OpcUaOperandBase *operand);
+
+ OpcUaOperandBase *secondOperand() const;
+ void setSecondOperand(OpcUaOperandBase *operand);
+
+signals:
+ void dataChanged();
+
+private:
+ FilterOperator m_filterOperator = FilterOperator::Equals;
+ OpcUaOperandBase *m_firstOperand = nullptr;
+ OpcUaOperandBase *m_secondOperand = nullptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // OPCUAFILTERELEMENT
diff --git a/src/imports/opcua/opcualiteraloperand.cpp b/src/imports/opcua/opcualiteraloperand.cpp
new file mode 100644
index 0000000..eb79a53
--- /dev/null
+++ b/src/imports/opcua/opcualiteraloperand.cpp
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt OPC UA module.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "opcualiteraloperand.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype LiteralOperand
+ \inqmlmodule QtOpcUa
+ \brief The OPC UA LiteralOperand type.
+ \since QtOpcUa 5.13
+
+ The LiteralOperand is defined in OPC-UA part 4, 7.4.4.3.
+ It contains a literal value that is to be used as operand for filters.
+
+ Setting the type should be done to match the expected types on the server.
+ Otherwise the type will be guessed and may lead to errors because it does
+ not match on the server.
+
+ \code
+ import QtOpcUa 5.13 as QtOpcUa
+
+ QtOpcUa.LiteralOperand {
+ value: 43.21
+ type: QtOpcUa.Constants.Double
+ }
+ \endcode
+*/
+
+/*!
+ \qmlproperty QOpcUa.Types LiteralOperand::type
+
+ Type of the value of the literal operand.
+*/
+
+/*!
+ \qmlproperty variant LiteralOperand::value
+
+ Value of the literal operand.
+*/
+
+OpcUaLiteralOperand::OpcUaLiteralOperand(QObject *parent)
+ : OpcUaOperandBase(parent)
+ , m_type(QOpcUa::Undefined)
+{
+}
+
+OpcUaLiteralOperand::~OpcUaLiteralOperand() = default;
+
+QVariant OpcUaLiteralOperand::toCppVariant(QOpcUaClient *client) const
+{
+ Q_UNUSED(client);
+ return QOpcUaLiteralOperand(m_value, m_type);
+}
+
+QVariant OpcUaLiteralOperand::value() const
+{
+ return m_value;
+}
+
+void OpcUaLiteralOperand::setValue(const QVariant &value)
+{
+ if (m_value != value) {
+ m_value = value;
+ emit dataChanged();
+ }
+}
+
+QOpcUa::Types OpcUaLiteralOperand::type() const
+{
+ return m_type;
+}
+
+void OpcUaLiteralOperand::setType(QOpcUa::Types type)
+{
+ if (m_type != type) {
+ m_type = type;
+ emit dataChanged();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/opcua/opcualiteraloperand.h b/src/imports/opcua/opcualiteraloperand.h
new file mode 100644
index 0000000..b08dfd7
--- /dev/null
+++ b/src/imports/opcua/opcualiteraloperand.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt OPC UA module.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OPCUALITERALOPERAND
+#define OPCUALITERALOPERAND
+
+#include "opcuaoperandbase.h"
+#include <QOpcUaLiteralOperand>
+#include <qopcuatype.h>
+
+QT_BEGIN_NAMESPACE
+
+class OpcUaLiteralOperand : public OpcUaOperandBase {
+ Q_OBJECT
+ Q_PROPERTY(QVariant value READ value WRITE setValue)
+ Q_PROPERTY(QOpcUa::Types type READ type WRITE setType)
+
+public:
+ explicit OpcUaLiteralOperand(QObject *parent = nullptr);
+ ~OpcUaLiteralOperand();
+ QVariant toCppVariant(QOpcUaClient *client) const override;
+
+ QVariant value() const;
+ void setValue(const QVariant &value);
+
+ QOpcUa::Types type() const;
+ void setType(QOpcUa::Types type);
+
+signals:
+ void dataChanged();
+
+private:
+ QVariant m_value;
+ QOpcUa::Types m_type;
+};
+
+QT_END_NAMESPACE
+
+#endif // OPCUALITERALOPERAND
diff --git a/src/imports/opcua/opcuanode.cpp b/src/imports/opcua/opcuanode.cpp
index 036afeb..d81f287 100644
--- a/src/imports/opcua/opcuanode.cpp
+++ b/src/imports/opcua/opcuanode.cpp
@@ -171,6 +171,15 @@ QT_BEGIN_NAMESPACE
\sa status, errorMessage
*/
+/*!
+ \qmlproperty EventFilter Node::eventFilter
+ \since 5.13
+
+ An event filter allows monitoring events on the server for certain conditions.
+
+ \sa EventFilter
+*/
+
Q_DECLARE_LOGGING_CATEGORY(QT_OPCUA_PLUGINS_QML)
OpcUaNode::OpcUaNode(QObject *parent):
@@ -350,11 +359,52 @@ void OpcUaNode::setupNode(const QString &absoluteNodePath)
setReadyToUse(true);
});
+ connect(m_node, &QOpcUaNode::enableMonitoringFinished, this, [this](QOpcUa::NodeAttribute attr, QOpcUa::UaStatusCode statusCode){
+ if (attr != QOpcUa::NodeAttribute::EventNotifier)
+ return;
+ if (statusCode == QOpcUa::Good) {
+ m_eventFilterActive = true;
+ qCDebug(QT_OPCUA_PLUGINS_QML) << "Event filter was enabled for node" << resolvedNode().fullNodeId();
+ updateEventFilter();
+ } else {
+ qCWarning(QT_OPCUA_PLUGINS_QML) << "Failed to enable event filter for node" << resolvedNode().fullNodeId();
+ setStatus(Status::FailedToSetupMonitoring);
+ }
+ });
+
+ connect(m_node, &QOpcUaNode::disableMonitoringFinished, this, [this](QOpcUa::NodeAttribute attr, QOpcUa::UaStatusCode statusCode){
+ if (attr != QOpcUa::NodeAttribute::EventNotifier)
+ return;
+ if (statusCode == QOpcUa::Good) {
+ m_eventFilterActive = false;
+ qCDebug(QT_OPCUA_PLUGINS_QML) << "Event filter was disabled for node "<< resolvedNode().fullNodeId();
+ } else {
+ qCWarning(QT_OPCUA_PLUGINS_QML) << "Failed to disable event filter for node "<< resolvedNode().fullNodeId();
+ setStatus(Status::FailedToDisableMonitoring);
+ }
+ });
+
+ connect(m_node, &QOpcUaNode::monitoringStatusChanged, this, [this](QOpcUa::NodeAttribute attr, QOpcUaMonitoringParameters::Parameters items,
+ QOpcUa::UaStatusCode statusCode) {
+ Q_UNUSED(items);
+ if (attr != QOpcUa::NodeAttribute::EventNotifier)
+ return;
+ if (statusCode != QOpcUa::Good) {
+ setStatus(Status::FailedToModifyMonitoring);
+ qCWarning(QT_OPCUA_PLUGINS_QML) << "Failed to modify event filter for" << m_node->nodeId();
+ }
+ });
+
+ connect (m_node, &QOpcUaNode::eventOccurred, this, &OpcUaNode::eventOccurred);
+
+
// Read mandatory attributes
if (!m_node->readAttributes(m_attributesToRead)) {
qCWarning(QT_OPCUA_PLUGINS_QML) << "Reading attributes" << m_node->nodeId() << "failed";
setStatus(Status::FailedToReadAttributes);
}
+
+ updateEventFilter();
}
void OpcUaNode::updateNode()
@@ -362,6 +412,45 @@ void OpcUaNode::updateNode()
retrieveAbsoluteNodePath(m_nodeId, [this](const QString &absoluteNodePath) {setupNode(absoluteNodePath);});
}
+OpcUaEventFilter *OpcUaNode::eventFilter() const
+{
+ return m_eventFilter;
+}
+
+void OpcUaNode::setEventFilter(OpcUaEventFilter *eventFilter)
+{
+ bool changed = false;
+
+ if (m_eventFilter) {
+ disconnect(m_eventFilter, &OpcUaEventFilter::dataChanged, this, &OpcUaNode::updateEventFilter);
+ changed = !(*m_eventFilter == *eventFilter);
+ } else {
+ changed = true;
+ }
+
+ m_eventFilter = eventFilter;
+ connect(m_eventFilter, &OpcUaEventFilter::dataChanged, this, &OpcUaNode::updateEventFilter);
+
+ if (changed)
+ emit eventFilterChanged();
+}
+
+
+void OpcUaNode::updateEventFilter()
+{
+ if (!m_connection || !m_node || !m_eventFilter)
+ return;
+
+ if (m_eventFilterActive) {
+ m_node->modifyEventFilter(m_eventFilter->filter(m_connection->m_client));
+ } else {
+ QOpcUaMonitoringParameters parameters;
+ parameters.setFilter(m_eventFilter->filter(m_connection->m_client));
+ m_node->enableMonitoring(QOpcUa::NodeAttribute::EventNotifier, parameters);
+ m_eventFilterActive = true;
+ }
+}
+
void OpcUaNode::setStatus(OpcUaNode::Status status, const QString &message)
{
QString errorMessage(message);
diff --git a/src/imports/opcua/opcuanode.h b/src/imports/opcua/opcuanode.h
index c91107e..b7501a5 100644
--- a/src/imports/opcua/opcuanode.h
+++ b/src/imports/opcua/opcuanode.h
@@ -40,6 +40,7 @@
#include "universalnode.h"
#include "opcuaattributecache.h"
#include "qopcualocalizedtext.h"
+#include "opcuaeventfilter.h"
#include <QDateTime>
QT_BEGIN_NAMESPACE
@@ -59,6 +60,7 @@ class OpcUaNode : public QObject
Q_PROPERTY(bool readyToUse READ readyToUse NOTIFY readyToUseChanged)
Q_PROPERTY(OpcUaNode::Status status READ status NOTIFY statusChanged)
Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged)
+ Q_PROPERTY(OpcUaEventFilter *eventFilter READ eventFilter WRITE setEventFilter NOTIFY eventFilterChanged)
// basic node properties
Q_PROPERTY(QString browseName READ browseName WRITE setBrowseName NOTIFY browseNameChanged)
@@ -105,6 +107,9 @@ public:
OpcUaNode::Status status() const;
const QString &errorMessage() const;
+ OpcUaEventFilter *eventFilter() const;
+ void setEventFilter(OpcUaEventFilter *eventFilter);
+
Q_INVOKABLE QDateTime getSourceTimestamp(QOpcUa::NodeAttribute) const;
Q_INVOKABLE QDateTime getServerTimestamp(QOpcUa::NodeAttribute) const;
@@ -129,10 +134,13 @@ signals:
void descriptionChanged();
void statusChanged();
void errorMessageChanged();
+ void eventFilterChanged();
+ void eventOccurred(const QVariantList&values);
protected slots:
virtual void setupNode(const QString &absoluteNodePath);
void updateNode();
+ void updateEventFilter();
protected:
void setStatus(Status status, const QString &message = QString());
@@ -152,6 +160,8 @@ protected:
QOpcUa::NodeAttributes m_attributesToRead;
Status m_status;
QString m_errorMessage;
+ OpcUaEventFilter *m_eventFilter = nullptr;
+ bool m_eventFilterActive = false;
};
QT_END_NAMESPACE
diff --git a/src/imports/opcua/opcuaoperandbase.cpp b/src/imports/opcua/opcuaoperandbase.cpp
new file mode 100644
index 0000000..967610e
--- /dev/null
+++ b/src/imports/opcua/opcuaoperandbase.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt OPC UA module.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "opcuaoperandbase.h"
+#include <QLoggingCategory>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(QT_OPCUA_PLUGINS_QML)
+
+OpcUaOperandBase::OpcUaOperandBase(QObject *parent)
+ : QObject(parent)
+{
+}
+
+OpcUaOperandBase::~OpcUaOperandBase() = default;
+
+QVariant OpcUaOperandBase::toCppVariant(QOpcUaClient *client) const
+{
+ Q_UNUSED(client);
+ qCWarning(QT_OPCUA_PLUGINS_QML) << "Calling invalid base function of OpcUaOperandBase";
+ return QVariant();
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/opcua/opcuaoperandbase.h b/src/imports/opcua/opcuaoperandbase.h
new file mode 100644
index 0000000..ab9f986
--- /dev/null
+++ b/src/imports/opcua/opcuaoperandbase.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt OPC UA module.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OPCUAOPERANDBASE
+#define OPCUAOPERANDBASE
+
+#include <QObject>
+
+QT_BEGIN_NAMESPACE
+
+class QOpcUaClient;
+
+class OpcUaOperandBase : public QObject {
+ Q_OBJECT
+
+public:
+ explicit OpcUaOperandBase(QObject *parent = nullptr);
+ ~OpcUaOperandBase();
+
+ virtual QVariant toCppVariant(QOpcUaClient *client) const;
+};
+
+QT_END_NAMESPACE
+
+#endif // OPCUAOPERANDBASE
diff --git a/src/imports/opcua/opcuasimpleattributeoperand.cpp b/src/imports/opcua/opcuasimpleattributeoperand.cpp
new file mode 100644
index 0000000..75dec51
--- /dev/null
+++ b/src/imports/opcua/opcuasimpleattributeoperand.cpp
@@ -0,0 +1,247 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt OPC UA module.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "opcuasimpleattributeoperand.h"
+#include "opcuanodeid.h"
+#include "universalnode.h"
+#include <QOpcUaQualifiedName>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype SimpleAttributeOperand
+ \inqmlmodule QtOpcUa
+ \brief The OPC UA SimpleAttributeOperand type.
+ \since QtOpcUa 5.13
+
+ The SimpleAttributeOperand is specified in OPC-UA part 4, 7.4.4.5.
+ It is used when a node attribute is required as operand.
+
+ For example, the following simple attribute operand represents the value
+ of the "Severity" field of the base event type:
+
+ \code
+ import QtOpcUa 5.13 as QtOpcUa
+
+ QtOpcUa.SimpleAttributeOperand {
+ identifier: "Severity"
+ ns: "http://opcfoundation.org/UA/"
+ }
+ \endcode
+*/
+
+/*!
+ \qmlproperty list<OpcUaNodeId> SimpleAttributeOperand::browsePath
+
+ Browse path to the node holding the attribute.
+
+ \code
+ import QtOpcUa 5.13 as QtOpcUa
+
+ QtOpcUA.SimpleAttributeOperand {
+ ...
+ browsePath: [
+ QtOpcUa.NodeId {
+ identifier: "Message"
+ ns: "http://opcfoundation.org/UA/"
+ }
+ ...
+ ]
+ }
+*/
+
+/*!
+ \qmlproperty string SimpleAttributeOperand::indexRange
+
+ Index range string used to identify a single value or subset of the attribute's value.
+
+ \code
+ import QtOpcUa 5.13 as QtOpcUa
+
+ QtOpcUa.SimpleAttributeOperand {
+ ...
+ indexRange: "0:2"
+ }
+ \endcode
+*/
+
+/*!
+ \qmlproperty Constants.NodeAttribute SimpleAttributeOperand::nodeAttribute
+
+ Attribute of the node \l browsePath is pointing to.
+ The default value is \c Constants.NodeAttribute.Value.
+
+ \code
+ import QtOpcUa 5.13 as QtOpcUa
+
+ QtOpcUa.SimpleAttributeOperand {
+ ...
+ nodeAttribute: QtOpcUa.Constants.NodeAttribute.Value
+ }
+ \endcode
+*/
+
+/*!
+ \qmlproperty string SimpleAttributeOperand::typeId
+
+ Node id of the type definition node. The operand will be of the type or one of its subtypes.
+ The default value is \c "ns=0;i=2041".
+
+ \code
+ import QtOpcUa 5.13 as QtOpcUa
+
+ QtOpcUa.SimpleAttributeOperand {
+ ...
+ typeId: "ns=0;i=2041"
+ }
+ \endcode
+*/
+
+OpcUaSimpleAttributeOperand::OpcUaSimpleAttributeOperand(QObject *parent)
+ : OpcUaOperandBase(parent)
+{
+ QOpcUaSimpleAttributeOperand::setTypeId(QStringLiteral("ns=0;i=2041"));
+ QOpcUaSimpleAttributeOperand::setAttributeId(QOpcUa::NodeAttribute::Value);
+}
+
+OpcUaSimpleAttributeOperand::~OpcUaSimpleAttributeOperand() = default;
+
+QOpcUaSimpleAttributeOperand OpcUaSimpleAttributeOperand::toSimpleAttributeOperand(QOpcUaClient *client) const
+{
+ QOpcUaSimpleAttributeOperand value(*this);
+ for (UniversalNode i : m_browsePath) {
+ i.resolveNamespaceNameToIndex(client);
+ value.browsePathRef().append(i.toQualifiedName());
+ }
+ return value;
+}
+
+QVariant OpcUaSimpleAttributeOperand::toCppVariant(QOpcUaClient *client) const
+{
+ return toSimpleAttributeOperand(client);
+}
+
+QString OpcUaSimpleAttributeOperand::indexRange() const
+{
+ return QOpcUaSimpleAttributeOperand::indexRange();
+}
+
+void OpcUaSimpleAttributeOperand::setIndexRange(const QString &indexRange)
+{
+ if (indexRange != QOpcUaSimpleAttributeOperand::indexRange()) {
+ QOpcUaSimpleAttributeOperand::setIndexRange(indexRange);
+ emit dataChanged();
+ }
+}
+
+QOpcUa::NodeAttribute OpcUaSimpleAttributeOperand::nodeAttribute() const
+{
+ return QOpcUaSimpleAttributeOperand::attributeId();
+}
+
+void OpcUaSimpleAttributeOperand::setNodeAttribute(QOpcUa::NodeAttribute nodeAttribute)
+{
+ if (nodeAttribute != QOpcUaSimpleAttributeOperand::attributeId()) {
+ QOpcUaSimpleAttributeOperand::setAttributeId(nodeAttribute);
+ emit dataChanged();
+ }
+}
+
+QString OpcUaSimpleAttributeOperand::typeId() const
+{
+ return QOpcUaSimpleAttributeOperand::typeId();
+}
+
+void OpcUaSimpleAttributeOperand::setTypeId(const QString &typeId)
+{
+ if (typeId != QOpcUaSimpleAttributeOperand::typeId()) {
+ QOpcUaSimpleAttributeOperand::setTypeId(typeId);
+ emit dataChanged();
+ }
+}
+
+QQmlListProperty<OpcUaNodeId> OpcUaSimpleAttributeOperand::browsePath()
+{
+ return QQmlListProperty<OpcUaNodeId>(this, this,
+ &OpcUaSimpleAttributeOperand::appendBrowsePathElement,
+ &OpcUaSimpleAttributeOperand::browsePathSize,
+ &OpcUaSimpleAttributeOperand::browsePathElement,
+ &OpcUaSimpleAttributeOperand::clearBrowsePath);
+}
+
+void OpcUaSimpleAttributeOperand::appendBrowsePathElement(OpcUaNodeId *nodeId)
+{
+ m_browsePath.append(nodeId);
+ emit dataChanged();
+}
+
+int OpcUaSimpleAttributeOperand::browsePathSize() const
+{
+ return m_browsePath.size();
+}
+
+OpcUaNodeId *OpcUaSimpleAttributeOperand::browsePathElement(int index) const
+{
+ return m_browsePath.at(index);
+}
+
+void OpcUaSimpleAttributeOperand::clearBrowsePath()
+{
+ m_browsePath.clear();
+ emit dataChanged();
+}
+
+void OpcUaSimpleAttributeOperand::appendBrowsePathElement(QQmlListProperty<OpcUaNodeId> *list, OpcUaNodeId *nodeId)
+{
+ reinterpret_cast<OpcUaSimpleAttributeOperand*>(list->data)->appendBrowsePathElement(nodeId);
+}
+
+int OpcUaSimpleAttributeOperand::browsePathSize(QQmlListProperty<OpcUaNodeId> *list)
+{
+ return reinterpret_cast<OpcUaSimpleAttributeOperand*>(list->data)->browsePathSize();
+}
+
+OpcUaNodeId *OpcUaSimpleAttributeOperand::browsePathElement(QQmlListProperty<OpcUaNodeId> *list, int index)
+{
+ return reinterpret_cast<OpcUaSimpleAttributeOperand*>(list->data)->browsePathElement(index);
+}
+
+void OpcUaSimpleAttributeOperand::clearBrowsePath(QQmlListProperty<OpcUaNodeId> *list)
+{
+ reinterpret_cast<OpcUaSimpleAttributeOperand*>(list->data)->clearBrowsePath();
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/opcua/opcuasimpleattributeoperand.h b/src/imports/opcua/opcuasimpleattributeoperand.h
new file mode 100644
index 0000000..06072fe
--- /dev/null
+++ b/src/imports/opcua/opcuasimpleattributeoperand.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt OPC UA module.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OPCUASIMPLEATTRIBUTEOPERAND
+#define OPCUASIMPLEATTRIBUTEOPERAND
+
+#include "opcuaoperandbase.h"
+#include <QOpcUaSimpleAttributeOperand>
+#include <QQmlListProperty>
+
+QT_BEGIN_NAMESPACE
+
+class OpcUaNodeId;
+class QOpcUaClient;
+
+class OpcUaSimpleAttributeOperand : public OpcUaOperandBase, private QOpcUaSimpleAttributeOperand {
+ Q_OBJECT
+ Q_PROPERTY(QQmlListProperty<OpcUaNodeId> browsePath READ browsePath)
+ Q_PROPERTY(QString indexRange READ indexRange WRITE setIndexRange)
+ Q_PROPERTY(QOpcUa::NodeAttribute nodeAttribute READ nodeAttribute WRITE setNodeAttribute)
+ Q_PROPERTY(QString typeId READ typeId WRITE setTypeId)
+
+public:
+ explicit OpcUaSimpleAttributeOperand(QObject *parent = nullptr);
+ ~OpcUaSimpleAttributeOperand();
+ QOpcUaSimpleAttributeOperand toSimpleAttributeOperand(QOpcUaClient *client) const;
+ virtual QVariant toCppVariant(QOpcUaClient *client) const override;
+
+ QString indexRange() const;
+ void setIndexRange(const QString &indexRange);
+
+ QOpcUa::NodeAttribute nodeAttribute() const;
+ void setNodeAttribute(QOpcUa::NodeAttribute nodeAttribute);
+
+ QString typeId() const;
+ void setTypeId(const QString &typeId);
+
+ QQmlListProperty<OpcUaNodeId> browsePath();
+ void appendBrowsePathElement(OpcUaNodeId*nodeId);
+ int browsePathSize() const;
+ OpcUaNodeId *browsePathElement(int index) const;
+ void clearBrowsePath();
+
+signals:
+ void dataChanged();
+
+private:
+ static void appendBrowsePathElement(QQmlListProperty<OpcUaNodeId> *list, OpcUaNodeId *nodeId);
+ static int browsePathSize(QQmlListProperty<OpcUaNodeId> *list);
+ static OpcUaNodeId* browsePathElement(QQmlListProperty<OpcUaNodeId> *list, int index);
+ static void clearBrowsePath(QQmlListProperty<OpcUaNodeId> *list);
+
+ QVector<OpcUaNodeId*> m_browsePath;
+};
+
+QT_END_NAMESPACE
+
+#endif // OPCUASIMPLEATTRIBUTEOPERAND
diff --git a/src/opcua/client/qopcuacontentfilterelement.cpp b/src/opcua/client/qopcuacontentfilterelement.cpp
index 2e55b25..583a154 100644
--- a/src/opcua/client/qopcuacontentfilterelement.cpp
+++ b/src/opcua/client/qopcuacontentfilterelement.cpp
@@ -103,6 +103,8 @@ QOpcUaContentFilterElement::QOpcUaContentFilterElement(const QOpcUaContentFilter
{
}
+QOpcUaContentFilterElement::~QOpcUaContentFilterElement() = default;
+
/*!
Sets the values from \a rhs in this content filter element.
*/
@@ -173,10 +175,6 @@ void QOpcUaContentFilterElement::setFilterOperator(QOpcUaContentFilterElement::F
data->filterOperator = filterOperator;
}
-QOpcUaContentFilterElement::~QOpcUaContentFilterElement()
-{
-}
-
/*!
Sets filter operator \a op in this content filter element.
If multiple operators are streamed into one content filter element, only the last operator is used.
diff --git a/tests/auto/declarative/MonitoringFilterTest.qml b/tests/auto/declarative/MonitoringFilterTest.qml
new file mode 100644
index 0000000..a591e8b
--- /dev/null
+++ b/tests/auto/declarative/MonitoringFilterTest.qml
@@ -0,0 +1,181 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt OPC UA module.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.3
+import QtTest 1.0
+import QtOpcUa 5.13 as QtOpcUa
+
+Item {
+ property string backendName
+ property int completedTestCases: 0
+ property int availableTestCases: 0
+ property bool completed: completedTestCases == availableTestCases && availableTestCases > 0
+ property bool shouldRun: false
+
+ onShouldRunChanged: {
+ if (shouldRun)
+ console.log("Running", parent.testName, "with", backendName);
+ }
+
+ QtOpcUa.Connection {
+ id: connection
+ backend: backendName
+ defaultConnection: true
+ }
+
+ QtOpcUa.ServerDiscovery {
+ id: serverDiscovery
+ onServersChanged: {
+ if (!count)
+ return;
+ endpointDiscovery.serverUrl = at(0).discoveryUrls[0];
+ }
+
+ Binding on discoveryUrl {
+ when: shouldRun && Component.completed
+ value: OPCUA_DISCOVERY_URL
+ }
+ }
+
+ QtOpcUa.EndpointDiscovery {
+ id: endpointDiscovery
+ onEndpointsChanged: {
+ if (!count)
+ return;
+ connection.connectToEndpoint(at(0));
+ }
+ }
+
+ Component.onCompleted: {
+ for (var i in children) {
+ if (children[i].objectName == "TestCase")
+ availableTestCases += 1;
+ }
+ }
+
+ Timer {
+ id: timer
+ interval: 2000
+ }
+
+/* // In order to run this test you need to compile the example tutorial_server_event from open62541 master branch.
+ CompletionLoggingTestCase {
+ name: "Event filter"
+ when: node3.readyToUse && shouldRun
+
+ function test_nodeTest() {
+ eventSpy.clear();
+ node4.callMethod();
+ eventSpy.wait();
+ compare(eventSpy.count, 1);
+ compare(eventSpy.signalArguments[0].length, 1);
+ compare(eventSpy.signalArguments[0][0].length, 2);
+ compare(eventSpy.signalArguments[0][0][0], 100);
+ compare(eventSpy.signalArguments[0][0][1].text, "An event has been generated.");
+ }
+
+ QtOpcUa.Node {
+ connection: connection
+ nodeId: QtOpcUa.NodeId {
+ ns: "http://opcfoundation.org/UA/"
+ identifier: "i=2253" // Server object
+ }
+ id: node3
+
+ eventFilter: QtOpcUa.EventFilter {
+ select: [
+ QtOpcUa.SimpleAttributeOperand {
+ browsePath: [
+ QtOpcUa.NodeId {
+ identifier: "Severity"
+ ns: "http://opcfoundation.org/UA/"
+ }
+ ]
+ },
+ QtOpcUa.SimpleAttributeOperand {
+ browsePath: [
+ QtOpcUa.NodeId {
+ identifier: "Message"
+ ns: "http://opcfoundation.org/UA/"
+ }
+ ]
+ }
+ ]
+
+// Where clause is not supported by server yet
+// where: [
+// QtOpcUa.FilterElement {
+// operator: QtOpcUa.FilterElement.GreaterThanOrEqual
+// firstOperand: QtOpcUa.SimpleAttributeOperand {
+// browsePath: [
+// QtOpcUa.NodeId {
+// identifier: "Severity"
+// ns: "http://opcfoundation.org/UA/"
+// }
+// ]
+// }
+// secondOperand: QtOpcUa.LiteralOperand {
+// value: 700
+// type: QtOpcUa.Constants.UInt16
+// }
+// }
+// ]
+ }
+ }
+
+ QtOpcUa.MethodNode {
+ connection: connection
+ nodeId: QtOpcUa.NodeId {
+ ns: "http://opcfoundation.org/UA/"
+ identifier: "i=62541"
+ }
+ objectNodeId: QtOpcUa.NodeId {
+ ns: "http://opcfoundation.org/UA/"
+ identifier: "i=85"
+ }
+ id: node4
+ }
+
+ SignalSpy {
+ id: eventSpy
+ target: node3
+ signalName: "eventOccurred"
+ }
+ }
+*/
+}
+
+
diff --git a/tests/auto/declarative/tst_monitoringFilterTest.qml b/tests/auto/declarative/tst_monitoringFilterTest.qml
new file mode 100644
index 0000000..1adfc74
--- /dev/null
+++ b/tests/auto/declarative/tst_monitoringFilterTest.qml
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt OPC UA module.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.3
+
+BackendTestMultiplier {
+ testName: "MonitoringFilterTest"
+}