aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThomas Vanbesien <tvanbesi@proton.me>2026-02-23 17:35:34 +0100
committerThomas Vanbesien <tvanbesi@proton.me>2026-02-23 17:35:34 +0100
commit4ac860baa81f30e3e1fc9aaa42a3f0bb0537543a (patch)
tree3ba02ef1943b0a6fcba49d8066b28c629f2a47a9 /src
parentdea81e8c330d75eaaa96e7f1915a9824ca23b15d (diff)
downloadBobinkQtOpcUa-4ac860baa81f30e3e1fc9aaa42a3f0bb0537543a.tar.gz
BobinkQtOpcUa-4ac860baa81f30e3e1fc9aaa42a3f0bb0537543a.zip
Add writeValueAtRange for index-range array writes
Diffstat (limited to 'src')
-rw-r--r--src/OpcUaMonitoredNode.cpp67
-rw-r--r--src/OpcUaMonitoredNode.h13
2 files changed, 80 insertions, 0 deletions
diff --git a/src/OpcUaMonitoredNode.cpp b/src/OpcUaMonitoredNode.cpp
index cd93730..922ad43 100644
--- a/src/OpcUaMonitoredNode.cpp
+++ b/src/OpcUaMonitoredNode.cpp
@@ -177,6 +177,7 @@ OpcUaMonitoredNode::teardownNode ()
emit infoChanged ();
m_valueType = QOpcUa::Types::Undefined;
+ m_pendingRangeWrite = false;
if (m_writable)
{
@@ -270,6 +271,9 @@ OpcUaMonitoredNode::handleAttributeUpdated (QOpcUa::NodeAttribute attr,
void
OpcUaMonitoredNode::handleValueUpdated (const QVariant &value)
{
+ if (m_pendingRangeWrite)
+ return;
+
m_value = value;
emit valueChanged ();
@@ -306,6 +310,8 @@ OpcUaMonitoredNode::handleAttributeWritten (QOpcUa::NodeAttribute attr,
if (attr != QOpcUa::NodeAttribute::Value)
return;
+ m_pendingRangeWrite = false;
+
bool ok = (statusCode == QOpcUa::Good);
emit writeCompleted (ok, ok ? QStringLiteral ("Write successful")
: QOpcUa::statusToString (statusCode));
@@ -511,3 +517,64 @@ OpcUaMonitoredNode::writeValue (const QVariant &value)
emit writeCompleted (false,
QStringLiteral ("Write request failed to dispatch"));
}
+
+void
+OpcUaMonitoredNode::writeValueAtRange (const QVariant &value,
+ const QString &indexRange)
+{
+ if (!m_node)
+ {
+ emit writeCompleted (false, QStringLiteral ("Node not connected"));
+ return;
+ }
+ if (!m_writable)
+ {
+ emit writeCompleted (false, QStringLiteral ("Node is read-only"));
+ return;
+ }
+ if (m_valueType == QOpcUa::Types::Undefined)
+ {
+ emit writeCompleted (false,
+ QStringLiteral ("Data type not yet resolved"));
+ return;
+ }
+ if (indexRange.isEmpty ())
+ {
+ emit writeCompleted (false, QStringLiteral ("Index range is empty"));
+ return;
+ }
+
+ QVariant toWrite = value;
+
+ // If the input is a comma-separated string, split into a list so
+ // coerceValue can handle each element (e.g. "10, 20" for range "0:1").
+ if (value.metaType ().id () == QMetaType::QString
+ && value.toString ().contains (QLatin1Char (',')))
+ {
+ QStringList parts
+ = value.toString ().split (QLatin1Char (','), Qt::SkipEmptyParts);
+ QVariantList list;
+ list.reserve (parts.size ());
+ for (const QString &part : parts)
+ list.append (QVariant (part.trimmed ()));
+ toWrite = QVariant::fromValue (list);
+ }
+
+ QVariant coerced = coerceValue (toWrite);
+ if (!coerced.isValid ())
+ {
+ emit writeCompleted (
+ false, QStringLiteral ("Cannot convert value to node data type"));
+ return;
+ }
+
+ m_pendingRangeWrite = true;
+
+ if (!m_node->writeAttributeRange (QOpcUa::NodeAttribute::Value, coerced,
+ indexRange, m_valueType))
+ {
+ m_pendingRangeWrite = false;
+ emit writeCompleted (
+ false, QStringLiteral ("Write range request failed to dispatch"));
+ }
+}
diff --git a/src/OpcUaMonitoredNode.h b/src/OpcUaMonitoredNode.h
index 2e86b2c..2ecffb7 100644
--- a/src/OpcUaMonitoredNode.h
+++ b/src/OpcUaMonitoredNode.h
@@ -88,6 +88,18 @@ public:
*/
Q_INVOKABLE void writeValue (const QVariant &value);
+ /**
+ * @brief Write a value to a specific index range of an array node.
+ *
+ * @a indexRange uses OPC UA syntax: "0" for first element,
+ * "0:3" for elements 0–3, "0,1" for 2D indexing.
+ * For multi-element writes, @a value can be a comma-separated
+ * string or a QVariantList.
+ * Result is reported asynchronously via writeCompleted().
+ */
+ Q_INVOKABLE void writeValueAtRange (const QVariant &value,
+ const QString &indexRange);
+
void classBegin () override;
void componentComplete () override;
@@ -129,6 +141,7 @@ private:
bool m_writable = false;
QVariant m_value;
OpcUaNodeInfo m_info;
+ bool m_pendingRangeWrite = false;
};
#endif // OPCUAMONITOREDNODE_H