From 690db0fa630ac57d0ec99010862c7b7e4a7ac589 Mon Sep 17 00:00:00 2001 From: Thomas Vanbesien Date: Fri, 20 Feb 2026 12:16:50 +0100 Subject: Implement OpcUaMonitoredNode attribute reading with OpcUaNodeInfo gadget --- demo/NodePage.qml | 138 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 125 insertions(+), 13 deletions(-) (limited to 'demo/NodePage.qml') diff --git a/demo/NodePage.qml b/demo/NodePage.qml index e00f468..2de0a15 100644 --- a/demo/NodePage.qml +++ b/demo/NodePage.qml @@ -1,4 +1,4 @@ -// NodePage.qml — Demo page with OpcUaMonitoredNode lifecycle logging. +// NodePage.qml — Demo page displaying a single OPC UA node. import QtQuick import QtQuick.Controls @@ -14,17 +14,16 @@ Page { OpcUaMonitoredNode { id: demoNode - nodeId: "ns=2;s=DemoVariable.Page" + nodePage.pageNumber + nodeId: nodePage.pageNumber === 1 ? "ns=1;s=double_rw_scalar" : "ns=1;s=string_rw_scalar" monitored: nodePage.StackView.status === StackView.Active - onMonitoredChanged: nodePage.logFunction( - "Page " + nodePage.pageNumber + " node [" + nodeId + "] " - + (monitored ? "MONITORED" : "UNMONITORED")) + onMonitoredChanged: nodePage.logFunction("Page " + nodePage.pageNumber + " node [" + nodeId + "] " + (monitored ? "MONITORED" : "UNMONITORED")) + onValueChanged: nodePage.logFunction("Page " + nodePage.pageNumber + " value = " + value) } ColumnLayout { anchors.fill: parent anchors.margins: 20 - spacing: 12 + spacing: 8 RowLayout { Label { @@ -32,22 +31,135 @@ Page { font.bold: true font.pointSize: 14 } - Item { Layout.fillWidth: true } + Item { + Layout.fillWidth: true + } Button { text: "Disconnect" onClicked: Bobink.disconnectFromServer() } } - Label { - text: "Node: " + demoNode.nodeId + // Value (prominent) + Rectangle { + Layout.fillWidth: true + height: 60 + color: "#f0f0f0" + radius: 4 + + ColumnLayout { + anchors.fill: parent + anchors.margins: 8 + spacing: 2 + + Label { + text: "Value" + font.pointSize: 10 + color: "gray" + } + Label { + text: demoNode.value !== undefined ? String(demoNode.value) : "—" + font.pointSize: 16 + font.bold: true + elide: Text.ElideRight + Layout.fillWidth: true + } + } } - Label { - text: "Monitored: " + demoNode.monitored - color: demoNode.monitored ? "green" : "gray" + + // Node info + GridLayout { + Layout.fillWidth: true + columns: 2 + columnSpacing: 12 + rowSpacing: 4 + + Label { + text: "Node ID:" + color: "gray" + } + Label { + text: demoNode.nodeId + Layout.fillWidth: true + } + + Label { + text: "Display Name:" + color: "gray" + } + Label { + text: demoNode.info.displayName || "—" + Layout.fillWidth: true + } + + Label { + text: "Data Type:" + color: "gray" + } + Label { + text: demoNode.info.dataType || "—" + Layout.fillWidth: true + } + + Label { + text: "Node Class:" + color: "gray" + } + Label { + text: demoNode.info.nodeClass || "—" + Layout.fillWidth: true + } + + Label { + text: "Access Level:" + color: "gray" + } + Label { + text: demoNode.info.accessLevel + Layout.fillWidth: true + } + + Label { + text: "Status:" + color: "gray" + } + Label { + text: demoNode.info.status || "—" + Layout.fillWidth: true + } + + Label { + text: "Source Time:" + color: "gray" + } + Label { + text: demoNode.info.sourceTimestamp.toLocaleString() || "—" + Layout.fillWidth: true + } + + Label { + text: "Server Time:" + color: "gray" + } + Label { + text: demoNode.info.serverTimestamp.toLocaleString() || "—" + Layout.fillWidth: true + } + + Label { + text: "Monitored:" + color: "gray" + } + Label { + text: demoNode.monitored ? "Yes" : "No" + color: demoNode.monitored ? "green" : "gray" + Layout.fillWidth: true + } } - Item { Layout.fillHeight: true } + Item { + Layout.fillHeight: true + } Button { Layout.fillWidth: true -- cgit v1.2.3