From 0b31dca3dc0c892987d3e3d6cf7e50245bb7f93b Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Tue, 30 Apr 2019 11:19:57 +0200 Subject: qml: Event filter support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I0631f4c4f23ef2f5e7665861d14c2c168502c1ae Reviewed-by: Jannis Völker Reviewed-by: Qt CI Bot --- src/imports/opcua/opcua.pro | 14 ++ src/imports/opcua/opcua_plugin.cpp | 12 + src/imports/opcua/opcuaattributeoperand.cpp | 250 ++++++++++++++++++++ src/imports/opcua/opcuaattributeoperand.h | 96 ++++++++ src/imports/opcua/opcuaelementoperand.cpp | 141 ++++++++++++ src/imports/opcua/opcuaelementoperand.h | 65 ++++++ src/imports/opcua/opcuaeventfilter.cpp | 254 +++++++++++++++++++++ src/imports/opcua/opcuaeventfilter.h | 94 ++++++++ src/imports/opcua/opcuafilterelement.cpp | 175 ++++++++++++++ src/imports/opcua/opcuafilterelement.h | 103 +++++++++ src/imports/opcua/opcualiteraloperand.cpp | 116 ++++++++++ src/imports/opcua/opcualiteraloperand.h | 72 ++++++ src/imports/opcua/opcuanode.cpp | 89 ++++++++ src/imports/opcua/opcuanode.h | 10 + src/imports/opcua/opcuaoperandbase.cpp | 58 +++++ src/imports/opcua/opcuaoperandbase.h | 58 +++++ src/imports/opcua/opcuasimpleattributeoperand.cpp | 247 ++++++++++++++++++++ src/imports/opcua/opcuasimpleattributeoperand.h | 91 ++++++++ src/opcua/client/qopcuacontentfilterelement.cpp | 6 +- tests/auto/declarative/MonitoringFilterTest.qml | 181 +++++++++++++++ .../auto/declarative/tst_monitoringFilterTest.qml | 41 ++++ 21 files changed, 2169 insertions(+), 4 deletions(-) create mode 100644 src/imports/opcua/opcuaattributeoperand.cpp create mode 100644 src/imports/opcua/opcuaattributeoperand.h create mode 100644 src/imports/opcua/opcuaelementoperand.cpp create mode 100644 src/imports/opcua/opcuaelementoperand.h create mode 100644 src/imports/opcua/opcuaeventfilter.cpp create mode 100644 src/imports/opcua/opcuaeventfilter.h create mode 100644 src/imports/opcua/opcuafilterelement.cpp create mode 100644 src/imports/opcua/opcuafilterelement.h create mode 100644 src/imports/opcua/opcualiteraloperand.cpp create mode 100644 src/imports/opcua/opcualiteraloperand.h create mode 100644 src/imports/opcua/opcuaoperandbase.cpp create mode 100644 src/imports/opcua/opcuaoperandbase.h create mode 100644 src/imports/opcua/opcuasimpleattributeoperand.cpp create mode 100644 src/imports/opcua/opcuasimpleattributeoperand.h create mode 100644 tests/auto/declarative/MonitoringFilterTest.qml create mode 100644 tests/auto/declarative/tst_monitoringFilterTest.qml 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 #include @@ -147,6 +153,12 @@ void OpcUaPlugin::registerTypes(const char *uri) qmlRegisterType(uri, major, minor, "ServerDiscovery"); qmlRegisterUncreatableType(uri, major, minor, "UserTokenPolicy", "This type can not be created."); qmlRegisterType(uri, major, minor, "DataChangeFilter"); + qmlRegisterType(uri, major, minor, "ElementOperand"); + qmlRegisterType(uri, major, minor, "LiteralOperand"); + qmlRegisterType(uri, major, minor, "SimpleAttributeOperand"); + qmlRegisterType(uri, major, minor, "AttributeOperand"); + qmlRegisterType(uri, major, minor, "FilterElement"); + qmlRegisterType(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 + +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 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 OpcUaAttributeOperand::browsePath() +{ + return QQmlListProperty(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 *list, OpcUaRelativeNodePath *nodeId) +{ + reinterpret_cast(list->data)->appendBrowsePathElement(nodeId); +} + +int OpcUaAttributeOperand::browsePathSize(QQmlListProperty *list) +{ + return reinterpret_cast(list->data)->browsePathSize(); +} + +OpcUaRelativeNodePath *OpcUaAttributeOperand::browsePathElement(QQmlListProperty *list, int index) +{ + return reinterpret_cast(list->data)->browsePathElement(index); +} + +void OpcUaAttributeOperand::clearBrowsePath(QQmlListProperty *list) +{ + reinterpret_cast(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 +#include + +QT_BEGIN_NAMESPACE + +class OpcUaNodeId; +class OpcUaRelativeNodePath; +class QOpcUaClient; + +class OpcUaAttributeOperand : public OpcUaOperandBase, private QOpcUaAttributeOperand { + Q_OBJECT + Q_PROPERTY(QQmlListProperty 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 browsePath(); + void appendBrowsePathElement(OpcUaRelativeNodePath *nodeId); + int browsePathSize() const; + OpcUaRelativeNodePath *browsePathElement(int index) const; + void clearBrowsePath(); + +signals: + void dataChanged(); + +private: + static void appendBrowsePathElement(QQmlListProperty *list, OpcUaRelativeNodePath *nodeId); + static int browsePathSize(QQmlListProperty *list); + static OpcUaRelativeNodePath* browsePathElement(QQmlListProperty *list, int index); + static void clearBrowsePath(QQmlListProperty *list); + + QVector 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 + +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 EventFilter::where + + Content filter used to restrict the reported events to events matching certain criteria. +*/ + +/*! + \qmlproperty listm_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 OpcUaEventFilter::filterElements() +{ + return QQmlListProperty(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 *list, OpcUaFilterElement *nodeId) +{ + reinterpret_cast(list->data)->appendFilterElement(nodeId); +} + +int OpcUaEventFilter::filterElementCount(QQmlListProperty *list) +{ + return reinterpret_cast(list->data)->filterElementCount(); +} + +OpcUaFilterElement *OpcUaEventFilter::filterElement(QQmlListProperty *list, int index) +{ + return reinterpret_cast(list->data)->filterElement(index); +} + +void OpcUaEventFilter::clearFilterElements(QQmlListProperty *list) +{ + reinterpret_cast(list->data)->clearFilterElements(); +} + +QQmlListProperty OpcUaEventFilter::selectors() +{ + return QQmlListProperty(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 *list, OpcUaSimpleAttributeOperand *nodeId) +{ + reinterpret_cast(list->data)->appendSelector(nodeId); +} + +int OpcUaEventFilter::selectorCount(QQmlListProperty *list) +{ + return reinterpret_cast(list->data)->selectorCount(); +} + +OpcUaSimpleAttributeOperand *OpcUaEventFilter::selector(QQmlListProperty *list, int index) +{ + return reinterpret_cast(list->data)->selector(index); +} + +void OpcUaEventFilter::clearSelectors(QQmlListProperty *list) +{ + reinterpret_cast(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 + +#include "opcuasimpleattributeoperand.h" +#include "opcuafilterelement.h" +#include + +QT_BEGIN_NAMESPACE + +class OpcUaNodeId; +class OpcUaRelativeNodePath; + +class OpcUaEventFilter : public QObject { + Q_OBJECT + Q_PROPERTY(QQmlListProperty where READ filterElements) + Q_PROPERTY(QQmlListProperty select READ selectors) + +public: + explicit OpcUaEventFilter(QObject *parent = nullptr); + ~OpcUaEventFilter(); + bool operator==(const OpcUaEventFilter &other) const; + QOpcUaMonitoringParameters::EventFilter filter(QOpcUaClient *client) const; + + QQmlListProperty selectors(); + void appendSelector(OpcUaSimpleAttributeOperand *selector); + int selectorCount() const; + OpcUaSimpleAttributeOperand *selector(int index) const; + void clearSelectors(); + + QQmlListProperty filterElements(); + void appendFilterElement(OpcUaFilterElement *filterElement); + int filterElementCount() const; + OpcUaFilterElement *filterElement(int index) const; + void clearFilterElements(); + +signals: + void dataChanged(); + +private: + static void appendSelector(QQmlListProperty *list, OpcUaSimpleAttributeOperand *); + static int selectorCount(QQmlListProperty *list); + static OpcUaSimpleAttributeOperand* selector(QQmlListProperty *list, int index); + static void clearSelectors(QQmlListProperty *list); + + static void appendFilterElement(QQmlListProperty *list, OpcUaFilterElement *nodeId); + static int filterElementCount(QQmlListProperty *list); + static OpcUaFilterElement* filterElement(QQmlListProperty *list, int index); + static void clearFilterElements(QQmlListProperty *list); + + QVector m_filterElements; + QVector 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 +#include + +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(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 +#include + +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 +#include + +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 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 + +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 + +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 + +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 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 OpcUaSimpleAttributeOperand::browsePath() +{ + return QQmlListProperty(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 *list, OpcUaNodeId *nodeId) +{ + reinterpret_cast(list->data)->appendBrowsePathElement(nodeId); +} + +int OpcUaSimpleAttributeOperand::browsePathSize(QQmlListProperty *list) +{ + return reinterpret_cast(list->data)->browsePathSize(); +} + +OpcUaNodeId *OpcUaSimpleAttributeOperand::browsePathElement(QQmlListProperty *list, int index) +{ + return reinterpret_cast(list->data)->browsePathElement(index); +} + +void OpcUaSimpleAttributeOperand::clearBrowsePath(QQmlListProperty *list) +{ + reinterpret_cast(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 +#include + +QT_BEGIN_NAMESPACE + +class OpcUaNodeId; +class QOpcUaClient; + +class OpcUaSimpleAttributeOperand : public OpcUaOperandBase, private QOpcUaSimpleAttributeOperand { + Q_OBJECT + Q_PROPERTY(QQmlListProperty 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 browsePath(); + void appendBrowsePathElement(OpcUaNodeId*nodeId); + int browsePathSize() const; + OpcUaNodeId *browsePathElement(int index) const; + void clearBrowsePath(); + +signals: + void dataChanged(); + +private: + static void appendBrowsePathElement(QQmlListProperty *list, OpcUaNodeId *nodeId); + static int browsePathSize(QQmlListProperty *list); + static OpcUaNodeId* browsePathElement(QQmlListProperty *list, int index); + static void clearBrowsePath(QQmlListProperty *list); + + QVector 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" +} -- cgit v1.2.3