diff --git a/CMakeLists.txt b/CMakeLists.txt index 8134163..15280f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,6 +72,7 @@ qt_add_qml_module(evcharger-app ConfirmingOnOffSwitch.qml ConnectingScreen.qml ConnectionPage.qml + Constants.qml ControllerPage.qml ControllerTabPage.qml CurrentLevelsPage.qml @@ -120,6 +121,7 @@ qt_add_qml_module(evcharger-app SettingsTabPage.qml SetValueHelper.qml SimpleNavigationItem.qml + StartStopButton.qml SwitchLanguagePage.qml TimeComponentLabel.qml TimePickerDialog.qml @@ -154,6 +156,8 @@ qt_add_qml_module(evcharger-app ui-icons/MaterialIcons-Regular.ttf ) +set_source_files_properties(Constants.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE) + target_link_libraries(evcharger-app PUBLIC Qt6::Core Qt6::Gui diff --git a/ChargerTabPage.qml b/ChargerTabPage.qml index 55f3d10..7811408 100644 --- a/ChargerTabPage.qml +++ b/ChargerTabPage.qml @@ -76,6 +76,12 @@ AnimatedStackView { Text { Layout.fillWidth: true + ApiKeyValueHelper { + id: errApiKeyHelper + deviceConnection: theDeviceConnection + apiKey: "err" + } + text: { switch (carApiKeyHelper.value) { @@ -84,7 +90,7 @@ AnimatedStackView { case 2: return qsTr("Car is charging") case 3: return qsTr("Connecting to your car...") case 4: return qsTr("Charging completed") - case 5: return qsTr("Unknown error %0").arg(0) + case 5: return qsTr("Unknown error %0").arg(errApiKeyHelper.value) } } font.pixelSize: 20 @@ -150,12 +156,9 @@ AnimatedStackView { } } - Button { + StartStopButton { Layout.fillWidth: true - - Material.accent: Material.White - - text: qsTr("Start") + deviceConnection: theDeviceConnection } ApiKeyValueHelper { diff --git a/Constants.qml b/Constants.qml new file mode 100644 index 0000000..cfb1a1e --- /dev/null +++ b/Constants.qml @@ -0,0 +1,110 @@ +pragma Singleton + +import QtQuick + +QtObject { + readonly property int test: 5 + + enum LogicMode { + Default = 2, + Eco, + NextTrip + } + + enum Error { + None = 0, + FiAc = 1, + FiDc = 2, + Phase = 3, + Overvolt = 4, + Overamp = 5, + Diode = 6, + PpInvalid = 7, + GndInvalid = 8, + ContactorStuck = 9, + ContactorMiss = 10, + StatusLockStuckOpen = 12, + StatusLockStuckLocked = 13, + FiUnknown = 14, + Unknown = 15, + Overtemp = 16, + NoComm = 17, + CpInvalid = 18 + } + + enum AccessControl { + Open, + Wait, + EVCMS + } + + enum ForceState { + Neutral, + Off, + On + } + + enum CarState { + Unknown, + Idle, + Charging, + WaitCar, + Complete, + Error + } + + enum SchedulerControl { + Disabled, + Allow, + Block, + AllowFromGrid, + BlockFromGrid + } + + enum ModelStatus { + ChargingBecauseNoChargeCtrlData, + NotChargingBecauseOvertemperature, + NotChargingBecauseAccessControl, + ChargingBecauseForceStateOn, + NotChargingBecauseForceStateOff, + NotChargingBecauseScheduler, + NotChargingBecauseEnergyLimit, + ChargingBecauseAwattarPriceLow, + ChargingBecauseNextTripTestLadung, + ChargingBecauseNextTripNotEnoughTime, + ChargingBecauseNextTrip, + ChargingBecauseNextTripNoClock, + ChargingBecausePvSurplus, + ChargingBecauseFallbackV2Default, + ChargingBecauseFallbackV2Scheduler, + ChargingBecauseFallbackDefault, + NotChargingBecauseFallbackV2Awattar, + NotChargingBecauseFallbackEco, + NotChargingBecauseFallbackNextTrip, + ChargingBecauseCarCompatibilityKeepAlive, + ChargingBecauseChargePauseNotAllowed, + Reserved21DoNotUse, + NotChargingBecauseSimulateUnplugging, + NotChargingBecausePhaseSwitch, + NotChargingBecauseMinPauseDuration, + Reserved25DoNotUse, + NotChargingBecauseError, + NotChargingBecauseLoadManagementDoesntWant, + NotChargingBecauseOcppDoesntWant, + NotChargingBecauseReconnectDelay, + NotChargingBecauseAdapterBlocking, + NotChargingBecauseUnderfrequencyControl, + NotChargingBecauseUnbalancedLoad, + ChargingBecauseDischargingPvBattery, + NotChargingBecauseGridMonitoring, + NotChargingBecauseOcppFallback, + NotChargingBecauseFloorDetected, + NotChargingBecauseOcppInoperable + } + + enum PhaseSwitchMode { + Auto, + Force_1, + Force_3 + } +} diff --git a/DeviceListScreen.qml b/DeviceListScreen.qml index 44e0be4..2316d20 100644 --- a/DeviceListScreen.qml +++ b/DeviceListScreen.qml @@ -5,6 +5,7 @@ import EVChargerApp BaseNavigationPage { id: page + title: qsTr("Device list") signal deviceSelected(url: string, password: string) diff --git a/DeviceScreen.qml b/DeviceScreen.qml index 92b7acf..d98c4b3 100644 --- a/DeviceScreen.qml +++ b/DeviceScreen.qml @@ -71,8 +71,12 @@ Loader { Connections { target: theDeviceConnection - onShowDisturbed: connectionDisturbed.open() - onHideDisturbed: connectionDisturbed.close() + function onShowDisturbed() { + connectionDisturbed.open() + } + function onHideDisturbed() { + connectionDisturbed.close() + } } } } diff --git a/StartStopButton.qml b/StartStopButton.qml new file mode 100644 index 0000000..b2a1b7a --- /dev/null +++ b/StartStopButton.qml @@ -0,0 +1,68 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQml +import EVChargerApp + +Button { + id: button + + required property DeviceConnection deviceConnection + + ApiKeyValueHelper { + id: alwApiKeyHelper + deviceConnection: button.deviceConnection + apiKey: "alw" + } + + ApiKeyValueHelper { + id: modelStatusApiKeyHelper + deviceConnection: button.deviceConnection + apiKey: "modelStatus" + } + + SetValueHelper { + id: setValueHelper + deviceConnection: button.deviceConnection + apiKey: "" + } + + BusyIndicator { + visible: setValueHelper.pending + } + + RequestStatusText { + request: setValueHelper + } + + Material.accent: Material.White + + text: alwApiKeyHelper.value ? qsTr("Stop") : qsTr("Start") + + readonly property int notChargingBecauseAccessControl: Constants.ModelStatus.NotChargingBecauseAccessControl + readonly property int forceOff: Constants.ForceState.Off + readonly property int forceOn: Constants.ForceState.On + + onClicked: { + // random delays not considered at all in this logic (yet) + + if (alwApiKeyHelper.value) { + // currently allowed to charge -> STOP + + setValueHelper.apiKey = "frc" + setValueHelper.setValue(forceOff) + } else { + // currently not allowed to -> START + + if (modelStatusApiKeyHelper.value === notChargingBecauseAccessControl) { + // not charging because of access control -> start transaction + setValueHelper.apiKey = "trx" + setValueHelper.setValue(0) + } else { + // set force state to on + setValueHelper.apiKey = "frc" + setValueHelper.setValue(forceOn) + } + } + } +} diff --git a/i18n/qml_de.ts b/i18n/qml_de.ts index 89c6961..2046fb1 100644 --- a/i18n/qml_de.ts +++ b/i18n/qml_de.ts @@ -315,124 +315,124 @@ Geräte - - + + Internal error Interner Fehler - - + + No car connected Kein Auto angeschlossen - - + + Car is charging Auto wird geladen - - + + Connecting to your car... Verbinde mit Auto... - - + + Charging completed Ladevorgang abgeschlossen - - + + Unknown error %0 Unbekannter Fehler %0 - - + + Plug in the cable to start charging your car Stecke das Kabel ein, um dein Auto aufzuladen - - + + Charger is connecting to your car, it usually takes a few seconds Der Charger stellt die Verbindung zu deinem Auto her, das dauert in der Regel ein paar Sekunden - - + + Let's go-e :) Let's go-e :) - - + + Price limit Preisgrenze - - + + %0 ct/kWh %0 ct/kWh - - + + By %0 with %1 Bis %0 mit %1 - - + + %0 km %0 km - - + + Charging speed Ladegeschwindigkeit - - + + %0 & %1 - - + + %0 Ampere - - - - - - Automatic phase selection - - - - - - 1-phase - - - - - - 3-phase - + %0 Ampere + Automatic phase selection + Automatische Phasenwahl + + + + + 1-phase + 1-phasig + + + + + 3-phase + 3-phasig + + + + Unknown phase selection (%0) - + Unbekannte Phasen Selektion (%0) %0 Ampere & %1-phase @@ -443,14 +443,12 @@ Stecke das Kabel ein, um dein Auto aufzuladen - - Start - Start + Start - - + + Daily trip Daily trip @@ -999,62 +997,62 @@ Cloud Seriennr. - - + + Device list Geräteliste - - + + App Settings App Einstellungen - - + + My devices Meine Geräte - - + + Found devices Im Netzwerk verfügbare Geräte - - + + Delete Löschen - - + + Serial Number %0 Seriennummer %0 - - + + Local Lokal - - + + Cloud Cloud - - + + Solala Solala - - + + Add or setup device Gerät hinzufügen oder einrichten @@ -1075,14 +1073,14 @@ Meine Geräte: - - + + Manufacturer: Hersteller: - - + + Device Type: Gerätetyp: @@ -1091,14 +1089,14 @@ Anzeigename: - - + + Host Name: Host Name: - - + + Ip: Ip: @@ -1118,38 +1116,38 @@ DeviceScreen - - + + Password required Passwort erforderlich - - + + Password: Passwort: - - + + Password Passwort - - + + Authentication impossible! Authentifizierung unmöglich! - - + + To use this password remotely a password has to be setup first. This can be done over the AccessPoint. Um dieses Gerät aus der Ferne nutzen zu können, müssen Sie erst ein Passwort einrichten. Dies kann über den AccessPoint gemacht werden. - - + + Connection disturbed Verbindung schwer gestört @@ -2150,25 +2148,25 @@ Phase switching - + Phasen wechseln Automatic - + Automatisch 1-Phase - + 1-phasig 3-Phase - + 3-phasig @@ -2464,6 +2462,21 @@ Firmware • Hardwareinformationen • Lizenzen + + StartStopButton + + + + Stop + Stop + + + + + Start + Start + + SwitchLanguagePage diff --git a/qmldir b/qmldir index 02e7962..c2a5a51 100644 --- a/qmldir +++ b/qmldir @@ -22,6 +22,7 @@ EVChargerApp 1.0 CloudUrlsModel.qml EVChargerApp 1.0 ConfirmingOnOffSwitch.qml EVChargerApp 1.0 ConnectingScreen.qml EVChargerApp 1.0 ConnectionPage.qml +singleton EVChargerApp 1.0 Constants.qml EVChargerApp 1.0 ControllerPage.qml EVChargerApp 1.0 ControllerTabPage.qml EVChargerApp 1.0 CurrentLevelsPage.qml @@ -70,6 +71,7 @@ EVChargerApp 1.0 SetPriceLimitPage.qml EVChargerApp 1.0 SettingsTabPage.qml EVChargerApp 1.0 SetValueHelper.qml EVChargerApp 1.0 SimpleNavigationItem.qml +EVChargerApp 1.0 StartStopButton.qml EVChargerApp 1.0 SwitchLanguagePage.qml EVChargerApp 1.0 TimeComponentLabel.qml EVChargerApp 1.0 TimePickerDialog.qml