diff --git a/evcharger-app/qml/GridPage.qml b/evcharger-app/qml/GridPage.qml index 17e140a..64eeb0c 100644 --- a/evcharger-app/qml/GridPage.qml +++ b/evcharger-app/qml/GridPage.qml @@ -1,13 +1,269 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts +import EVChargerApp NavigationPage { + id: gridPage + title: qsTr("Grid") - Text { - text: "TODO" + function secondsText(value) { + return value === null || value === undefined ? "—" : qsTr("%1 s").arg(value) + } + function unitText(value, unit, decimals) { + return value === null || value === undefined + ? "—" : Qt.locale().toString(Number(value), "f", decimals) + " " + unit + } - Layout.fillHeight: true + // --- Country ------------------------------------------------------------------------------- + + RowLayout { + Layout.fillWidth: true + SettingsLabel { + text: qsTr("Country (cy)") + Layout.fillWidth: true + } + ApiKeyValueItem { + apiKey: "cy" + horizontalAlignment: Text.AlignRight + } + } + + // --- Reconnection after power outage (TOR / OVE R37 5.7.4.2) --------------------------------- + + Text { + Layout.fillWidth: true + Layout.topMargin: 10 + text: qsTr("Reconnection after power outage (TOR / OVE R37)") + font.bold: true + } + + Text { + Layout.fillWidth: true + text: qsTr("After power outage while charging, charging resumes only after voltage and frequency " + + "have been within the limits for the waiting time. Every violation restarts the waiting " + + "time. Charging then ramps up from the minimum current.") + color: "gray" + wrapMode: Text.Wrap + } + + GeneralOnOffSwitch { + apiKey: "rsre" + text: qsTr("Grid monitoring and ramp-up after power outage") + } + + EditValueItem { + text: qsTr("Waiting time after power outage") + apiKey: "gmtr" + visible: exists + valueText: secondsText(value) + editableItem: SpinBox { + editable: true + from: 0 + to: 300 // R37: adjustable between 0 s and 300 s + stepSize: 10 + } + } + + EditValueItem { + text: qsTr("Ramp-up rate") + apiKey: "rsrr" + visible: exists + valueText: unitText(value, "%/s", 2) + editableItem: DoubleSpinBox { + from: 0.01 + to: 10.0 + stepSize: 0.01 + decimals: 2 + } + } + + EditValueItem { + text: qsTr("Reconnection minimum voltage") + apiKey: "rmiv" + visible: exists + valueText: unitText(value, "V", 1) + editableItem: DoubleSpinBox { + from: 150.0 + to: 260.0 + stepSize: 0.1 + decimals: 1 + } + } + + EditValueItem { + text: qsTr("Reconnection maximum voltage") + apiKey: "rmav" + visible: exists + valueText: unitText(value, "V", 1) + editableItem: DoubleSpinBox { + from: 200.0 + to: 300.0 + stepSize: 0.1 + decimals: 1 + } + } + + EditValueItem { + text: qsTr("Reconnection minimum frequency") + apiKey: "rmif" + visible: exists + valueText: unitText(value, "Hz", 2) + editableItem: DoubleSpinBox { + from: 45.0 + to: 55.0 + stepSize: 0.01 + decimals: 2 + } + } + + EditValueItem { + text: qsTr("Reconnection maximum frequency") + apiKey: "rmaf" + visible: exists + valueText: unitText(value, "Hz", 2) + editableItem: DoubleSpinBox { + from: 45.0 + to: 55.0 + stepSize: 0.01 + decimals: 2 + } + } + + // --- Random delay after restart --------------------------------------------------------------- + + Text { + Layout.fillWidth: true + Layout.topMargin: 10 + text: qsTr("Random delay after restart") + font.bold: true + } + + Text { + Layout.fillWidth: true + text: qsTr("Additional random delay after every restart of the charger. This is NOT the TOR " + + "waiting time and must be 0 s for OVE R37, otherwise the random timer runs in front of " + + "the grid monitoring.") + color: "gray" + wrapMode: Text.Wrap + } + + EditValueItem { + text: qsTr("Random delay after restart (rdre)") + apiKey: "rdre" + visible: exists + valueText: secondsText(value) + editableItem: SpinBox { + editable: true + from: 0 + to: 600 + stepSize: 10 + } + } + + // --- Apply Austrian defaults ------------------------------------------------------------------ + + Text { + Layout.fillWidth: true + Layout.topMargin: 10 + text: qsTr("Austria (TOR) defaults") + font.bold: true + } + + Text { + Layout.fillWidth: true + text: qsTr("Writes values of certified Wattpilot uses: grid monitoring and ramp-up on, waiting " + + "time 60 s, ramp-up 0.16 %/s, 207–250.7 V, 49.9–50.1 Hz, random delay after restart 0 s.") + color: "gray" + wrapMode: Text.Wrap + } + + // one helper per key, so every request gets its own response + SetValueHelper { id: setRsre; deviceConnection: theDeviceConnection; apiKey: "rsre" } + SetValueHelper { id: setGmtr; deviceConnection: theDeviceConnection; apiKey: "gmtr" } + SetValueHelper { id: setRsrr; deviceConnection: theDeviceConnection; apiKey: "rsrr" } + SetValueHelper { id: setRmiv; deviceConnection: theDeviceConnection; apiKey: "rmiv" } + SetValueHelper { id: setRmav; deviceConnection: theDeviceConnection; apiKey: "rmav" } + SetValueHelper { id: setRmif; deviceConnection: theDeviceConnection; apiKey: "rmif" } + SetValueHelper { id: setRmaf; deviceConnection: theDeviceConnection; apiKey: "rmaf" } + SetValueHelper { id: setRdre; deviceConnection: theDeviceConnection; apiKey: "rdre" } + + RowLayout { + Layout.fillWidth: true + + Button { + text: qsTr("Apply Austria (TOR) defaults") + onClicked: { + setRsre.setValue(true) + setGmtr.setValue(60) + setRsrr.setValue(0.16) + setRmiv.setValue(207.0) + setRmav.setValue(250.7) + setRmif.setValue(49.9) + setRmaf.setValue(50.1) + setRdre.setValue(0) + } + } + + BusyIndicator { + visible: setRsre.pending || setGmtr.pending || setRsrr.pending || setRmiv.pending + || setRmav.pending || setRmif.pending || setRmaf.pending || setRdre.pending + } + } + + // per-key result, so a rejected key is visible immediately + GridLayout { + columns: 2 + Layout.fillWidth: true + + Text { + text: "rsre" + } + RequestStatusText { + request: setRsre + } + Text { + text: "gmtr" + } + RequestStatusText { + request: setGmtr + } + Text { + text: "rsrr" + } + RequestStatusText { + request: setRsrr + } + Text { + text: "rmiv" + } + RequestStatusText { + request: setRmiv + } + Text { + text: "rmav" + } + RequestStatusText { + request: setRmav + } + Text { + text: "rmif" + } + RequestStatusText { + request: setRmif + } + Text { + text: "rmaf" + } + RequestStatusText { + request: setRmaf + } + Text { + text: "rdre" + } + RequestStatusText { + request: setRdre + } } }