From 4f1a91fd3eb040e3473e8c49d89d24b8a3bc1102 Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 Date: Tue, 25 Nov 2025 18:41:44 +0100 Subject: [PATCH] Add controller 30sec history graph --- evcharger-app/CMakeLists.txt | 3 +- evcharger-app/qml/DeviceListScreen.qml | 2 +- evcharger-app/qml/InformationsTabPage.qml | 142 ++++++++++++++++++---- 3 files changed, 123 insertions(+), 24 deletions(-) diff --git a/evcharger-app/CMakeLists.txt b/evcharger-app/CMakeLists.txt index 838e8e8..e6281e1 100644 --- a/evcharger-app/CMakeLists.txt +++ b/evcharger-app/CMakeLists.txt @@ -1,4 +1,4 @@ -find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets Quick WebSockets LinguistTools) +find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets Quick WebSockets LinguistTools Charts) qt_standard_project_setup(REQUIRES 6.6 I18N_TRANSLATED_LANGUAGES de) @@ -155,6 +155,7 @@ target_link_libraries(evcharger-app PUBLIC Qt6::Widgets Qt6::Quick Qt6::WebSockets + Qt6::Charts qmsgpack QtZeroConf goecommon diff --git a/evcharger-app/qml/DeviceListScreen.qml b/evcharger-app/qml/DeviceListScreen.qml index 2316d20..9f1a68e 100644 --- a/evcharger-app/qml/DeviceListScreen.qml +++ b/evcharger-app/qml/DeviceListScreen.qml @@ -281,7 +281,7 @@ BaseNavigationPage { font.bold: true highlighted: true - Material.accent: Material.Blue + //Material.accent: Material.Blue display: listView.contentY < 20 ? AbstractButton.TextBesideIcon : AbstractButton.IconOnly diff --git a/evcharger-app/qml/InformationsTabPage.qml b/evcharger-app/qml/InformationsTabPage.qml index 66102f1..0730f44 100644 --- a/evcharger-app/qml/InformationsTabPage.qml +++ b/evcharger-app/qml/InformationsTabPage.qml @@ -15,6 +15,126 @@ ScrollableTabPage { text: qsTr("Informations") } + ChartView { + visible: categoryPowers.exists + + ApiKeyValueHelper { + id: categoryNames + deviceConnection: theDeviceConnection + apiKey: "ccn" + } + + ApiKeyValueHelper { + id: categoryPowers + deviceConnection: theDeviceConnection + apiKey: "ccp" + onValueChanged: { + const t = new Date(); + + const doit = function(category, value) { + category.append(t, value) + if (value) + category.visible = true + }; + + doit(category0, value[0]) + doit(category1, value[1]) + doit(category2, value[2]) + doit(category3, value[3]) + doit(category4, value[4]) + + // --- X axis range (last 30 seconds) --- + const now = new Date() // current time as Date + axisX.min = new Date(now.getTime() - 30*1000) // 30 sec ago + axisX.max = now + + // --- Y axis auto-range --- + let minY = Number.POSITIVE_INFINITY + let maxY = Number.NEGATIVE_INFINITY + + for (let s of [category0, category1, category2, category3, category4]) { + if (!s.visible) + continue + const c = s.count + if (c === 0) continue + + for (let i = 0; i < c; ++i) { + const y = s.at(i).y + if (y < minY) minY = y + if (y > maxY) maxY = y + } + } + + // fallback if no data + if (!isFinite(minY)) { + minY = 0 + maxY = 1 + } + + // add 10% padding + const d = (maxY - minY) * 0.1 + axisY.min = minY - d + axisY.max = maxY + d + } + } + + title: "Category Powers 30sec" + Layout.fillWidth: true + Layout.preferredHeight: 300 + antialiasing: true + + DateTimeAxis { + id: axisX + format: "hh:mm:ss" + tickCount: 5 + } + + ValueAxis { + id: axisY + tickCount: 6 + } + + LineSeries { + id: category0 + name: categoryNames.value[0] + axisX: axisX + axisY: axisY + visible: false + } + + LineSeries { + id: category1 + name: categoryNames.value[1] + axisX: axisX + axisY: axisY + visible: false + } + + LineSeries { + id: category2 + name: categoryNames.value[2] + axisX: axisX + axisY: axisY + visible: false + } + + LineSeries { + id: category3 + name: categoryNames.value[3] + axisX: axisX + axisY: axisY + visible: false + } + + LineSeries { + id: category4 + name: categoryNames.value[4] + axisX: axisX + axisY: axisY + visible: false + } + } + Text { id: statusText text: qsTr("Idle") @@ -86,28 +206,6 @@ ScrollableTabPage { } } - Repeater { - model: 5 - - ChartView { - title: "Line" - Layout.fillWidth: true - Layout.preferredHeight: page.height * 0.75 - antialiasing: true - - LineSeries { - name: "LineSeries" - XYPoint { x: 0; y: 0 } - XYPoint { x: 1.1; y: 2.1 } - XYPoint { x: 1.9; y: 3.3 } - XYPoint { x: 2.1; y: 2.1 } - XYPoint { x: 2.9; y: 4.9 } - XYPoint { x: 3.4; y: 3.0 } - XYPoint { x: 4.1; y: 3.3 } - } - } - } - OpenLinkButton { ApiKeyValueHelper { id: downloadsLink