diff options
Diffstat (limited to 'src')
26 files changed, 2577 insertions, 2 deletions
diff --git a/src/opcua/client/client.pri b/src/opcua/client/client.pri index 44eb9fc..c6167d3 100644 --- a/src/opcua/client/client.pri +++ b/src/opcua/client/client.pri @@ -21,7 +21,11 @@ SOURCES += \ client/qopcuareadresult.cpp \ client/qopcuanodeids.cpp \ client/qopcuawriteitem.cpp \ - client/qopcuawriteresult.cpp + client/qopcuawriteresult.cpp \ + client/qopcuanodecreationattributes.cpp \ + client/qopcuaaddreferenceitem.cpp \ + client/qopcuadeletereferenceitem.cpp \ + client/qopcuaaddnodeitem.cpp HEADERS += \ client/qopcuaclient_p.h \ @@ -38,4 +42,9 @@ HEADERS += \ client/qopcuareadresult.h \ client/qopcuanodeids.h \ client/qopcuawriteitem.h \ - client/qopcuawriteresult.h + client/qopcuawriteresult.h \ + client/qopcuanodecreationattributes.h \ + client/qopcuanodecreationattributes_p.h \ + client/qopcuaaddnodeitem.h \ + client/qopcuaaddreferenceitem.h \ + client/qopcuadeletereferenceitem.h diff --git a/src/opcua/client/qopcuaaddnodeitem.cpp b/src/opcua/client/qopcuaaddnodeitem.cpp new file mode 100644 index 0000000..62eea3e --- /dev/null +++ b/src/opcua/client/qopcuaaddnodeitem.cpp @@ -0,0 +1,215 @@ +/**************************************************************************** +** +** Copyright (C) 2018 basysKom GmbH, opensource@basyskom.com +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtOpcUa module of the Qt Toolkit. +** +** $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 "qopcuanodecreationattributes.h" +#include "qopcuaaddnodeitem.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QOpcUaAddNodeItem + \inmodule QtOpcUa + \brief This class stores the necessary information to create a new node on the server. + + \sa QOpcUaClient::addNode() +*/ + +class QOpcUaAddNodeItemData : public QSharedData +{ +public: + QOpcUa::QExpandedNodeId parentNodeId; + QString referenceTypeId; + QOpcUa::QExpandedNodeId requestedNewNodeId; + QOpcUa::QQualifiedName browseName; + QOpcUa::NodeClass nodeClass {QOpcUa::NodeClass::Object}; + QOpcUaNodeCreationAttributes nodeAttributes; + QOpcUa::QExpandedNodeId typeDefinition; +}; + +QOpcUaAddNodeItem::QOpcUaAddNodeItem() + : data(new QOpcUaAddNodeItemData) +{ +} + +/*! + Constructs a add node item from \a other. +*/ +QOpcUaAddNodeItem::QOpcUaAddNodeItem(const QOpcUaAddNodeItem &other) + : data(other.data) +{ +} + +/*! + Assigns the values from \a rhs to this add node item. +*/ +QOpcUaAddNodeItem &QOpcUaAddNodeItem::operator=(const QOpcUaAddNodeItem &rhs) +{ + if (this != &rhs) + data.operator=(rhs.data); + return *this; +} + +QOpcUaAddNodeItem::~QOpcUaAddNodeItem() +{ +} + +/*! + Returns the node id of the type definition node. +*/ +QOpcUa::QExpandedNodeId QOpcUaAddNodeItem::typeDefinition() const +{ + return data->typeDefinition; +} + +/*! + Sets the node id of the type definition node to \a typeDefinition. This value shall be set if the node class + is not Object or Variable. +*/ +void QOpcUaAddNodeItem::setTypeDefinition(const QOpcUa::QExpandedNodeId &typeDefinition) +{ + data->typeDefinition = typeDefinition; +} + +/*! + Returns the values for the node attributes of the new node. +*/ +QOpcUaNodeCreationAttributes QOpcUaAddNodeItem::nodeAttributes() const +{ + return data->nodeAttributes; +} + +/*! + Returns a reference to the values for the node attributes of the new node. +*/ +QOpcUaNodeCreationAttributes &QOpcUaAddNodeItem::nodeAttributesRef() +{ + return data->nodeAttributes; +} + +/*! + Sets the values for the node attributes of the new node to \a nodeAttributes. + Only the attributes supported by the node class of the new node will be used. +*/ +void QOpcUaAddNodeItem::setNodeAttributes(const QOpcUaNodeCreationAttributes &nodeAttributes) +{ + data->nodeAttributes = nodeAttributes; +} + +/*! + Returns the node class of the new node. +*/ +QOpcUa::NodeClass QOpcUaAddNodeItem::nodeClass() const +{ + return data->nodeClass; +} + +/*! + Sets the node class of the new node to \a nodeClass. +*/ +void QOpcUaAddNodeItem::setNodeClass(const QOpcUa::NodeClass &nodeClass) +{ + data->nodeClass = nodeClass; +} + +/*! + Returns the browse name of the new node. +*/ +QOpcUa::QQualifiedName QOpcUaAddNodeItem::browseName() const +{ + return data->browseName; +} + +/*! + Sets the browse name of the new node to \a browseName. +*/ +void QOpcUaAddNodeItem::setBrowseName(const QOpcUa::QQualifiedName &browseName) +{ + data->browseName = browseName; +} + +/*! + Returns the requested new node id. +*/ +QOpcUa::QExpandedNodeId QOpcUaAddNodeItem::requestedNewNodeId() const +{ + return data->requestedNewNodeId; +} + +/*! + Sets the requested new node id to \a requestedNewNodeId. +*/ +void QOpcUaAddNodeItem::setRequestedNewNodeId(const QOpcUa::QExpandedNodeId &requestedNewNodeId) +{ + data->requestedNewNodeId = requestedNewNodeId; +} + +/*! + Returns the reference type id. +*/ +QString QOpcUaAddNodeItem::referenceTypeId() const +{ + return data->referenceTypeId; +} + +/*! + Sets the reference type id to \a referenceTypeId. A reference of this type will be used to connect + the node to the parent node. +*/ +void QOpcUaAddNodeItem::setReferenceTypeId(const QString &referenceTypeId) +{ + data->referenceTypeId = referenceTypeId; +} + +/*! + Returns the parent node id. +*/ +QOpcUa::QExpandedNodeId QOpcUaAddNodeItem::parentNodeId() const +{ + return data->parentNodeId; +} + +/*! + Sets the parent node id to \a parentNodeId. A reference of the type set in \l setReferenceTypeId() + from this node to the newly added node will be created. + + \sa setReferenceTypeId() +*/ +void QOpcUaAddNodeItem::setParentNodeId(const QOpcUa::QExpandedNodeId &parentNodeId) +{ + data->parentNodeId = parentNodeId; +} + +QT_END_NAMESPACE diff --git a/src/opcua/client/qopcuaaddnodeitem.h b/src/opcua/client/qopcuaaddnodeitem.h new file mode 100644 index 0000000..188dba7 --- /dev/null +++ b/src/opcua/client/qopcuaaddnodeitem.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2018 basysKom GmbH, opensource@basyskom.com +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtOpcUa module of the Qt Toolkit. +** +** $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 QOPCUADDNODEITEM_H +#define QOPCUADDNODEITEM_H + +#include <QtOpcUa/qopcuanodecreationattributes.h> +#include <QtOpcUa/qopcuatype.h> + +QT_BEGIN_NAMESPACE + +class QOpcUaAddNodeItemData; +class Q_OPCUA_EXPORT QOpcUaAddNodeItem +{ +public: + QOpcUaAddNodeItem(); + QOpcUaAddNodeItem(const QOpcUaAddNodeItem &); + QOpcUaAddNodeItem &operator=(const QOpcUaAddNodeItem &); + ~QOpcUaAddNodeItem(); + + QOpcUa::QExpandedNodeId parentNodeId() const; + void setParentNodeId(const QOpcUa::QExpandedNodeId &parentNodeId); + + QString referenceTypeId() const; + void setReferenceTypeId(const QString &referenceTypeId); + + QOpcUa::QExpandedNodeId requestedNewNodeId() const; + void setRequestedNewNodeId(const QOpcUa::QExpandedNodeId &requestedNewNodeId); + + QOpcUa::QQualifiedName browseName() const; + void setBrowseName(const QOpcUa::QQualifiedName &browseName); + + QOpcUa::NodeClass nodeClass() const; + void setNodeClass(const QOpcUa::NodeClass &nodeClass); + + QOpcUaNodeCreationAttributes nodeAttributes() const; + QOpcUaNodeCreationAttributes &nodeAttributesRef(); + void setNodeAttributes(const QOpcUaNodeCreationAttributes &nodeAttributes); + + QOpcUa::QExpandedNodeId typeDefinition() const; + void setTypeDefinition(const QOpcUa::QExpandedNodeId &typeDefinition); + +private: + QSharedDataPointer<QOpcUaAddNodeItemData> data; +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QOpcUaAddNodeItem) + +#endif // QOPCUADDNODEITEM_H diff --git a/src/opcua/client/qopcuaaddreferenceitem.cpp b/src/opcua/client/qopcuaaddreferenceitem.cpp new file mode 100644 index 0000000..305500e --- /dev/null +++ b/src/opcua/client/qopcuaaddreferenceitem.cpp @@ -0,0 +1,189 @@ +/**************************************************************************** +** +** Copyright (C) 2018 basysKom GmbH, opensource@basyskom.com +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtOpcUa module of the Qt Toolkit. +** +** $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 "qopcuanodecreationattributes.h" +#include "qopcuaaddreferenceitem.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QOpcUaAddReferenceItem + \inmodule QtOpcUa + \brief This class stores the necessary information to add a new reference on the server. + + \sa QOpcUaClient::addReference() +*/ +class QOpcUaAddReferenceItemData : public QSharedData +{ +public: + QString sourceNodeId; + QString referenceTypeId; + bool isForward {true}; + QOpcUa::QExpandedNodeId targetNodeId; + QOpcUa::NodeClass targetNodeClass {QOpcUa::NodeClass::Undefined}; + QString targetServerUri; +}; + +QOpcUaAddReferenceItem::QOpcUaAddReferenceItem() + : data(new QOpcUaAddReferenceItemData) +{ +} + +/*! + Constructs an add reference item from \a other. +*/ +QOpcUaAddReferenceItem::QOpcUaAddReferenceItem(const QOpcUaAddReferenceItem &other) + : data(other.data) +{ + +} + +/*! + Sets the values from \a rhs in this add reference item. +*/ +QOpcUaAddReferenceItem &QOpcUaAddReferenceItem::operator=(const QOpcUaAddReferenceItem &rhs) +{ + if (this != &rhs) + data.operator=(rhs.data); + return *this; +} + +QOpcUaAddReferenceItem::~QOpcUaAddReferenceItem() +{ +} + +/*! + Returns the target node class. +*/ +QOpcUa::NodeClass QOpcUaAddReferenceItem::targetNodeClass() const +{ + return data->targetNodeClass; +} + +/*! + Sets the node class of the target node to \a targetNodeClass. + The target node class shall be specified because the target node might be located on another server. +*/ +void QOpcUaAddReferenceItem::setTargetNodeClass(QOpcUa::NodeClass targetNodeClass) +{ + data->targetNodeClass = targetNodeClass; +} + +/*! + Returns the target server URI. +*/ +QString QOpcUaAddReferenceItem::targetServerUri() const +{ + return data->targetServerUri; +} + +/*! + Sets the URI of the target server to \a targetServerUri. + If this value is set, it will override the server URI from \l setTargetNodeId(). +*/ +void QOpcUaAddReferenceItem::setTargetServerUri(const QString &targetServerUri) +{ + data->targetServerUri = targetServerUri; +} + +/*! + Returns the target node id. +*/ +QOpcUa::QExpandedNodeId QOpcUaAddReferenceItem::targetNodeId() const +{ + return data->targetNodeId; +} + +/*! + Sets the node id of the target node to \a targetNodeId. +*/ +void QOpcUaAddReferenceItem::setTargetNodeId(const QOpcUa::QExpandedNodeId &targetNodeId) +{ + data->targetNodeId = targetNodeId; +} + +/*! + Returns the isForward flag. +*/ +bool QOpcUaAddReferenceItem::isForward() const +{ + return data->isForward; +} + +/*! + Sets the isForward flag to \a isForward. + If the flag is set, a forward reference is created. + Otherwise, an inverse reference is created. +*/ +void QOpcUaAddReferenceItem::setIsForward(bool isForward) +{ + data->isForward = isForward; +} + +/*! + Returns the reference type id. +*/ +QString QOpcUaAddReferenceItem::referenceTypeId() const +{ + return data->referenceTypeId; +} + +/*! + Sets the reference type id to \a referenceTypeId. + A reference of this type will be created on the server. +*/ +void QOpcUaAddReferenceItem::setReferenceTypeId(const QString &referenceTypeId) +{ + data->referenceTypeId = referenceTypeId; +} + +/*! + Returns the source node id. +*/ +QString QOpcUaAddReferenceItem::sourceNodeId() const +{ + return data->sourceNodeId; +} + +/*! + Sets the node id of the source node to \a sourceNodeId. +*/ +void QOpcUaAddReferenceItem::setSourceNodeId(const QString &sourceNodeId) +{ + data->sourceNodeId = sourceNodeId; +} + +QT_END_NAMESPACE diff --git a/src/opcua/client/qopcuaaddreferenceitem.h b/src/opcua/client/qopcuaaddreferenceitem.h new file mode 100644 index 0000000..eb50bf4 --- /dev/null +++ b/src/opcua/client/qopcuaaddreferenceitem.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2018 basysKom GmbH, opensource@basyskom.com +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtOpcUa module of the Qt Toolkit. +** +** $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 QOPCUAADDREFERENCEITEM_H +#define QOPCUAADDREFERENCEITEM_H + +#include <QtOpcUa/qopcuanodecreationattributes.h> +#include <QtOpcUa/qopcuatype.h> + +QT_BEGIN_NAMESPACE + +class QOpcUaAddReferenceItemData; +class Q_OPCUA_EXPORT QOpcUaAddReferenceItem +{ +public: + QOpcUaAddReferenceItem(); + QOpcUaAddReferenceItem(const QOpcUaAddReferenceItem &other); + QOpcUaAddReferenceItem &operator=(const QOpcUaAddReferenceItem &rhs); + ~QOpcUaAddReferenceItem(); + + QString sourceNodeId() const; + void setSourceNodeId(const QString &sourceNodeId); + + QString referenceTypeId() const; + void setReferenceTypeId(const QString &referenceTypeId); + + bool isForward() const; + void setIsForward(bool isForward); + + QOpcUa::QExpandedNodeId targetNodeId() const; + void setTargetNodeId(const QOpcUa::QExpandedNodeId &targetNodeId); + + QOpcUa::NodeClass targetNodeClass() const; + void setTargetNodeClass(QOpcUa::NodeClass targetNodeClass); + + QString targetServerUri() const; + void setTargetServerUri(const QString &targetServerUri); + +private: + QSharedDataPointer<QOpcUaAddReferenceItemData> data; +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QOpcUaAddReferenceItem) + +#endif // QOPCUAADDREFERENCEITEM_H diff --git a/src/opcua/client/qopcuabackend_p.h b/src/opcua/client/qopcuabackend_p.h index 5ed80b7..628d2a5 100644 --- a/src/opcua/client/qopcuabackend_p.h +++ b/src/opcua/client/qopcuabackend_p.h @@ -97,6 +97,13 @@ Q_SIGNALS: void batchReadFinished(QVector<QOpcUaReadResult> results, QOpcUa::UaStatusCode serviceResult); void batchWriteFinished(QVector<QOpcUaWriteResult> results, QOpcUa::UaStatusCode serviceResult); + void addNodeFinished(QOpcUa::QExpandedNodeId requestedNodeId, QString assignedNodeId, QOpcUa::UaStatusCode statusCode); + void deleteNodeFinished(QString nodeId, QOpcUa::UaStatusCode statusCode); + void addReferenceFinished(QString sourceNodeId, QString referenceTypeId, QOpcUa::QExpandedNodeId targetNodeId, bool isForward, + QOpcUa::UaStatusCode statusCode); + void deleteReferenceFinished(QString sourceNodeId, QString referenceTypeId, QOpcUa::QExpandedNodeId targetNodeId, bool isForward, + QOpcUa::UaStatusCode statusCode); + private: Q_DISABLE_COPY(QOpcUaBackend) }; diff --git a/src/opcua/client/qopcuaclient.cpp b/src/opcua/client/qopcuaclient.cpp index de4e863..f484df7 100644 --- a/src/opcua/client/qopcuaclient.cpp +++ b/src/opcua/client/qopcuaclient.cpp @@ -214,6 +214,39 @@ Q_DECLARE_LOGGING_CATEGORY(QT_OPCUA) */ /*! + \fn void QOpcUaClient::addNodeFinished(QOpcUa::QExpandedNodeId requestedNodeId, QString assignedNodeId, QOpcUa::UaStatusCode statusCode) + + This signal is emitted after an \l addNode() operation has finished. + \a requestedNodeId is the requested node id from the \l addNode() call, \a assignedNodeId is the node id the server has assigned to the new node. + \a statusCode contains the result of the operation. If the result is \l {QOpcUa::UaStatusCode} {Bad}, \a assignedNodeId is empty and no node + has been added to the server's address space. +*/ + +/*! + \fn void QOpcUaClient::deleteNodeFinished(QString nodeId, QOpcUa::UaStatusCode statusCode) + + This signal is emitted after a \l deleteNode() operation has finished. + \a nodeId is the node id from the \l deleteNode() call. + \a statusCode contains the result of the operation. +*/ + +/*! + \fn void QOpcUaClient::addReferenceFinished(QString sourceNodeId, QString referenceTypeId, QOpcUa::QExpandedNodeId targetNodeId, bool isForward, QOpcUa::UaStatusCode statusCode) + + This signal is emitted after an \l addReference() operation has finished. + \a sourceNodeId, \a referenceTypeId, \a targetNodeId and \a isForward are the values from the \l addReference() call. + \a statusCode contains the result of the operation. +*/ + +/*! + \fn void QOpcUaClient::deleteReferenceFinished(QString sourceNodeId, QString referenceTypeId, QOpcUa::QExpandedNodeId targetNodeId, bool isForward, QOpcUa::UaStatusCode statusCode) + + This signal is emitted after a \l deleteReference() operation has finished. + \a sourceNodeId, \a referenceTypeId, \a targetNodeId and \a isForward are the values from the \l deleteReference() call. + \a statusCode contains the result of the operation. +*/ + +/*! \internal QOpcUaClientImpl is an opaque type (as seen from the public API). This prevents users of the public API to use this constructor (eventhough it is public). @@ -439,6 +472,135 @@ QOpcUa::QQualifiedName QOpcUaClient::qualifiedNameFromNamespaceUri(const QString *ok = true; return QOpcUa::QQualifiedName(index, name); +}; + +/*! + Adds the node described by \a nodeToAdd on the server. + + Returns \c true if the asynchronous call has been successfully dispatched. + + The success of the operation is returned in the \l addNodeFinished() signal. + + The following example code adds new a Variable node on the server: + + \code + QOpcUaNodeCreationAttributes attributes; + attributes.setDisplayName(QOpcUa::QLocalizedText("en", "My new Variable node")); + attributes.setDescription(QOpcUa::QLocalizedText("en", "A node which has been added at runtime")); + attributes.setValue(23.0, QOpcUa::Types::Double); + attributes.setDataTypeId(QOpcUa::ns0ID(QOpcUa::NodeIds::NS0::Double)); + attributes.setValueRank(-2); // Scalar or array + attributes.setAccessLevel(QOpcUa::AccessLevelBit::CurrentRead); + attributes.setUserAccessLevel(QOpcUa::AccessLevelBit::CurrentRead); + + QOpcUaAddNodeItem item; + item.setParentNodeId(QOpcUa::QExpandedNodeId("ns=3;s=TestFolder")); + item.setReferenceTypeId(QOpcUa::nodeIdFromReferenceType(QOpcUa::ReferenceTypeId::Organizes)); + item.setRequestedNewNodeId(QOpcUa::QExpandedNodeId("ns=3;s=MyNewVariableNode")); + item.setBrowseName(QOpcUa::QQualifiedName(3, "MyNewVariableNode")); + item.setNodeClass(QOpcUa::NodeClass::Variable); + item.setNodeAttributes(attributes); + + m_client->addNode(item); + \endcode + + \sa deleteNode() addNodeFinished() QOpcUaAddNodeItem +*/ +bool QOpcUaClient::addNode(const QOpcUaAddNodeItem &nodeToAdd) +{ + if (state() != QOpcUaClient::Connected) + return false; + + Q_D(QOpcUaClient); + return d->m_impl->addNode(nodeToAdd); +} + +/*! + Deletes the node with node id \a nodeId from the server. + If \a deleteTargetReferences is \c false, only the references with source node \a nodeId are deleted. + If \a deleteTargetReferences is \c true, references with \a nodeId as target are deleted too. + + Returns \c true if the asynchronous call has been successfully dispatched. + + The success of the operation is returned in the \l deleteNodeFinished() signal. + + The following example code deletes a node and all references to it from the server: + + \code + m_client->deleteNode(QOpcUa::QExpandedNodeId("ns=3;s=MyNewVariableNode"), true); + \endcode + + \sa addNode() deleteNodeFinished() +*/ +bool QOpcUaClient::deleteNode(const QString &nodeId, bool deleteTargetReferences) +{ + if (state() != QOpcUaClient::Connected) + return false; + + Q_D(QOpcUaClient); + return d->m_impl->deleteNode(nodeId, deleteTargetReferences); +} + +/*! + Adds the reference described by \a referenceToAdd to the server. + + Returns \c true if the asynchronous call has been successfully dispatched. + + The success of the operation is returned in the \l addReferenceFinished() signal. + + The following example code adds a reference to a node to the "Objects" folder: + + \code + QOpcUaAddReferenceItem item; + item.setSourceNodeId(QOpcUa::ns0ID(QOpcUa::NodeIds::NS0::ObjectsFolder)); + item.setReferenceTypeId(QOpcUa::nodeIdFromInteger(0, static_cast<quint32>(QOpcUa::ReferenceTypeId::Organizes))); + item.setIsForward(true); + item.setTargetNodeId(QOpcUa::QExpandedNodeId("ns=3;s=MyNewVariableNode")); + item.setTargetNodeClass(QOpcUa::NodeClass::Variable); + + m_client->addReference(item); + \endcode + + \sa deleteReference() addReferenceFinished() QOpcUaAddReferenceItem +*/ +bool QOpcUaClient::addReference(const QOpcUaAddReferenceItem &referenceToAdd) +{ + if (state() != QOpcUaClient::Connected) + return false; + + Q_D(QOpcUaClient); + return d->m_impl->addReference(referenceToAdd); +} + +/*! + Deletes the reference described by \a referenceToDelete from the server. + + Returns \c true if the asynchronous call has been successfully dispatched. + + The success of the operation is returned in the \l deleteReferenceFinished() signal. + + The following example code deletes a reference to a node from the "Objects" folder: + + \code + QOpcUaDeleteReferenceItem item; + item.setSourceNodeId(QOpcUa::ns0ID(QOpcUa::NodeIds::NS0::ObjectsFolder)); + item.setReferenceTypeId(QOpcUa::nodeIdFromInteger(0, static_cast<quint32>(QOpcUa::ReferenceTypeId::Organizes))); + item.setIsForward(true); + item.setTargetNodeId(QOpcUa::QExpandedNodeId("ns=3;s=MyNewVariableNode")); + item.setDeleteBidirectional(true); + + m_client->deleteReference(item); + \endcode + + \sa addReference() deleteReferenceFinished() QOpcUaDeleteReferenceItem +*/ +bool QOpcUaClient::deleteReference(const QOpcUaDeleteReferenceItem &referenceToDelete) +{ + if (state() != QOpcUaClient::Connected) + return false; + + Q_D(QOpcUaClient); + return d->m_impl->deleteReference(referenceToDelete); } /*! diff --git a/src/opcua/client/qopcuaclient.h b/src/opcua/client/qopcuaclient.h index 7aca93b..c764f7c 100644 --- a/src/opcua/client/qopcuaclient.h +++ b/src/opcua/client/qopcuaclient.h @@ -43,6 +43,9 @@ #include <QtOpcUa/qopcuareadresult.h> #include <QtOpcUa/qopcuawriteitem.h> #include <QtOpcUa/qopcuawriteresult.h> +#include <QtOpcUa/qopcuaaddnodeitem.h> +#include <QtOpcUa/qopcuaaddreferenceitem.h> +#include <QtOpcUa/qopcuadeletereferenceitem.h> #include <QtCore/qobject.h> #include <QtCore/qurl.h> @@ -98,6 +101,12 @@ public: bool batchRead(const QVector<QOpcUaReadItem> &nodesToRead); bool batchWrite(const QVector<QOpcUaWriteItem> &nodesToWrite); + bool addNode(const QOpcUaAddNodeItem &nodeToAdd); + bool deleteNode(const QString &nodeId, bool deleteTargetReferences = true); + + bool addReference(const QOpcUaAddReferenceItem &referenceToAdd); + bool deleteReference(const QOpcUaDeleteReferenceItem &referenceToDelete); + QUrl url() const; ClientState state() const; @@ -121,6 +130,12 @@ Q_SIGNALS: void findServersFinished(QVector<QOpcUa::QApplicationDescription> servers, QOpcUa::UaStatusCode statusCode); void batchReadFinished(QVector<QOpcUaReadResult> results, QOpcUa::UaStatusCode serviceResult); void batchWriteFinished(QVector<QOpcUaWriteResult> results, QOpcUa::UaStatusCode serviceResult); + void addNodeFinished(QOpcUa::QExpandedNodeId requestedNodeId, QString assignedNodeId, QOpcUa::UaStatusCode statusCode); + void deleteNodeFinished(QString nodeId, QOpcUa::UaStatusCode statusCode); + void addReferenceFinished(QString sourceNodeId, QString referenceTypeId, QOpcUa::QExpandedNodeId targetNodeId, bool isForward, + QOpcUa::UaStatusCode statusCode); + void deleteReferenceFinished(QString sourceNodeId, QString referenceTypeId, QOpcUa::QExpandedNodeId targetNodeId, bool isForward, + QOpcUa::UaStatusCode statusCode); private: Q_DISABLE_COPY(QOpcUaClient) diff --git a/src/opcua/client/qopcuaclientimpl.cpp b/src/opcua/client/qopcuaclientimpl.cpp index df83d40..3480c61 100644 --- a/src/opcua/client/qopcuaclientimpl.cpp +++ b/src/opcua/client/qopcuaclientimpl.cpp @@ -85,6 +85,10 @@ void QOpcUaClientImpl::connectBackendWithClient(QOpcUaBackend *backend) connect(backend, &QOpcUaBackend::findServersFinished, this, &QOpcUaClientImpl::findServersFinished); connect(backend, &QOpcUaBackend::batchReadFinished, this, &QOpcUaClientImpl::batchReadFinished); connect(backend, &QOpcUaBackend::batchWriteFinished, this, &QOpcUaClientImpl::batchWriteFinished); + connect(backend, &QOpcUaBackend::addNodeFinished, this, &QOpcUaClientImpl::addNodeFinished); + connect(backend, &QOpcUaBackend::deleteNodeFinished, this, &QOpcUaClientImpl::deleteNodeFinished); + connect(backend, &QOpcUaBackend::addReferenceFinished, this, &QOpcUaClientImpl::addReferenceFinished); + connect(backend, &QOpcUaBackend::deleteReferenceFinished, this, &QOpcUaClientImpl::deleteReferenceFinished); } void QOpcUaClientImpl::handleAttributesRead(quint64 handle, QVector<QOpcUaReadResult> attr, QOpcUa::UaStatusCode serviceResult) diff --git a/src/opcua/client/qopcuaclientimpl_p.h b/src/opcua/client/qopcuaclientimpl_p.h index 0b6b8da..76ab9eb 100644 --- a/src/opcua/client/qopcuaclientimpl_p.h +++ b/src/opcua/client/qopcuaclientimpl_p.h @@ -83,6 +83,12 @@ public: bool registerNode(QPointer<QOpcUaNodeImpl> obj); void unregisterNode(QPointer<QOpcUaNodeImpl> obj); + virtual bool addNode(const QOpcUaAddNodeItem &nodeToAdd) = 0; + virtual bool deleteNode(const QString &nodeId, bool deleteTargetReferences) = 0; + + virtual bool addReference(const QOpcUaAddReferenceItem &referenceToAdd) = 0; + virtual bool deleteReference(const QOpcUaDeleteReferenceItem &referenceToDelete) = 0; + void connectBackendWithClient(QOpcUaBackend *backend); QOpcUaClient *m_client; @@ -111,6 +117,12 @@ signals: void findServersFinished(QVector<QOpcUa::QApplicationDescription> servers, QOpcUa::UaStatusCode statusCode); void batchReadFinished(QVector<QOpcUaReadResult> results, QOpcUa::UaStatusCode serviceResult); void batchWriteFinished(QVector<QOpcUaWriteResult> results, QOpcUa::UaStatusCode serviceResult); + void addNodeFinished(QOpcUa::QExpandedNodeId requestedNodeId, QString assignedNodeId, QOpcUa::UaStatusCode statusCode); + void deleteNodeFinished(QString nodeId, QOpcUa::UaStatusCode statusCode); + void addReferenceFinished(QString sourceNodeId, QString referenceTypeId, QOpcUa::QExpandedNodeId targetNodeId, bool isForward, + QOpcUa::UaStatusCode statusCode); + void deleteReferenceFinished(QString sourceNodeId, QString referenceTypeId, QOpcUa::QExpandedNodeId targetNodeId, bool isForward, + QOpcUa::UaStatusCode statusCode); private: Q_DISABLE_COPY(QOpcUaClientImpl) diff --git a/src/opcua/client/qopcuaclientprivate.cpp b/src/opcua/client/qopcuaclientprivate.cpp index a186bf8..33d5285 100644 --- a/src/opcua/client/qopcuaclientprivate.cpp +++ b/src/opcua/client/qopcuaclientprivate.cpp @@ -81,6 +81,28 @@ QOpcUaClientPrivate::QOpcUaClientPrivate(QOpcUaClientImpl *impl) Q_Q(QOpcUaClient); emit q->batchWriteFinished(results, serviceResult); }); + + QObject::connect(m_impl.data(), &QOpcUaClientImpl::addNodeFinished, [this](const QOpcUa::QExpandedNodeId &requestedNodeId, const QString &assignedNodeId, QOpcUa::UaStatusCode statusCode) { + Q_Q(QOpcUaClient); + emit q->addNodeFinished(requestedNodeId, assignedNodeId, statusCode); + }); + + QObject::connect(m_impl.data(), &QOpcUaClientImpl::deleteNodeFinished, [this](const QString &nodeId, QOpcUa::UaStatusCode statusCode) { + Q_Q(QOpcUaClient); + emit q->deleteNodeFinished(nodeId, statusCode); + }); + + QObject::connect(m_impl.data(), &QOpcUaClientImpl::addReferenceFinished, [this](const QString &sourceNodeId, const QString &referenceTypeId, + const QOpcUa::QExpandedNodeId &targetNodeId, bool isForward, QOpcUa::UaStatusCode statusCode) { + Q_Q(QOpcUaClient); + emit q->addReferenceFinished(sourceNodeId, referenceTypeId, targetNodeId, isForward, statusCode); + }); + + QObject::connect(m_impl.data(), &QOpcUaClientImpl::deleteReferenceFinished, [this](const QString &sourceNodeId, const QString &referenceTypeId, + const QOpcUa::QExpandedNodeId &targetNodeId, bool isForward, QOpcUa::UaStatusCode statusCode) { + Q_Q(QOpcUaClient); + emit q->deleteReferenceFinished(sourceNodeId, referenceTypeId, targetNodeId, isForward, statusCode); + }); } QOpcUaClientPrivate::~QOpcUaClientPrivate() diff --git a/src/opcua/client/qopcuadeletereferenceitem.cpp b/src/opcua/client/qopcuadeletereferenceitem.cpp new file mode 100644 index 0000000..abfcaa0 --- /dev/null +++ b/src/opcua/client/qopcuadeletereferenceitem.cpp @@ -0,0 +1,169 @@ +/**************************************************************************** +** +** Copyright (C) 2018 basysKom GmbH, opensource@basyskom.com +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtOpcUa module of the Qt Toolkit. +** +** $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 "qopcuanodecreationattributes.h" +#include "qopcuadeletereferenceitem.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QOpcUaDeleteReferenceItem + \inmodule QtOpcUa + \brief This class stores the necessary information to delete a reference from the server. + + \sa QOpcUaClient::deleteReference() +*/ + +class QOpcUaDeleteReferenceItemData : public QSharedData +{ +public: + QString sourceNodeId; + QString referenceTypeId; + bool isForward {true}; + QOpcUa::QExpandedNodeId targetNodeId; + bool deleteBidirectional {true}; +}; + +QOpcUaDeleteReferenceItem::QOpcUaDeleteReferenceItem() + : data(new QOpcUaDeleteReferenceItemData) +{ +} + +/*! + Constructs a delete reference item from \a other. +*/ +QOpcUaDeleteReferenceItem::QOpcUaDeleteReferenceItem(const QOpcUaDeleteReferenceItem &other) + : data(other.data) +{ +} + +/*! + Sets the values from \a rhs in this delete reference item. +*/ +QOpcUaDeleteReferenceItem &QOpcUaDeleteReferenceItem::operator=(const QOpcUaDeleteReferenceItem &rhs) +{ + if (this != &rhs) + data.operator=(rhs.data); + return *this; +} + +QOpcUaDeleteReferenceItem::~QOpcUaDeleteReferenceItem() +{ +} + +/*! + Returns the deleteBidirectional Flag. +*/ +bool QOpcUaDeleteReferenceItem::deleteBidirectional() const +{ + return data->deleteBidirectional; +} + +/*! + Sets the deleteBidirectional flag to \a deleteBidirectional. + If this flag is false, only this reference will be deleted. + Else, the opposite reference from the target node is deleted too if accessible by the server. +*/ +void QOpcUaDeleteReferenceItem::setDeleteBidirectional(bool deleteBidirectional) +{ + data->deleteBidirectional = deleteBidirectional; +} + +/*! + Returns the target node id. +*/ +QOpcUa::QExpandedNodeId QOpcUaDeleteReferenceItem::targetNodeId() const +{ + return data->targetNodeId; +} + +/*! + Sets the node id of the target node to \a targetNodeId. +*/ +void QOpcUaDeleteReferenceItem::setTargetNodeId(const QOpcUa::QExpandedNodeId &targetNodeId) +{ + data->targetNodeId = targetNodeId; +} + +/*! + Returns the isForward flag. +*/ +bool QOpcUaDeleteReferenceItem::isForward() const +{ + return data->isForward; +} + +/*! + Sets the isForward flag to \a isForward. +*/ +void QOpcUaDeleteReferenceItem::setIsForward(bool isForward) +{ + data->isForward = isForward; +} + +/*! + Returns the reference type id. +*/ +QString QOpcUaDeleteReferenceItem::referenceTypeId() const +{ + return data->referenceTypeId; +} + +/*! + Sets the reference type id to \a referenceTypeId. +*/ +void QOpcUaDeleteReferenceItem::setReferenceTypeId(const QString &referenceTypeId) +{ + data->referenceTypeId = referenceTypeId; +} + +/*! + Returns the source node id. +*/ +QString QOpcUaDeleteReferenceItem::sourceNodeId() const +{ + return data->sourceNodeId; +} + +/*! + Sets the node id of the source node to \a sourceNodeId. +*/ +void QOpcUaDeleteReferenceItem::setSourceNodeId(const QString &sourceNodeId) +{ + data->sourceNodeId = sourceNodeId; +} + +QT_END_NAMESPACE diff --git a/src/opcua/client/qopcuadeletereferenceitem.h b/src/opcua/client/qopcuadeletereferenceitem.h new file mode 100644 index 0000000..7df305f --- /dev/null +++ b/src/opcua/client/qopcuadeletereferenceitem.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2018 basysKom GmbH, opensource@basyskom.com +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtOpcUa module of the Qt Toolkit. +** +** $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 QOPCUADELETEREFERENCEITEM_H +#define QOPCUADELETEREFERENCEITEM_H + +#include <QtOpcUa/qopcuanodecreationattributes.h> +#include <QtOpcUa/qopcuatype.h> + +QT_BEGIN_NAMESPACE + +class QOpcUaDeleteReferenceItemData; +class Q_OPCUA_EXPORT QOpcUaDeleteReferenceItem +{ +public: + QOpcUaDeleteReferenceItem(); + QOpcUaDeleteReferenceItem(const QOpcUaDeleteReferenceItem &other); + QOpcUaDeleteReferenceItem &operator=(const QOpcUaDeleteReferenceItem &rhs); + ~QOpcUaDeleteReferenceItem(); + + QString sourceNodeId() const; + void setSourceNodeId(const QString &sourceNodeId); + + QString referenceTypeId() const; + void setReferenceTypeId(const QString &referenceTypeId); + + bool isForward() const; + void setIsForward(bool isForward); + + QOpcUa::QExpandedNodeId targetNodeId() const; + void setTargetNodeId(const QOpcUa::QExpandedNodeId &targetNodeId); + + bool deleteBidirectional() const; + void setDeleteBidirectional(bool deleteBidirectional); + +private: + QSharedDataPointer<QOpcUaDeleteReferenceItemData> data; +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QOpcUaDeleteReferenceItem) + +#endif // QOPCUADELETEREFERENCEITEM_H diff --git a/src/opcua/client/qopcuanodecreationattributes.cpp b/src/opcua/client/qopcuanodecreationattributes.cpp new file mode 100644 index 0000000..b191611 --- /dev/null +++ b/src/opcua/client/qopcuanodecreationattributes.cpp @@ -0,0 +1,776 @@ +/**************************************************************************** +** +** Copyright (C) 2018 basysKom GmbH, opensource@basyskom.com +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtOpcUa module of the Qt Toolkit. +** +** $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 "qopcuanodecreationattributes.h" + +#include "qopcuanodecreationattributes_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QOpcUaNodeCreationAttributes + \inmodule QtOpcUa + \brief This class manages attribute values for node creation. + + This class holds values for node attributes that are passed to the server + when creating a new node in the OPC UA address space. + + The following node attributes are supported by the different node classes: + + \table + \header + \li Attribute + \li Object + \li Variable + \li Method + \li ObjectType + \li VariableType + \li ReferenceType + \li DataType + \li View + \row + \li AccessLevel + \li + \li X + \li + \li + \li + \li + \li + \li + \row + \li ArrayDimensions + \li + \li X + \li + \li + \li X + \li + \li + \li + \row + \li ContainsNoLoops + \li + \li + \li + \li + \li + \li + \li + \li X + \row + \li DataType + \li + \li X + \li + \li + \li X + \li + \li + \li + \row + \li Description + \li X + \li X + \li X + \li X + \li X + \li X + \li X + \li X + \row + \li DisplayName + \li X + \li X + \li X + \li X + \li X + \li X + \li X + \li X + \row + \li EventNotifier + \li X + \li + \li + \li + \li + \li + \li + \li + \row + \li Executable + \li + \li + \li X + \li + \li + \li + \li + \li + \row + \li Historizing + \li + \li X + \li + \li + \li + \li + \li + \li + \row + \li InverseName + \li + \li + \li + \li + \li + \li X + \li + \li + \row + \li IsAbstract + \li + \li + \li + \li X + \li X + \li X + \li X + \li + \row + \li MinimumSamplingInterval + \li + \li X + \li + \li + \li + \li + \li + \li + \row + \li Symmetric + \li + \li + \li + \li + \li + \li X + \li + \li + \row + \li UserAccessLevel + \li + \li X + \li + \li + \li + \li + \li + \li + \row + \li UserExecutable + \li + \li + \li X + \li + \li + \li + \li + \li + \row + \li UserWriteMask + \li X + \li X + \li X + \li X + \li X + \li X + \li X + \li X + \row + \li Value + \li + \li X + \li + \li + \li X + \li + \li + \li + \row + \li ValueRank + \li + \li X + \li + \li + \li X + \li + \li + \li + \row + \li WriteMask + \li X + \li X + \li X + \li X + \li X + \li X + \li X + \li X + \endtable + + \sa QOpcUaClient::addNode() +*/ + +QOpcUaNodeCreationAttributes::QOpcUaNodeCreationAttributes() + : data(new QOpcUaNodeCreationAttributesPrivate()) +{} + +/*! + Constructs a node creation attributes object with the values of \a other. +*/ +QOpcUaNodeCreationAttributes::QOpcUaNodeCreationAttributes(const QOpcUaNodeCreationAttributes &other) + : data(other.data) +{} + +/*! + Assigns the value of \a rhs to this node creation attributes object. +*/ +QOpcUaNodeCreationAttributes &QOpcUaNodeCreationAttributes::operator=(const QOpcUaNodeCreationAttributes &rhs) +{ + if (this != &rhs) + data = rhs.data; + return *this; +} + +QOpcUaNodeCreationAttributes::~QOpcUaNodeCreationAttributes() +{} + +/*! + Returns the bitmask containing information about set attributes. + For a mapping of bit positions to attributes, see OPC-UA part 4, table 145. +*/ +quint32 QOpcUaNodeCreationAttributes::mask() const +{ + return data->mask; +} + +/*! + Returns the value for the AccessLevel attribute. +*/ +QOpcUa::AccessLevel QOpcUaNodeCreationAttributes::accessLevel() const +{ + return data->accessLevel; +} + +/*! + Sets the value for the AccessLevel attribute to \a accessLevel. +*/ +void QOpcUaNodeCreationAttributes::setAccessLevel(QOpcUa::AccessLevel accessLevel) +{ + data->accessLevel = accessLevel; + data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::AccessLevel); +} + +/*! + Returns \c true if a value for the AccessLevel attribute is set. +*/ +bool QOpcUaNodeCreationAttributes::hasAccessLevel() const +{ + return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::AccessLevel); +} + +/*! + Returns the value for the ArrayDimensions attribute. +*/ +QVector<quint32> QOpcUaNodeCreationAttributes::arrayDimensions() const +{ + return data->arrayDimensions; +} + +/*! + Sets the value for the ArrayDimensions attribute to \a arrayDimensions. +*/ +void QOpcUaNodeCreationAttributes::setArrayDimensions(const QVector<quint32> &arrayDimensions) +{ + data->arrayDimensions = arrayDimensions; + data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::ArrayDimensions); +} + +/*! + Returns \c true if a value for the ArrayDimensions attribute is set. +*/ +bool QOpcUaNodeCreationAttributes::hasArrayDimensions() const +{ + return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::ArrayDimensions); +} + +/*! + Returns the value for the ContainsNoLoops attribute. +*/ +bool QOpcUaNodeCreationAttributes::containsNoLoops() const +{ + return data->containsNoLoops; +} + +/*! + Sets the value for the ContainsNoLoops attribute to \a containsNoLoops. +*/ +void QOpcUaNodeCreationAttributes::setContainsNoLoops(bool containsNoLoops) +{ + data->containsNoLoops = containsNoLoops; + data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::ContainsNoLoops); +} + +/*! + Returns \c true if a value for the ContainsNoLoops attribute is set. +*/ +bool QOpcUaNodeCreationAttributes::hasContainsNoLoops() const +{ + return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::ContainsNoLoops); +} + +/*! + Returns the value for the DataType attribute. +*/ +QString QOpcUaNodeCreationAttributes::dataTypeId() const +{ + return data->dataTypeId; +} + +/*! + Sets the value for the DataType attribute to \a dataTypeId. +*/ +void QOpcUaNodeCreationAttributes::setDataTypeId(const QString &dataTypeId) +{ + data->dataTypeId = dataTypeId; + data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::DataType); +} + +/*! + Returns \c true if a value for the DataType attribute is set. +*/ +bool QOpcUaNodeCreationAttributes::hasDataTypeId() const +{ + return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::DataType); +} + +/*! + Returns the value for the Description attribute. +*/ +QOpcUa::QLocalizedText QOpcUaNodeCreationAttributes::description() const +{ + return data->description; +} + +/*! + Sets the value for the Description attribute to \a description. +*/ +void QOpcUaNodeCreationAttributes::setDescription(const QOpcUa::QLocalizedText &description) +{ + data->description = description; + data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::Description); +} + +/*! + Returns \c true if a value for the Description attribute is set. +*/ +bool QOpcUaNodeCreationAttributes::hasDescription() const +{ + return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::Description); +} + +/*! + Returns the value for the DisplayName attribute. +*/ +QOpcUa::QLocalizedText QOpcUaNodeCreationAttributes::displayName() const +{ + return data->displayName; +} + +/*! + Sets the value for the DisplayName attribute to \a displayName. +*/ +void QOpcUaNodeCreationAttributes::setDisplayName(const QOpcUa::QLocalizedText &displayName) +{ + data->displayName = displayName; + data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::DisplayName); +} + +/*! + Returns \c true if a value for the DisplayName attribute is set. +*/ +bool QOpcUaNodeCreationAttributes::hasDisplayName() const +{ + return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::DisplayName); +} + +/*! + Returns the value for the EventNotifier attribute. +*/ +QOpcUa::EventNotifier QOpcUaNodeCreationAttributes::eventNotifier() const +{ + return data->eventNotifier; +} + +/*! + Sets the value for the EventNotifier attribute to \a eventNotifier. +*/ +void QOpcUaNodeCreationAttributes::setEventNotifier(QOpcUa::EventNotifier eventNotifier) +{ + data->eventNotifier = eventNotifier; + data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::EventNotifier); +} + +/*! + Returns \c true if a value for the EventNotifier attribute is set. +*/ +bool QOpcUaNodeCreationAttributes::hasEventNotifier() const +{ + return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::EventNotifier); +} + +/*! + Returns the value for the Executable attribute. +*/ +bool QOpcUaNodeCreationAttributes::executable() const +{ + return data->executable; +} + +/*! + Sets the value for the Executable attribute to \a executable. +*/ +void QOpcUaNodeCreationAttributes::setExecutable(bool executable) +{ + data->executable = executable; + data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::Executable); +} + +/*! + Returns \c true if a value for the Executable attribute is set. +*/ +bool QOpcUaNodeCreationAttributes::hasExecutable() const +{ + return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::Executable); +} + +/*! + Returns the value for the Historizing attribute. +*/ +bool QOpcUaNodeCreationAttributes::historizing() const +{ + return data->historizing; +} + +/*! + Sets the value for the Historizing attribute to \a historizing. +*/ +void QOpcUaNodeCreationAttributes::setHistorizing(bool historizing) +{ + data->historizing = historizing; + data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::Historizing); +} + +/*! + Returns \c true if a value for the Historizing attribute is set. +*/ +bool QOpcUaNodeCreationAttributes::hasHistorizing() const +{ + return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::Historizing); +} + +/*! + Returns the value for the InverseName attribute. +*/ +QOpcUa::QLocalizedText QOpcUaNodeCreationAttributes::inverseName() const +{ + return data->inverseName; +} + +/*! + Sets the value for the InverseName attribute to \a inverseName. +*/ +void QOpcUaNodeCreationAttributes::setInverseName(const QOpcUa::QLocalizedText &inverseName) +{ + data->inverseName = inverseName; + data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::InverseName); +} + +/*! + Returns \c true if a value for the InverseName attribute is set. +*/ +bool QOpcUaNodeCreationAttributes::hasInverseName() const +{ + return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::InverseName); +} + +/*! + Returns the value for the IsAbstract attribute. +*/ +bool QOpcUaNodeCreationAttributes::isAbstract() const +{ + return data->isAbstract; +} + +/*! + Sets the value for the IsAbstract attribute to \a isAbstract. +*/ +void QOpcUaNodeCreationAttributes::setIsAbstract(bool isAbstract) +{ + data->isAbstract = isAbstract; + data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::IsAbstract); +} + +/*! + Returns \c true if a value for the IsAbstract attribute is set. +*/ +bool QOpcUaNodeCreationAttributes::hasIsAbstract() const +{ + return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::IsAbstract); +} + +/*! + Returns the value for the MinimumSamplingInterval attribute. +*/ +double QOpcUaNodeCreationAttributes::minimumSamplingInterval() const +{ + return data->minimumSamplingInterval; +} + +/*! + Sets the value for the MinimumSamplingInterval attribute to \a minimumSamplingInterval. +*/ +void QOpcUaNodeCreationAttributes::setMinimumSamplingInterval(double minimumSamplingInterval) +{ + data->minimumSamplingInterval = minimumSamplingInterval; + data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::MinimumSamplingInterval); +} + +/*! + Returns \c true if a value for the MinimumSamplingInterval attribute is set. +*/ +bool QOpcUaNodeCreationAttributes::hasMinimumSamplingInterval() const +{ + return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::MinimumSamplingInterval); +} + +/*! + Returns the value for the Symmetric attribute. +*/ +bool QOpcUaNodeCreationAttributes::symmetric() const +{ + return data->symmetric; +} + +/*! + Sets the value for the Symmetric attribute to \a symmetric. +*/ +void QOpcUaNodeCreationAttributes::setSymmetric(bool symmetric) +{ + data->symmetric = symmetric; + data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::Symmetric); +} + +/*! + Returns \c true if a value for the Symmetric attribute is set. +*/ +bool QOpcUaNodeCreationAttributes::hasSymmetric() const +{ + return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::Symmetric); +} + +/*! + Returns the value for the UserAccessLevel attribute. +*/ +QOpcUa::AccessLevel QOpcUaNodeCreationAttributes::userAccessLevel() const +{ + return data->userAccessLevel; +} + +/*! + Sets the value for the UserAccessLevel attribute to \a userAccessLevel. +*/ +void QOpcUaNodeCreationAttributes::setUserAccessLevel(QOpcUa::AccessLevel userAccessLevel) +{ + data->userAccessLevel = userAccessLevel; + data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::UserAccessLevel); +} + +/*! + Returns \c true if a value for the UserAccessLevel attribute is set. +*/ +bool QOpcUaNodeCreationAttributes::hasUserAccessLevel() const +{ + return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::UserAccessLevel); +} + +/*! + Returns the value for the UserExecutable attribute. +*/ +bool QOpcUaNodeCreationAttributes::userExecutable() const +{ + return data->userExecutable; +} + +/*! + Sets the value for the UserExecutable attribute to \a userExecutable. +*/ +void QOpcUaNodeCreationAttributes::setUserExecutable(bool userExecutable) +{ + data->userExecutable = userExecutable; + data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::UserExecutable); +} + +/*! + Returns \c true if a value for the UserExecutable attribute is set. +*/ +bool QOpcUaNodeCreationAttributes::hasUserExecutable() const +{ + return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::UserExecutable); +} + +/*! + Returns the value for the UserWriteMask attribute. +*/ +QOpcUa::WriteMask QOpcUaNodeCreationAttributes::userWriteMask() const +{ + return data->userWriteMask; +} + +/*! + Sets the value for the UserWriteMask attribute to \a userWriteMask. +*/ +void QOpcUaNodeCreationAttributes::setUserWriteMask(QOpcUa::WriteMask userWriteMask) +{ + data->userWriteMask = userWriteMask; + data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::UserWriteMask); +} + +/*! + Returns \c true if a value for the UserWriteMask attribute is set. +*/ +bool QOpcUaNodeCreationAttributes::hasUserWriteMask() const +{ + return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::UserWriteMask); +} + +/*! + Returns the value for the ValueRank attribute. +*/ +qint32 QOpcUaNodeCreationAttributes::valueRank() const +{ + return data->valueRank; +} + +/*! + Sets the value for the ValueRank attribute to \a valueRank. +*/ +void QOpcUaNodeCreationAttributes::setValueRank(qint32 valueRank) +{ + data->valueRank = valueRank; + data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::ValueRank); +} + +/*! + Returns \c true if a value for the ValueRank attribute is set. +*/ +bool QOpcUaNodeCreationAttributes::hasValueRank() const +{ + return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::ValueRank); +} + +/*! + Returns the value for the WriteMask attribute. +*/ +QOpcUa::WriteMask QOpcUaNodeCreationAttributes::writeMask() const +{ + return data->writeMask; +} + +/*! + Sets the value for the WriteMask attribute to \a writeMask. +*/ +void QOpcUaNodeCreationAttributes::setWriteMask(QOpcUa::WriteMask writeMask) +{ + data->writeMask = writeMask; + data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::WriteMask); +} + +/*! + Returns \c true if a value for the WriteMask attribute is set. +*/ +bool QOpcUaNodeCreationAttributes::hasWriteMask() const +{ + return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::WriteMask); +} + +/*! + Returns the value for the Value attribute. +*/ +QVariant QOpcUaNodeCreationAttributes::value() const +{ + return data->value; +} + +/*! + Sets the value for the Value attribute to \a value of type \a type. +*/ +void QOpcUaNodeCreationAttributes::setValue(const QVariant &value, QOpcUa::Types type) +{ + data->value = value; + data->valueType = type; + data->setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask::Value); +} + +/*! + Returns \c true if a value for the Value attribute is set. +*/ +bool QOpcUaNodeCreationAttributes::hasValue() const +{ + return data->attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask::Value); +} + +/*! + Returns the type of the value attribute. +*/ +QOpcUa::Types QOpcUaNodeCreationAttributes::valueType() const +{ + return data->valueType; +} + +QT_END_NAMESPACE diff --git a/src/opcua/client/qopcuanodecreationattributes.h b/src/opcua/client/qopcuanodecreationattributes.h new file mode 100644 index 0000000..ad775ce --- /dev/null +++ b/src/opcua/client/qopcuanodecreationattributes.h @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2018 basysKom GmbH, opensource@basyskom.com +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtOpcUa module of the Qt Toolkit. +** +** $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 QOPCUANODECREATIONATTRIBUTES_H +#define QOPCUANODECREATIONATTRIBUTES_H + +#include <QtOpcUa/qopcuatype.h> + +#include <QtCore/qshareddata.h> + +QT_BEGIN_NAMESPACE + +class QOpcUaNodeCreationAttributesPrivate; + +class Q_OPCUA_EXPORT QOpcUaNodeCreationAttributes +{ +public: + QOpcUaNodeCreationAttributes(); + QOpcUaNodeCreationAttributes(const QOpcUaNodeCreationAttributes &other); + QOpcUaNodeCreationAttributes &operator=(const QOpcUaNodeCreationAttributes &rhs); + + ~QOpcUaNodeCreationAttributes(); + + // A bitmask containing all set values, see OPC-UA part 4, table 145 + quint32 mask() const; + + QOpcUa::AccessLevel accessLevel() const; + void setAccessLevel(QOpcUa::AccessLevel accessLevel); + bool hasAccessLevel() const; + + QVector<quint32> arrayDimensions() const; + void setArrayDimensions(const QVector<quint32> &arrayDimensions); + bool hasArrayDimensions() const; + + bool containsNoLoops() const; + void setContainsNoLoops(bool containsNoLoops); + bool hasContainsNoLoops() const; + + QString dataTypeId() const; + void setDataTypeId(const QString &dataTypeId); + bool hasDataTypeId() const; + + QOpcUa::QLocalizedText description() const; + void setDescription(const QOpcUa::QLocalizedText &description); + bool hasDescription() const; + + QOpcUa::QLocalizedText displayName() const; + void setDisplayName(const QOpcUa::QLocalizedText &displayName); + bool hasDisplayName() const; + + QOpcUa::EventNotifier eventNotifier() const; + void setEventNotifier(QOpcUa::EventNotifier eventNotifier); + bool hasEventNotifier() const; + + bool executable() const; + void setExecutable(bool executable); + bool hasExecutable() const; + + bool historizing() const; + void setHistorizing(bool historizing); + bool hasHistorizing() const; + + QOpcUa::QLocalizedText inverseName() const; + void setInverseName(const QOpcUa::QLocalizedText &inverseName); + bool hasInverseName() const; + + bool isAbstract() const; + void setIsAbstract(bool isAbstract); + bool hasIsAbstract() const; + + double minimumSamplingInterval() const; + void setMinimumSamplingInterval(double minimumSamplingInterval); + bool hasMinimumSamplingInterval() const; + + bool symmetric() const; + void setSymmetric(bool symmetric); + bool hasSymmetric() const; + + QOpcUa::AccessLevel userAccessLevel() const; + void setUserAccessLevel(QOpcUa::AccessLevel userAccessLevel); + bool hasUserAccessLevel() const; + + bool userExecutable() const; + void setUserExecutable(bool userExecutable); + bool hasUserExecutable() const; + + QOpcUa::WriteMask userWriteMask() const; + void setUserWriteMask(QOpcUa::WriteMask userWriteMask); + bool hasUserWriteMask() const; + + qint32 valueRank() const; + void setValueRank(qint32 valueRank); + bool hasValueRank() const; + + QOpcUa::WriteMask writeMask() const; + void setWriteMask(QOpcUa::WriteMask writeMask); + bool hasWriteMask() const; + + QVariant value() const; + void setValue(const QVariant &value, QOpcUa::Types type = QOpcUa::Types::Undefined); + bool hasValue() const; + + QOpcUa::Types valueType() const; + +private: + QSharedDataPointer<QOpcUaNodeCreationAttributesPrivate> data; +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QOpcUaNodeCreationAttributes) + +#endif // QOPCUANODECREATIONATTRIBUTES_H diff --git a/src/opcua/client/qopcuanodecreationattributes_p.h b/src/opcua/client/qopcuanodecreationattributes_p.h new file mode 100644 index 0000000..c33d3cf --- /dev/null +++ b/src/opcua/client/qopcuanodecreationattributes_p.h @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2018 basysKom GmbH, opensource@basyskom.com +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtOpcUa module of the Qt Toolkit. +** +** $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 QOPCUANODECREATIONATTRIBUTES_P_H +#define QOPCUANODECREATIONATTRIBUTES_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qopcuatype.h" + +#include <QSharedData> + +QT_BEGIN_NAMESPACE + +class QOpcUaNodeCreationAttributesPrivate : public QSharedData +{ +public: + QOpcUaNodeCreationAttributesPrivate() + : mask(0) + {} + + // Bit positions from OPC-UA part 4, table 145 + enum class BitMask : quint32 { + AccessLevel = 0, + ArrayDimensions = 1, + ContainsNoLoops = 3, + DataType = 4, + Description = 5, + DisplayName = 6, + EventNotifier = 7, + Executable = 8, + Historizing = 9, + InverseName = 10, + IsAbstract = 11, + MinimumSamplingInterval = 12, + Symmetric = 15, + UserAccessLevel = 16, + UserExecutable = 17, + UserWriteMask = 18, + ValueRank = 19, + WriteMask = 20, + Value = 21 + }; + + void setAttributeInMask(QOpcUaNodeCreationAttributesPrivate::BitMask attribute) + { + const quint32 position = static_cast<quint32>(attribute); + mask |= (1 << position); + } + + bool attributeSet(QOpcUaNodeCreationAttributesPrivate::BitMask attribute) const + { + const quint32 position = static_cast<quint32>(attribute); + return mask & (1 << position); + } + + quint32 mask {0}; + QOpcUa::AccessLevel accessLevel {QOpcUa::AccessLevelBit::None}; + QVector<quint32> arrayDimensions; + bool containsNoLoops {false}; + QString dataTypeId; + QOpcUa::QLocalizedText description; + QOpcUa::QLocalizedText displayName; + QOpcUa::EventNotifier eventNotifier {QOpcUa::EventNotifierBit::None}; + bool executable {false}; + bool historizing {false}; + QOpcUa::QLocalizedText inverseName; + bool isAbstract {false}; + double minimumSamplingInterval {0}; + bool symmetric {false}; + QOpcUa::AccessLevel userAccessLevel {QOpcUa::AccessLevelBit::None}; + bool userExecutable {false}; + QOpcUa::WriteMask userWriteMask {QOpcUa::WriteMaskBit::None}; + qint32 valueRank {0}; + QOpcUa::WriteMask writeMask {QOpcUa::WriteMaskBit::None}; + QVariant value; + QOpcUa::Types valueType {QOpcUa::Types::Undefined}; +}; + +QT_END_NAMESPACE + +#endif // QOPCUANODECREATIONATTRIBUTES_P_H diff --git a/src/opcua/client/qopcuatype.cpp b/src/opcua/client/qopcuatype.cpp index 96bd943..6e462df 100644 --- a/src/opcua/client/qopcuatype.cpp +++ b/src/opcua/client/qopcuatype.cpp @@ -137,6 +137,65 @@ QT_BEGIN_NAMESPACE */ /*! + \enum QOpcUa::WriteMaskBit + + This enum contains all possible bits for the WriteMask and UserWriteMask node attributes + defined in OPC-UA part 3, Tabe 3. + + \value None No attribute is writable. + \value AccessLevel The AccessLevel attribute is writable. + \value ArrayDimensions The ArrayDimensions attribute is writable. + \value BrowseName The BrowseName attribute is writable. + \value ContainsNoLoops The ContainsNoLoops attribute is writable. + \value DataType The DataType attribute is writable. + \value Description The Description attribute is writable. + \value DisplayName The DisplayName attribute is writable. + \value EventNotifier The EventNotifier attribute is writable. + \value Executable The Executable attribute is writable. + \value Historizing The Historizing attribute is writable. + \value InverseName The InverseName attribute is writable. + \value IsAbstract The IsAbstract attribute is writable. + \value MinimumSamplingInterval The MinimumSamplingInterval attribute is writable. + \value NodeClass The NodeClass attribute is writable. + \value NodeId The NodeId attribute is writable. + \value Symmetric The Symmetric attribute is writable. + \value UserAccessLevel The UserAccessLevel attribute is writable. + \value UserExecutable The UserExecutable attribute is writable. + \value UserWriteMask The UserWriteMask attribute is writable. + \value ValueRank The ValueRank attribute is writable. + \value WriteMask The WriteMask attribute is writable. + \value ValueForVariableType The Value attribute of a variable type is writable. +*/ + +/*! + \enum QOpcUa::AccessLevelBit + + This enum contains all possible bits for the AccessLevel and UserAccessLevel node attributes + defined in OPC-UA part 3, Table 8. + + \value None No read access to the Value attribute is permitted. + \value CurrentRead The current value can be read. + \value CurrentWrite The current value can be written. + \value HistoryRead The history of the value is readable. + \value HistoryWrite The history of the value is writable. + \value SemanticChange The property variable generates SemanticChangeEvents. + \value StatusWrite The status code of the value is writable. + \value TimestampWrite The SourceTimestamp is writable. +*/ + +/*! + \enum QOpcUa::EventNotifierBit + + This enum contains all possible bits for the EventNotifier node attribute + defined in OPC-UA part 3, Table 6. + + \value None The node can't be used to interact with events. + \value SubscribeToEvents A client can subscribe to events. + \value HistoryRead A client can read the event history. + \value HistoryWrite A client can write the event history. +*/ + +/*! \fn inline uint QOpcUa::qHash(const QOpcUa::NodeAttribute& attr) Returns a \l QHash key for \a attr. diff --git a/src/opcua/client/qopcuatype.h b/src/opcua/client/qopcuatype.h index bee0954..5390af5 100644 --- a/src/opcua/client/qopcuatype.h +++ b/src/opcua/client/qopcuatype.h @@ -98,6 +98,59 @@ enum class NodeAttribute { Q_ENUM_NS(NodeAttribute) Q_DECLARE_FLAGS(NodeAttributes, NodeAttribute) +// Defined in OPC-UA part 3, Table 8. +enum class WriteMaskBit : quint32 { + None = 0, + AccessLevel = (1 << 0), + ArrayDimensions = (1 << 1), + BrowseName = (1 << 2), + ContainsNoLoops = (1 << 3), + DataType = (1 << 4), + Description = (1 << 5), + DisplayName = (1 << 6), + EventNotifier = (1 << 7), + Executable = (1 << 8), + Historizing = (1 << 9), + InverseName = (1 << 10), + IsAbstract = (1 << 11), + MinimumSamplingInterval = (1 << 12), + NodeClass = (1 << 13), + NodeId = (1 << 14), + Symmetric = (1 << 15), + UserAccessLevel = (1 << 16), + UserExecutable = (1 << 17), + UserWriteMask = (1 << 18), + ValueRank = (1 << 19), + WriteMask = (1 << 20), + ValueForVariableType = (1 << 21), +}; +Q_ENUM_NS(WriteMaskBit) +Q_DECLARE_FLAGS(WriteMask, WriteMaskBit) + +// Defined in OPC-UA part 3, Table 8. +enum class AccessLevelBit : quint8 { + None = 0, + CurrentRead = (1 << 0), + CurrentWrite = (1 << 1), + HistoryRead = (1 << 2), + HistoryWrite = (1 << 3), + SemanticChange = (1 << 4), + StatusWrite = (1 << 5), + TimestampWrite = (1 << 6), +}; +Q_ENUM_NS(AccessLevelBit) +Q_DECLARE_FLAGS(AccessLevel, AccessLevelBit) + +// Defined in OPC-UA part 3, Table 6. +enum class EventNotifierBit : quint8 { + None = 0, + SubscribeToEvents = (1 << 0), + HistoryRead = (1 << 2), + HistoryWrite = (1 << 3) +}; +Q_ENUM_NS(EventNotifierBit) +Q_DECLARE_FLAGS(EventNotifier, EventNotifierBit) + inline uint qHash(const QOpcUa::NodeAttribute& attr) { return ::qHash(static_cast<uint>(attr)); @@ -1139,6 +1192,9 @@ Q_DECLARE_TYPEINFO(QOpcUa::ErrorCategory, Q_PRIMITIVE_TYPE); Q_DECLARE_TYPEINFO(QOpcUa::NodeClass, Q_PRIMITIVE_TYPE); Q_DECLARE_TYPEINFO(QOpcUa::NodeAttribute, Q_PRIMITIVE_TYPE); Q_DECLARE_OPERATORS_FOR_FLAGS(QOpcUa::NodeAttributes) +Q_DECLARE_OPERATORS_FOR_FLAGS(QOpcUa::WriteMask) +Q_DECLARE_OPERATORS_FOR_FLAGS(QOpcUa::AccessLevel) +Q_DECLARE_OPERATORS_FOR_FLAGS(QOpcUa::EventNotifier) Q_DECLARE_OPERATORS_FOR_FLAGS(QOpcUa::NodeClasses) Q_DECLARE_TYPEINFO(QOpcUa::ReferenceTypeId, Q_PRIMITIVE_TYPE); @@ -1153,6 +1209,12 @@ Q_DECLARE_METATYPE(QOpcUa::ErrorCategory) Q_DECLARE_METATYPE(QOpcUa::NodeClass) Q_DECLARE_METATYPE(QOpcUa::NodeAttribute) Q_DECLARE_METATYPE(QOpcUa::NodeAttributes) +Q_DECLARE_METATYPE(QOpcUa::WriteMaskBit) +Q_DECLARE_METATYPE(QOpcUa::WriteMask) +Q_DECLARE_METATYPE(QOpcUa::AccessLevelBit) +Q_DECLARE_METATYPE(QOpcUa::AccessLevel) +Q_DECLARE_METATYPE(QOpcUa::EventNotifierBit) +Q_DECLARE_METATYPE(QOpcUa::EventNotifier) Q_DECLARE_METATYPE(QOpcUa::ReferenceTypeId) Q_DECLARE_METATYPE(QOpcUa::NodeClasses) Q_DECLARE_METATYPE(QOpcUa::QRange) diff --git a/src/opcua/core/qopcuaprovider.cpp b/src/opcua/core/qopcuaprovider.cpp index 9f3c795..6e4df1a 100644 --- a/src/opcua/core/qopcuaprovider.cpp +++ b/src/opcua/core/qopcuaprovider.cpp @@ -165,6 +165,10 @@ QOpcUaProvider::QOpcUaProvider(QObject *parent) qRegisterMetaType<QOpcUaWriteResult>(); qRegisterMetaType<QVector<QOpcUaWriteItem>>(); qRegisterMetaType<QVector<QOpcUaWriteResult>>(); + qRegisterMetaType<QOpcUaNodeCreationAttributes>(); + qRegisterMetaType<QOpcUaAddNodeItem>(); + qRegisterMetaType<QOpcUaAddReferenceItem>(); + qRegisterMetaType<QOpcUaDeleteReferenceItem>(); } QOpcUaProvider::~QOpcUaProvider() diff --git a/src/opcua/doc/src/qtopcua.qdoc b/src/opcua/doc/src/qtopcua.qdoc index d0263fc..2801420 100644 --- a/src/opcua/doc/src/qtopcua.qdoc +++ b/src/opcua/doc/src/qtopcua.qdoc @@ -174,6 +174,9 @@ \li FindServers \li X \li + \li NodeManagement + \li X + \li \endtable \section1 Data types diff --git a/src/plugins/opcua/open62541/qopen62541backend.cpp b/src/plugins/opcua/open62541/qopen62541backend.cpp index 5e6a1ef..44a675e 100644 --- a/src/plugins/opcua/open62541/qopen62541backend.cpp +++ b/src/plugins/opcua/open62541/qopen62541backend.cpp @@ -558,6 +558,126 @@ void Open62541AsyncBackend::batchWrite(const QVector<QOpcUaWriteItem> &nodesToWr } } +void Open62541AsyncBackend::addNode(const QOpcUaAddNodeItem &nodeToAdd) +{ + UA_AddNodesRequest req; + UA_AddNodesRequest_init(&req); + UaDeleter<UA_AddNodesRequest> requestDeleter(&req, UA_AddNodesRequest_deleteMembers); + req.nodesToAddSize = 1; + req.nodesToAdd = UA_AddNodesItem_new(); + UA_AddNodesItem_init(req.nodesToAdd); + + QOpen62541ValueConverter::scalarFromQt<UA_ExpandedNodeId, QOpcUa::QExpandedNodeId>( + nodeToAdd.parentNodeId(), &req.nodesToAdd->parentNodeId); + + req.nodesToAdd->referenceTypeId = Open62541Utils::nodeIdFromQString(nodeToAdd.referenceTypeId()); + + QOpen62541ValueConverter::scalarFromQt<UA_ExpandedNodeId, QOpcUa::QExpandedNodeId>( + nodeToAdd.requestedNewNodeId(), &req.nodesToAdd->requestedNewNodeId); + + QOpen62541ValueConverter::scalarFromQt<UA_QualifiedName, QOpcUa::QQualifiedName>( + nodeToAdd.browseName(), &req.nodesToAdd->browseName); + + req.nodesToAdd->nodeClass = static_cast<UA_NodeClass>(nodeToAdd.nodeClass()); + + req.nodesToAdd->nodeAttributes = assembleNodeAttributes(nodeToAdd.nodeAttributes(), + nodeToAdd.nodeClass()); + + if (!nodeToAdd.typeDefinition().nodeId().isEmpty()) + QOpen62541ValueConverter::scalarFromQt<UA_ExpandedNodeId, QOpcUa::QExpandedNodeId>( + nodeToAdd.typeDefinition(), &req.nodesToAdd->typeDefinition); + + UA_AddNodesResponse res = UA_Client_Service_addNodes(m_uaclient, req); + UaDeleter<UA_AddNodesResponse> responseDeleter(&res, UA_AddNodesResponse_deleteMembers); + + QOpcUa::UaStatusCode status = QOpcUa::UaStatusCode::Good; + QString resultId; + if (res.responseHeader.serviceResult == UA_STATUSCODE_GOOD) { + if (res.results[0].statusCode == UA_STATUSCODE_GOOD) + resultId = Open62541Utils::nodeIdToQString(res.results[0].addedNodeId); + else { + status = static_cast<QOpcUa::UaStatusCode>(res.results[0].statusCode); + qCDebug(QT_OPCUA_PLUGINS_OPEN62541) << "Failed to add node:" << status; + } + } else { + status = static_cast<QOpcUa::UaStatusCode>(res.responseHeader.serviceResult); + qCDebug(QT_OPCUA_PLUGINS_OPEN62541) << "Failed to add node:" << status; + } + + emit addNodeFinished(nodeToAdd.requestedNewNodeId(), resultId, status); +} + +void Open62541AsyncBackend::deleteNode(const QString &nodeId, bool deleteTargetReferences) +{ + UA_NodeId id = Open62541Utils::nodeIdFromQString(nodeId); + UaDeleter<UA_NodeId> nodeIdDeleter(&id, UA_NodeId_deleteMembers); + + UA_StatusCode res = UA_Client_deleteNode(m_uaclient, id, deleteTargetReferences); + + QOpcUa::UaStatusCode resultStatus = static_cast<QOpcUa::UaStatusCode>(res); + + if (resultStatus != QOpcUa::UaStatusCode::Good) { + qCDebug(QT_OPCUA_PLUGINS_OPEN62541) << "Failed to delete node" << nodeId << "with status code" << resultStatus; + } + + emit deleteNodeFinished(nodeId, resultStatus); +} + +void Open62541AsyncBackend::addReference(const QOpcUaAddReferenceItem &referenceToAdd) +{ + UA_ExpandedNodeId target; + UA_ExpandedNodeId_init(&target); + UaDeleter<UA_ExpandedNodeId> nodeIdDeleter(&target, UA_ExpandedNodeId_deleteMembers); + + QOpen62541ValueConverter::scalarFromQt<UA_ExpandedNodeId, QOpcUa::QExpandedNodeId>( + referenceToAdd.targetNodeId(), &target); + + UA_String serverUri; + UaDeleter<UA_String> serverUriDeleter(&serverUri, UA_String_deleteMembers); + QOpen62541ValueConverter::scalarFromQt<UA_String, QString>( + referenceToAdd.targetServerUri(), &serverUri); + + UA_NodeClass nodeClass = static_cast<UA_NodeClass>(referenceToAdd.targetNodeClass()); + + UA_StatusCode res = UA_Client_addReference(m_uaclient, + Open62541Utils::nodeIdFromQString(referenceToAdd.sourceNodeId()), + Open62541Utils::nodeIdFromQString(referenceToAdd.referenceTypeId()), + referenceToAdd.isForward(), serverUri, target, nodeClass); + + QOpcUa::UaStatusCode statusCode = static_cast<QOpcUa::UaStatusCode>(res); + if (res != UA_STATUSCODE_GOOD) + qCDebug(QT_OPCUA_PLUGINS_OPEN62541) << "Failed to add reference from" << referenceToAdd.sourceNodeId() << "to" + << referenceToAdd.targetNodeId().nodeId() << ":" << statusCode; + + emit addReferenceFinished(referenceToAdd.sourceNodeId(), referenceToAdd.referenceTypeId(), + referenceToAdd.targetNodeId(), + referenceToAdd.isForward(), statusCode); +} + +void Open62541AsyncBackend::deleteReference(const QOpcUaDeleteReferenceItem &referenceToDelete) +{ + UA_ExpandedNodeId target; + UA_ExpandedNodeId_init(&target); + UaDeleter<UA_ExpandedNodeId> targetDeleter(&target, UA_ExpandedNodeId_deleteMembers); + QOpen62541ValueConverter::scalarFromQt<UA_ExpandedNodeId, QOpcUa::QExpandedNodeId>( + referenceToDelete.targetNodeId(), &target); + + UA_StatusCode res = UA_Client_deleteReference(m_uaclient, + Open62541Utils::nodeIdFromQString(referenceToDelete.sourceNodeId()), + Open62541Utils::nodeIdFromQString(referenceToDelete.referenceTypeId()), + referenceToDelete.isForward(), + target, referenceToDelete.deleteBidirectional()); + + QOpcUa::UaStatusCode statusCode = static_cast<QOpcUa::UaStatusCode>(res); + if (res != UA_STATUSCODE_GOOD) + qCDebug(QT_OPCUA_PLUGINS_OPEN62541) << "Failed to delete reference from" << referenceToDelete.sourceNodeId() << "to" + << referenceToDelete.targetNodeId().nodeId() << ":" << statusCode; + + emit deleteReferenceFinished(referenceToDelete.sourceNodeId(), referenceToDelete.referenceTypeId(), + referenceToDelete.targetNodeId(), + referenceToDelete.isForward(), statusCode); +} + static void convertBrowseResult(UA_BrowseResult *src, quint32 referencesSize, QVector<QOpcUaReferenceDescription> &dst) { if (!src) @@ -834,4 +954,161 @@ void Open62541AsyncBackend::cleanupSubscriptions() m_minPublishingInterval = 0; } +UA_ExtensionObject Open62541AsyncBackend::assembleNodeAttributes(const QOpcUaNodeCreationAttributes &nodeAttributes, + QOpcUa::NodeClass nodeClass) +{ + UA_ExtensionObject obj; + UA_ExtensionObject_init(&obj); + obj.encoding = UA_EXTENSIONOBJECT_DECODED; + + switch (nodeClass) { + case QOpcUa::NodeClass::Object: { + UA_ObjectAttributes *attr = UA_ObjectAttributes_new(); + *attr = UA_ObjectAttributes_default; + obj.content.decoded.data = attr; + obj.content.decoded.type = &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES]; + + if (nodeAttributes.hasEventNotifier()) + attr->eventNotifier = nodeAttributes.eventNotifier(); + break; + } + case QOpcUa::NodeClass::Variable: { + UA_VariableAttributes *attr = UA_VariableAttributes_new(); + *attr = UA_VariableAttributes_default; + obj.content.decoded.data = attr; + obj.content.decoded.type = &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES]; + + if (nodeAttributes.hasValue()) + attr->value = QOpen62541ValueConverter::toOpen62541Variant(nodeAttributes.value(), + nodeAttributes.valueType()); + if (nodeAttributes.hasDataTypeId()) + attr->dataType = Open62541Utils::nodeIdFromQString(nodeAttributes.dataTypeId()); + if (nodeAttributes.hasValueRank()) + attr->valueRank = nodeAttributes.valueRank(); + if (nodeAttributes.hasArrayDimensions()) + attr->arrayDimensions = copyArrayDimensions(nodeAttributes.arrayDimensions(), &attr->arrayDimensionsSize); + if (nodeAttributes.hasAccessLevel()) + attr->accessLevel = nodeAttributes.accessLevel(); + if (nodeAttributes.hasUserAccessLevel()) + attr->userAccessLevel = nodeAttributes.userAccessLevel(); + if (nodeAttributes.hasMinimumSamplingInterval()) + attr->minimumSamplingInterval = nodeAttributes.minimumSamplingInterval(); + if (nodeAttributes.hasHistorizing()) + attr->historizing = nodeAttributes.historizing(); + break; + } + case QOpcUa::NodeClass::Method: { + UA_MethodAttributes *attr = UA_MethodAttributes_new(); + *attr = UA_MethodAttributes_default; + obj.content.decoded.data = attr; + obj.content.decoded.type = &UA_TYPES[UA_TYPES_METHODATTRIBUTES]; + + if (nodeAttributes.hasExecutable()) + attr->executable = nodeAttributes.executable(); + if (nodeAttributes.hasUserExecutable()) + attr->userExecutable = nodeAttributes.userExecutable(); + break; + } + case QOpcUa::NodeClass::ObjectType: { + UA_ObjectTypeAttributes *attr = UA_ObjectTypeAttributes_new(); + *attr = UA_ObjectTypeAttributes_default; + obj.content.decoded.data = attr; + obj.content.decoded.type = &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES]; + + if (nodeAttributes.hasIsAbstract()) + attr->isAbstract = nodeAttributes.isAbstract(); + break; + } + case QOpcUa::NodeClass::VariableType: { + UA_VariableTypeAttributes *attr = UA_VariableTypeAttributes_new(); + *attr = UA_VariableTypeAttributes_default; + obj.content.decoded.data = attr; + obj.content.decoded.type = &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES]; + + if (nodeAttributes.hasValue()) + attr->value = QOpen62541ValueConverter::toOpen62541Variant(nodeAttributes.value(), + nodeAttributes.valueType()); + if (nodeAttributes.hasDataTypeId()) + attr->dataType = Open62541Utils::nodeIdFromQString(nodeAttributes.dataTypeId()); + if (nodeAttributes.hasValueRank()) + attr->valueRank = nodeAttributes.valueRank(); + if (nodeAttributes.hasArrayDimensions()) + attr->arrayDimensions = copyArrayDimensions(nodeAttributes.arrayDimensions(), &attr->arrayDimensionsSize); + if (nodeAttributes.hasIsAbstract()) + attr->isAbstract = nodeAttributes.isAbstract(); + break; + } + case QOpcUa::NodeClass::ReferenceType: { + UA_ReferenceTypeAttributes *attr = UA_ReferenceTypeAttributes_new(); + *attr = UA_ReferenceTypeAttributes_default; + obj.content.decoded.data = attr; + obj.content.decoded.type = &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES]; + + if (nodeAttributes.hasIsAbstract()) + attr->isAbstract = nodeAttributes.isAbstract(); + if (nodeAttributes.hasSymmetric()) + attr->symmetric = nodeAttributes.symmetric(); + if (nodeAttributes.hasInverseName()) + QOpen62541ValueConverter::scalarFromQt<UA_LocalizedText, QOpcUa::QLocalizedText>( + nodeAttributes.inverseName(), &attr->inverseName); + break; + } + case QOpcUa::NodeClass::DataType: { + UA_DataTypeAttributes *attr = UA_DataTypeAttributes_new(); + *attr = UA_DataTypeAttributes_default; + obj.content.decoded.data = attr; + obj.content.decoded.type = &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES]; + + if (nodeAttributes.hasIsAbstract()) + attr->isAbstract = nodeAttributes.isAbstract(); + break; + } + case QOpcUa::NodeClass::View: { + UA_ViewAttributes *attr = UA_ViewAttributes_new(); + *attr = UA_ViewAttributes_default; + obj.content.decoded.data = attr; + obj.content.decoded.type = &UA_TYPES[UA_TYPES_VIEWATTRIBUTES]; + + if (nodeAttributes.hasContainsNoLoops()) + attr->containsNoLoops = nodeAttributes.containsNoLoops(); + if (nodeAttributes.hasEventNotifier()) + attr->eventNotifier = nodeAttributes.eventNotifier(); + break; + } + default: + qCDebug(QT_OPCUA_PLUGINS_OPEN62541) << "Could not convert node attributes, unknown node class"; + UA_ExtensionObject_init(&obj); + return obj; + } + + UA_ObjectAttributes *attr = reinterpret_cast<UA_ObjectAttributes *>(obj.content.decoded.data); + attr->specifiedAttributes = nodeAttributes.mask(); + if (nodeAttributes.hasDisplayName()) + QOpen62541ValueConverter::scalarFromQt<UA_LocalizedText, QOpcUa::QLocalizedText>( + nodeAttributes.displayName(), &attr->displayName); + if (nodeAttributes.hasDescription()) + QOpen62541ValueConverter::scalarFromQt<UA_LocalizedText, QOpcUa::QLocalizedText>( + nodeAttributes.description(), &attr->description); + if (nodeAttributes.hasWriteMask()) + attr->writeMask = nodeAttributes.writeMask(); + if (nodeAttributes.hasUserWriteMask()) + attr->userWriteMask = nodeAttributes.userWriteMask(); + + return obj; +} + +UA_UInt32 *Open62541AsyncBackend::copyArrayDimensions(const QVector<quint32> &arrayDimensions, size_t *outputSize) +{ + if (outputSize) + *outputSize = arrayDimensions.size(); + + if (!outputSize) + return nullptr; + + UA_UInt32 *data = nullptr; + UA_StatusCode res = UA_Array_copy(arrayDimensions.constData(), arrayDimensions.size(), + reinterpret_cast<void **>(&data), &UA_TYPES[UA_TYPES_UINT32]); + return res == UA_STATUSCODE_GOOD ? data : nullptr; +} + QT_END_NAMESPACE diff --git a/src/plugins/opcua/open62541/qopen62541backend.h b/src/plugins/opcua/open62541/qopen62541backend.h index 44b549f..622f91d 100644 --- a/src/plugins/opcua/open62541/qopen62541backend.h +++ b/src/plugins/opcua/open62541/qopen62541backend.h @@ -72,6 +72,12 @@ public Q_SLOTS: void batchRead(const QVector<QOpcUaReadItem> &nodesToRead); void batchWrite(const QVector<QOpcUaWriteItem> &nodesToWrite); + // Node management + void addNode(const QOpcUaAddNodeItem &nodeToAdd); + void deleteNode(const QString &nodeId, bool deleteTargetReferences); + void addReference(const QOpcUaAddReferenceItem &referenceToAdd); + void deleteReference(const QOpcUaDeleteReferenceItem &referenceToDelete); + // Subscription QOpen62541Subscription *getSubscription(const QOpcUaMonitoringParameters &settings); bool removeSubscription(UA_UInt32 subscriptionId); @@ -89,6 +95,9 @@ private: QOpen62541Subscription *getSubscriptionForItem(quint64 handle, QOpcUa::NodeAttribute attr); QOpcUa::QApplicationDescription convertApplicationDescription(UA_ApplicationDescription &desc); + UA_ExtensionObject assembleNodeAttributes(const QOpcUaNodeCreationAttributes &nodeAttributes, QOpcUa::NodeClass nodeClass); + UA_UInt32 *copyArrayDimensions(const QVector<quint32> &arrayDimensions, size_t *outputSize); + QTimer m_subscriptionTimer; QHash<quint32, QOpen62541Subscription *> m_subscriptions; diff --git a/src/plugins/opcua/open62541/qopen62541client.cpp b/src/plugins/opcua/open62541/qopen62541client.cpp index 841c841..370bcee 100644 --- a/src/plugins/opcua/open62541/qopen62541client.cpp +++ b/src/plugins/opcua/open62541/qopen62541client.cpp @@ -124,4 +124,29 @@ bool QOpen62541Client::batchWrite(const QVector<QOpcUaWriteItem> &nodesToWrite) Q_ARG(QVector<QOpcUaWriteItem>, nodesToWrite)); } +bool QOpen62541Client::addNode(const QOpcUaAddNodeItem &nodeToAdd) +{ + return QMetaObject::invokeMethod(m_backend, "addNode", Qt::QueuedConnection, + Q_ARG(QOpcUaAddNodeItem, nodeToAdd)); +} + +bool QOpen62541Client::deleteNode(const QString &nodeId, bool deleteTargetReferences) +{ + return QMetaObject::invokeMethod(m_backend, "deleteNode", Qt::QueuedConnection, + Q_ARG(QString, nodeId), + Q_ARG(bool, deleteTargetReferences)); +} + +bool QOpen62541Client::addReference(const QOpcUaAddReferenceItem &referenceToAdd) +{ + return QMetaObject::invokeMethod(m_backend, "addReference", Qt::QueuedConnection, + Q_ARG(QOpcUaAddReferenceItem, referenceToAdd)); +} + +bool QOpen62541Client::deleteReference(const QOpcUaDeleteReferenceItem &referenceToDelete) +{ + return QMetaObject::invokeMethod(m_backend, "deleteReference", Qt::QueuedConnection, + Q_ARG(QOpcUaDeleteReferenceItem, referenceToDelete)); +} + QT_END_NAMESPACE diff --git a/src/plugins/opcua/open62541/qopen62541client.h b/src/plugins/opcua/open62541/qopen62541client.h index 84e8e1a..466b60a 100644 --- a/src/plugins/opcua/open62541/qopen62541client.h +++ b/src/plugins/opcua/open62541/qopen62541client.h @@ -68,6 +68,12 @@ public: bool batchRead(const QVector<QOpcUaReadItem> &nodesToRead) override; bool batchWrite(const QVector<QOpcUaWriteItem> &nodesToWrite) override; + bool addNode(const QOpcUaAddNodeItem &nodeToAdd) override; + bool deleteNode(const QString &nodeId, bool deleteTargetReferences) override; + + bool addReference(const QOpcUaAddReferenceItem &referenceToAdd) override; + bool deleteReference(const QOpcUaDeleteReferenceItem &referenceToDelete) override; + private slots: private: diff --git a/src/plugins/opcua/uacpp/quacppclient.cpp b/src/plugins/opcua/uacpp/quacppclient.cpp index 28c52c3..815f741 100644 --- a/src/plugins/opcua/uacpp/quacppclient.cpp +++ b/src/plugins/opcua/uacpp/quacppclient.cpp @@ -115,4 +115,37 @@ bool QUACppClient::batchWrite(const QVector<QOpcUaWriteItem> &nodesToWrite) return false; } +bool QUACppClient::addNode(const QOpcUaAddNodeItem &nodeToAdd) +{ + Q_UNUSED(nodeToAdd); + + qCInfo(QT_OPCUA_PLUGINS_UACPP) << "AddNode is not yet supported by the uacpp backend"; + return false; +} + +bool QUACppClient::deleteNode(const QString &nodeId, bool deleteTargetReferences) +{ + Q_UNUSED(nodeId); + Q_UNUSED(deleteTargetReferences); + + qCInfo(QT_OPCUA_PLUGINS_UACPP) << "DeleteNode is not yet supported by the uacpp backend"; + return false; +} + +bool QUACppClient::addReference(const QOpcUaAddReferenceItem &referenceToAdd) +{ + Q_UNUSED(referenceToAdd); + + qCInfo(QT_OPCUA_PLUGINS_UACPP) << "AddReference is not yet supported by the uacpp backend"; + return false; +} + +bool QUACppClient::deleteReference(const QOpcUaDeleteReferenceItem &referenceToDelete) +{ + Q_UNUSED(referenceToDelete); + + qCDebug(QT_OPCUA_PLUGINS_UACPP) << "deleteReference is not yet supported by the uacpp backend"; + return false; +} + QT_END_NAMESPACE diff --git a/src/plugins/opcua/uacpp/quacppclient.h b/src/plugins/opcua/uacpp/quacppclient.h index 4efbadb..af16cd2 100644 --- a/src/plugins/opcua/uacpp/quacppclient.h +++ b/src/plugins/opcua/uacpp/quacppclient.h @@ -52,6 +52,12 @@ public: bool batchRead(const QVector<QOpcUaReadItem> &nodesToRead) override; bool batchWrite(const QVector<QOpcUaWriteItem> &nodesToWrite) override; + bool addNode(const QOpcUaAddNodeItem &nodeToAdd) override; + bool deleteNode(const QString &nodeId, bool deleteTargetReferences) override; + + bool addReference(const QOpcUaAddReferenceItem &referenceToAdd) override; + bool deleteReference(const QOpcUaDeleteReferenceItem &referenceToDelete) override; + private: friend class QUACppNode; QThread *m_thread; |