diff --git a/evcharger-app/CMakeLists.txt b/evcharger-app/CMakeLists.txt
index 6d615b7..a76fee8 100644
--- a/evcharger-app/CMakeLists.txt
+++ b/evcharger-app/CMakeLists.txt
@@ -121,6 +121,7 @@ qt_add_qml_module(evcharger-app
qml/KwhLimitPage.qml
qml/LanguageSelector.qml
qml/LedPage.qml
+ qml/LedRingPreview.qml
qml/LicensesPage.qml
qml/LoadBalancingPage.qml
qml/LogicModeButton.qml
diff --git a/evcharger-app/i18n/qml_da.ts b/evcharger-app/i18n/qml_da.ts
index 3e47b50..5e0c538 100644
--- a/evcharger-app/i18n/qml_da.ts
+++ b/evcharger-app/i18n/qml_da.ts
@@ -2878,10 +2878,218 @@
LedPage
-
+ LEDLED
+
+
+
+
+
+ Ready
+ Klar
+
+
+
+ Color shown while the charger is ready and no car is connected.
+ Farve, der vises, når laderen er klar, og ingen bil er tilsluttet.
+
+
+
+
+
+
+ Waiting for car
+ Venter på bil
+
+
+
+ Color shown while the charger is waiting for the vehicle.
+ Farve, der vises, mens laderen venter på køretøjet.
+
+
+
+
+
+
+ Charging
+ Oplader
+
+
+
+ Color of the rotating tails while the vehicle is charging.
+ Farven på de roterende lyshaler, mens køretøjet oplades.
+
+
+
+
+
+
+ Finished
+ Fuldført
+
+
+
+ Color shown when charging has finished.
+ Farve, der vises, når opladningen er fuldført.
+
+
+
+ Live device
+ Direkte fra enheden
+
+
+
+ Live LED ring
+ LED-ring i realtid
+
+
+
+ No animation data
+ Ingen animationsdata
+
+
+
+ Waiting for authorization
+ Venter på godkendelse
+
+
+
+ Rainbow
+ Regnbue
+
+
+
+ Pulsating
+ Pulserende
+
+
+
+ Firmware update
+ Firmwareopdatering
+
+
+
+ Firmware update finished
+ Firmwareopdateringen er fuldført
+
+
+
+ Firmware update failed
+ Firmwareopdateringen mislykkedes
+
+
+
+ Configured preview
+ Konfigureret forhåndsvisning
+
+
+
+ Adjust how the LED ring communicates charging states and preview the result before using it on the charger.
+ Juster, hvordan LED-ringen viser opladningstilstande, og forhåndsvis resultatet, før du bruger det på laderen.
+
+
+
+ LED ring preview
+ Forhåndsvisning af LED-ring
+
+
+
+ Preview
+ Forhåndsvisning
+
+
+
+ The live preview follows the animation reported by the charger. Select another state to preview its configured color; the charging preview includes the rotating tails.
+ Forhåndsvisningen i realtid følger den animation, som laderen rapporterer. Vælg en anden tilstand for at forhåndsvise dens konfigurerede farve; opladningsforhåndsvisningen indeholder de roterende lyshaler.
+
+
+
+ Brightness
+ Lysstyrke
+
+
+
+ LED brightness
+ LED-lysstyrke
+
+
+
+
+ %1%
+ %1%
+
+
+
+ Lower brightness is less distracting at night. Set it to zero to turn the ring off completely.
+ Lavere lysstyrke er mindre forstyrrende om natten. Indstil den til nul for at slukke ringen helt.
+
+
+
+ Status colors
+ Statusfarver
+
+
+
+ Tap a charging state to choose the color used by the LED ring.
+ Tryk på en opladningstilstand for at vælge den farve, LED-ringen bruger.
+
+
+
+ Energy saving
+ Energibesparelse
+
+
+
+ Energy saving on
+ Energibesparelse til
+
+
+
+ Energy saving off
+ Energibesparelse fra
+
+
+
+ Energy saving turns off status lighting when it is not needed. Charging and important warnings remain visible.
+ Energibesparelse slukker statusbelysningen, når den ikke er nødvendig. Opladning og vigtige advarsler forbliver synlige.
+
+
+
+ Keep mode indicators on
+ Behold tilstandsindikatorerne tændt
+
+
+
+ Keep the small charging-mode indicators visible while the LED ring is saving energy.
+ Behold de små opladningstilstandsindikatorer synlige, mens LED-ringen sparer energi.
+
+
+
+ Service diagnostics
+ Servicediagnostik
+
+
+
+ These service options can replace normal status animations. Leave them off unless you are diagnosing the LED hardware.
+ Disse serviceindstillinger kan erstatte normale statusanimationer. Lad dem være slået fra, medmindre du diagnosticerer LED-hardwaren.
+
+
+
+ Factory LED test
+ Fabrikkens LED-test
+
+
+
+ LED diagnostics
+ LED-diagnostik
+
+
+
+ Choose color for %1
+ Vælg farve til %1
+ LicensesPage
diff --git a/evcharger-app/i18n/qml_de.ts b/evcharger-app/i18n/qml_de.ts
index 0649dd1..de4f5a9 100644
--- a/evcharger-app/i18n/qml_de.ts
+++ b/evcharger-app/i18n/qml_de.ts
@@ -3053,10 +3053,218 @@
LedPage
-
+ LEDLED
+
+
+
+
+
+ Ready
+ Bereit
+
+
+
+ Color shown while the charger is ready and no car is connected.
+ Farbe, die angezeigt wird, wenn der Charger bereit und kein Auto verbunden ist.
+
+
+
+
+
+
+ Waiting for car
+ Warte auf Auto
+
+
+
+ Color shown while the charger is waiting for the vehicle.
+ Farbe, die angezeigt wird, während der Charger auf das Fahrzeug wartet.
+
+
+
+
+
+
+ Charging
+ Lädt
+
+
+
+ Color of the rotating tails while the vehicle is charging.
+ Farbe der rotierenden Schweife, während das Fahrzeug lädt.
+
+
+
+
+
+
+ Finished
+ Beendet
+
+
+
+ Color shown when charging has finished.
+ Farbe, die nach Abschluss des Ladevorgangs angezeigt wird.
+
+
+
+ Live device
+ Live-Gerät
+
+
+
+ Live LED ring
+ Live-LED-Ring
+
+
+
+ No animation data
+ Keine Animationsdaten
+
+
+
+ Waiting for authorization
+ Warte auf Autorisierung
+
+
+
+ Rainbow
+ Regenbogen
+
+
+
+ Pulsating
+ Pulsierend
+
+
+
+ Firmware update
+ Firmware-Update
+
+
+
+ Firmware update finished
+ Firmware-Update abgeschlossen
+
+
+
+ Firmware update failed
+ Firmware-Update fehlgeschlagen
+
+
+
+ Configured preview
+ Konfigurierte Vorschau
+
+
+
+ Adjust how the LED ring communicates charging states and preview the result before using it on the charger.
+ Passe an, wie der LED-Ring Ladezustände anzeigt, und prüfe das Ergebnis in der Vorschau, bevor du es am Charger verwendest.
+
+
+
+ LED ring preview
+ LED-Ring-Vorschau
+
+
+
+ Preview
+ Vorschau
+
+
+
+ The live preview follows the animation reported by the charger. Select another state to preview its configured color; the charging preview includes the rotating tails.
+ Die Live-Vorschau folgt der vom Charger gemeldeten Animation. Wähle einen anderen Zustand, um dessen konfigurierte Farbe zu prüfen; die Ladevorschau enthält die rotierenden Schweife.
+
+
+
+ Brightness
+ Helligkeit
+
+
+
+ LED brightness
+ LED-Helligkeit
+
+
+
+
+ %1%
+ %1%
+
+
+
+ Lower brightness is less distracting at night. Set it to zero to turn the ring off completely.
+ Geringere Helligkeit stört nachts weniger. Stelle sie auf null, um den Ring vollständig auszuschalten.
+
+
+
+ Status colors
+ Statusfarben
+
+
+
+ Tap a charging state to choose the color used by the LED ring.
+ Tippe auf einen Ladezustand, um die vom LED-Ring verwendete Farbe auszuwählen.
+
+
+
+ Energy saving
+ Energiesparen
+
+
+
+ Energy saving on
+ Energiesparen ein
+
+
+
+ Energy saving off
+ Energiesparen aus
+
+
+
+ Energy saving turns off status lighting when it is not needed. Charging and important warnings remain visible.
+ Beim Energiesparen wird die Statusbeleuchtung ausgeschaltet, wenn sie nicht benötigt wird. Laden und wichtige Warnungen bleiben sichtbar.
+
+
+
+ Keep mode indicators on
+ Modusanzeigen eingeschaltet lassen
+
+
+
+ Keep the small charging-mode indicators visible while the LED ring is saving energy.
+ Lasse die kleinen Lademodus-Anzeigen sichtbar, während der LED-Ring Energie spart.
+
+
+
+ Service diagnostics
+ Servicediagnose
+
+
+
+ These service options can replace normal status animations. Leave them off unless you are diagnosing the LED hardware.
+ Diese Serviceoptionen können normale Statusanimationen ersetzen. Lasse sie ausgeschaltet, sofern du nicht die LED-Hardware diagnostizierst.
+
+
+
+ Factory LED test
+ Werkseitiger LED-Test
+
+
+
+ LED diagnostics
+ LED-Diagnose
+
+
+
+ Choose color for %1
+ Farbe für %1 wählen
+ LicensesPage
@@ -3382,7 +3590,7 @@
Charging
-
+ Lädt
@@ -4771,7 +4979,7 @@
Finished
-
+ Beendet
diff --git a/evcharger-app/i18n/qml_fi.ts b/evcharger-app/i18n/qml_fi.ts
index 3a0e580..9866f2a 100644
--- a/evcharger-app/i18n/qml_fi.ts
+++ b/evcharger-app/i18n/qml_fi.ts
@@ -2878,10 +2878,218 @@
LedPage
-
+ LEDLED
+
+
+
+
+
+ Ready
+ Valmiina
+
+
+
+ Color shown while the charger is ready and no car is connected.
+ Väri, joka näytetään, kun laturi on valmiina eikä autoa ole yhdistetty.
+
+
+
+
+
+
+ Waiting for car
+ Odottaa autoa
+
+
+
+ Color shown while the charger is waiting for the vehicle.
+ Väri, joka näytetään, kun laturi odottaa ajoneuvoa.
+
+
+
+
+
+
+ Charging
+ Lataus
+
+
+
+ Color of the rotating tails while the vehicle is charging.
+ Pyörivien valovanojen väri ajoneuvon latauksen aikana.
+
+
+
+
+
+
+ Finished
+ Lataus valmis
+
+
+
+ Color shown when charging has finished.
+ Väri, joka näytetään latauksen valmistuttua.
+
+
+
+ Live device
+ Laite reaaliajassa
+
+
+
+ Live LED ring
+ Reaaliaikainen LED-rengas
+
+
+
+ No animation data
+ Ei animaatiotietoja
+
+
+
+ Waiting for authorization
+ Odotetaan valtuutusta
+
+
+
+ Rainbow
+ Sateenkaari
+
+
+
+ Pulsating
+ Sykkivä
+
+
+
+ Firmware update
+ Laiteohjelmistopäivitys
+
+
+
+ Firmware update finished
+ Laiteohjelmistopäivitys valmis
+
+
+
+ Firmware update failed
+ Laiteohjelmistopäivitys epäonnistui
+
+
+
+ Configured preview
+ Määritetty esikatselu
+
+
+
+ Adjust how the LED ring communicates charging states and preview the result before using it on the charger.
+ Säädä, miten LED-rengas ilmaisee lataustilat, ja esikatsele tulos ennen sen käyttämistä laturissa.
+
+
+
+ LED ring preview
+ LED-renkaan esikatselu
+
+
+
+ Preview
+ Esikatselu
+
+
+
+ The live preview follows the animation reported by the charger. Select another state to preview its configured color; the charging preview includes the rotating tails.
+ Reaaliaikainen esikatselu seuraa laturin ilmoittamaa animaatiota. Valitse toinen tila nähdäksesi sen määritetyn värin; latauksen esikatselu sisältää pyörivät valovanat.
+
+
+
+ Brightness
+ Kirkkaus
+
+
+
+ LED brightness
+ LED-kirkkaus
+
+
+
+
+ %1%
+ %1%
+
+
+
+ Lower brightness is less distracting at night. Set it to zero to turn the ring off completely.
+ Pienempi kirkkaus häiritsee vähemmän yöllä. Aseta arvoksi nolla sammuttaaksesi renkaan kokonaan.
+
+
+
+ Status colors
+ Tilavärit
+
+
+
+ Tap a charging state to choose the color used by the LED ring.
+ Valitse LED-renkaan käyttämä väri napauttamalla lataustilaa.
+
+
+
+ Energy saving
+ Energiansäästö
+
+
+
+ Energy saving on
+ Energiansäästö käytössä
+
+
+
+ Energy saving off
+ Energiansäästö pois käytöstä
+
+
+
+ Energy saving turns off status lighting when it is not needed. Charging and important warnings remain visible.
+ Energiansäästö sammuttaa tilavalot, kun niitä ei tarvita. Lataus ja tärkeät varoitukset pysyvät näkyvissä.
+
+
+
+ Keep mode indicators on
+ Pidä tilan merkkivalot päällä
+
+
+
+ Keep the small charging-mode indicators visible while the LED ring is saving energy.
+ Pidä pienet lataustilan merkkivalot näkyvissä, kun LED-rengas säästää energiaa.
+
+
+
+ Service diagnostics
+ Huoltodiagnostiikka
+
+
+
+ These service options can replace normal status animations. Leave them off unless you are diagnosing the LED hardware.
+ Nämä huoltoasetukset voivat korvata normaalit tila-animaatiot. Jätä ne pois käytöstä, ellet diagnosoi LED-laitteistoa.
+
+
+
+ Factory LED test
+ Tehtaan LED-testi
+
+
+
+ LED diagnostics
+ LED-diagnostiikka
+
+
+
+ Choose color for %1
+ Valitse kohteen %1 väri
+ LicensesPage
diff --git a/evcharger-app/i18n/qml_nb.ts b/evcharger-app/i18n/qml_nb.ts
index 819c27f..ccd0563 100644
--- a/evcharger-app/i18n/qml_nb.ts
+++ b/evcharger-app/i18n/qml_nb.ts
@@ -2878,10 +2878,218 @@
LedPage
-
+ LEDLED
+
+
+
+
+
+ Ready
+ Klar
+
+
+
+ Color shown while the charger is ready and no car is connected.
+ Farge som vises når laderen er klar og ingen bil er tilkoblet.
+
+
+
+
+
+
+ Waiting for car
+ Venter på bil
+
+
+
+ Color shown while the charger is waiting for the vehicle.
+ Farge som vises mens laderen venter på kjøretøyet.
+
+
+
+
+
+
+ Charging
+ Lader
+
+
+
+ Color of the rotating tails while the vehicle is charging.
+ Fargen på de roterende lyshalene mens kjøretøyet lades.
+
+
+
+
+
+
+ Finished
+ Fullført
+
+
+
+ Color shown when charging has finished.
+ Farge som vises når ladingen er fullført.
+
+
+
+ Live device
+ Direkte fra enheten
+
+
+
+ Live LED ring
+ LED-ring i sanntid
+
+
+
+ No animation data
+ Ingen animasjonsdata
+
+
+
+ Waiting for authorization
+ Venter på godkjenning
+
+
+
+ Rainbow
+ Regnbue
+
+
+
+ Pulsating
+ Pulserende
+
+
+
+ Firmware update
+ Fastvareoppdatering
+
+
+
+ Firmware update finished
+ Fastvareoppdateringen er fullført
+
+
+
+ Firmware update failed
+ Fastvareoppdateringen mislyktes
+
+
+
+ Configured preview
+ Konfigurert forhåndsvisning
+
+
+
+ Adjust how the LED ring communicates charging states and preview the result before using it on the charger.
+ Juster hvordan LED-ringen viser ladestatus, og forhåndsvis resultatet før du bruker det på laderen.
+
+
+
+ LED ring preview
+ Forhåndsvisning av LED-ring
+
+
+
+ Preview
+ Forhåndsvisning
+
+
+
+ The live preview follows the animation reported by the charger. Select another state to preview its configured color; the charging preview includes the rotating tails.
+ Forhåndsvisningen i sanntid følger animasjonen som laderen rapporterer. Velg en annen tilstand for å forhåndsvise den konfigurerte fargen; ladeforhåndsvisningen inkluderer de roterende lyshalene.
+
+
+
+ Brightness
+ Lysstyrke
+
+
+
+ LED brightness
+ LED-lysstyrke
+
+
+
+
+ %1%
+ %1%
+
+
+
+ Lower brightness is less distracting at night. Set it to zero to turn the ring off completely.
+ Lavere lysstyrke er mindre forstyrrende om natten. Sett den til null for å slå av ringen helt.
+
+
+
+ Status colors
+ Statusfarger
+
+
+
+ Tap a charging state to choose the color used by the LED ring.
+ Trykk på en ladestatus for å velge fargen som LED-ringen bruker.
+
+
+
+ Energy saving
+ Energisparing
+
+
+
+ Energy saving on
+ Energisparing på
+
+
+
+ Energy saving off
+ Energisparing av
+
+
+
+ Energy saving turns off status lighting when it is not needed. Charging and important warnings remain visible.
+ Energisparing slår av statusbelysningen når den ikke trengs. Lading og viktige advarsler forblir synlige.
+
+
+
+ Keep mode indicators on
+ Behold modusindikatorene på
+
+
+
+ Keep the small charging-mode indicators visible while the LED ring is saving energy.
+ Behold de små lademodusindikatorene synlige mens LED-ringen sparer energi.
+
+
+
+ Service diagnostics
+ Servicediagnostikk
+
+
+
+ These service options can replace normal status animations. Leave them off unless you are diagnosing the LED hardware.
+ Disse servicealternativene kan erstatte normale statusanimasjoner. La dem være av med mindre du feilsøker LED-maskinvaren.
+
+
+
+ Factory LED test
+ LED-test fra fabrikk
+
+
+
+ LED diagnostics
+ LED-diagnostikk
+
+
+
+ Choose color for %1
+ Velg farge for %1
+ LicensesPage
diff --git a/evcharger-app/i18n/qml_sv.ts b/evcharger-app/i18n/qml_sv.ts
index 7af3d13..13be1b2 100644
--- a/evcharger-app/i18n/qml_sv.ts
+++ b/evcharger-app/i18n/qml_sv.ts
@@ -2878,10 +2878,218 @@
LedPage
-
+ LEDLED
+
+
+
+
+
+ Ready
+ Klar
+
+
+
+ Color shown while the charger is ready and no car is connected.
+ Färg som visas när laddaren är klar och ingen bil är ansluten.
+
+
+
+
+
+
+ Waiting for car
+ Väntar på bil
+
+
+
+ Color shown while the charger is waiting for the vehicle.
+ Färg som visas medan laddaren väntar på fordonet.
+
+
+
+
+
+
+ Charging
+ Laddar
+
+
+
+ Color of the rotating tails while the vehicle is charging.
+ Färgen på de roterande ljussvansarna medan fordonet laddas.
+
+
+
+
+
+
+ Finished
+ Slutförd
+
+
+
+ Color shown when charging has finished.
+ Färg som visas när laddningen är slutförd.
+
+
+
+ Live device
+ Aktuell enhet
+
+
+
+ Live LED ring
+ LED-ring i realtid
+
+
+
+ No animation data
+ Inga animationsdata
+
+
+
+ Waiting for authorization
+ Väntar på auktorisering
+
+
+
+ Rainbow
+ Regnbåge
+
+
+
+ Pulsating
+ Pulserande
+
+
+
+ Firmware update
+ Firmwareuppdatering
+
+
+
+ Firmware update finished
+ Firmwareuppdateringen är slutförd
+
+
+
+ Firmware update failed
+ Firmwareuppdateringen misslyckades
+
+
+
+ Configured preview
+ Konfigurerad förhandsvisning
+
+
+
+ Adjust how the LED ring communicates charging states and preview the result before using it on the charger.
+ Anpassa hur LED-ringen visar laddningsstatus och förhandsgranska resultatet innan du använder det på laddaren.
+
+
+
+ LED ring preview
+ Förhandsvisning av LED-ring
+
+
+
+ Preview
+ Förhandsvisning
+
+
+
+ The live preview follows the animation reported by the charger. Select another state to preview its configured color; the charging preview includes the rotating tails.
+ Förhandsvisningen i realtid följer animationen som laddaren rapporterar. Välj ett annat tillstånd för att förhandsgranska dess konfigurerade färg; laddningsförhandsvisningen innehåller de roterande ljussvansarna.
+
+
+
+ Brightness
+ Ljusstyrka
+
+
+
+ LED brightness
+ LED-ljusstyrka
+
+
+
+
+ %1%
+ %1%
+
+
+
+ Lower brightness is less distracting at night. Set it to zero to turn the ring off completely.
+ Lägre ljusstyrka stör mindre på natten. Ställ in den på noll för att stänga av ringen helt.
+
+
+
+ Status colors
+ Statusfärger
+
+
+
+ Tap a charging state to choose the color used by the LED ring.
+ Tryck på ett laddningstillstånd för att välja färgen som LED-ringen använder.
+
+
+
+ Energy saving
+ Energisparläge
+
+
+
+ Energy saving on
+ Energisparläge på
+
+
+
+ Energy saving off
+ Energisparläge av
+
+
+
+ Energy saving turns off status lighting when it is not needed. Charging and important warnings remain visible.
+ Energisparläget stänger av statusbelysningen när den inte behövs. Laddning och viktiga varningar förblir synliga.
+
+
+
+ Keep mode indicators on
+ Behåll lägesindikatorerna tända
+
+
+
+ Keep the small charging-mode indicators visible while the LED ring is saving energy.
+ Behåll de små laddningslägesindikatorerna synliga medan LED-ringen sparar energi.
+
+
+
+ Service diagnostics
+ Servicediagnostik
+
+
+
+ These service options can replace normal status animations. Leave them off unless you are diagnosing the LED hardware.
+ Dessa servicealternativ kan ersätta normala statusanimationer. Låt dem vara avstängda om du inte felsöker LED-maskinvaran.
+
+
+
+ Factory LED test
+ LED-test från fabrik
+
+
+
+ LED diagnostics
+ LED-diagnostik
+
+
+
+ Choose color for %1
+ Välj färg för %1
+ LicensesPage
diff --git a/evcharger-app/i18n/qml_tr.ts b/evcharger-app/i18n/qml_tr.ts
index 4c513b4..c14c189 100644
--- a/evcharger-app/i18n/qml_tr.ts
+++ b/evcharger-app/i18n/qml_tr.ts
@@ -2878,10 +2878,218 @@
LedPage
-
+ LEDLED
+
+
+
+
+
+ Ready
+ Hazır
+
+
+
+ Color shown while the charger is ready and no car is connected.
+ Şarj cihazı hazırken ve hiçbir araç bağlı değilken gösterilen renk.
+
+
+
+
+
+
+ Waiting for car
+ Araç bekleniyor
+
+
+
+ Color shown while the charger is waiting for the vehicle.
+ Şarj cihazı aracı beklerken gösterilen renk.
+
+
+
+
+
+
+ Charging
+ Şarj ediliyor
+
+
+
+ Color of the rotating tails while the vehicle is charging.
+ Araç şarj olurken dönen ışık kuyruklarının rengi.
+
+
+
+
+
+
+ Finished
+ Tamamlandı
+
+
+
+ Color shown when charging has finished.
+ Şarj tamamlandığında gösterilen renk.
+
+
+
+ Live device
+ Canlı cihaz
+
+
+
+ Live LED ring
+ Canlı LED halkası
+
+
+
+ No animation data
+ Animasyon verisi yok
+
+
+
+ Waiting for authorization
+ Yetkilendirme bekleniyor
+
+
+
+ Rainbow
+ Gökkuşağı
+
+
+
+ Pulsating
+ Nabız efekti
+
+
+
+ Firmware update
+ Donanım yazılımı güncellemesi
+
+
+
+ Firmware update finished
+ Donanım yazılımı güncellemesi tamamlandı
+
+
+
+ Firmware update failed
+ Donanım yazılımı güncellemesi başarısız
+
+
+
+ Configured preview
+ Yapılandırılmış önizleme
+
+
+
+ Adjust how the LED ring communicates charging states and preview the result before using it on the charger.
+ LED halkasının şarj durumlarını nasıl gösterdiğini ayarlayın ve şarj cihazında kullanmadan önce sonucu önizleyin.
+
+
+
+ LED ring preview
+ LED halkası önizlemesi
+
+
+
+ Preview
+ Önizleme
+
+
+
+ The live preview follows the animation reported by the charger. Select another state to preview its configured color; the charging preview includes the rotating tails.
+ Canlı önizleme, şarj cihazının bildirdiği animasyonu izler. Yapılandırılmış rengini önizlemek için başka bir durum seçin; şarj önizlemesi dönen ışık kuyruklarını içerir.
+
+
+
+ Brightness
+ Parlaklık
+
+
+
+ LED brightness
+ LED parlaklığı
+
+
+
+
+ %1%
+ %1%
+
+
+
+ Lower brightness is less distracting at night. Set it to zero to turn the ring off completely.
+ Düşük parlaklık geceleri daha az rahatsız eder. Halkayı tamamen kapatmak için sıfıra ayarlayın.
+
+
+
+ Status colors
+ Durum renkleri
+
+
+
+ Tap a charging state to choose the color used by the LED ring.
+ LED halkasının kullanacağı rengi seçmek için bir şarj durumuna dokunun.
+
+
+
+ Energy saving
+ Enerji tasarrufu
+
+
+
+ Energy saving on
+ Enerji tasarrufu açık
+
+
+
+ Energy saving off
+ Enerji tasarrufu kapalı
+
+
+
+ Energy saving turns off status lighting when it is not needed. Charging and important warnings remain visible.
+ Enerji tasarrufu, gerekmediğinde durum aydınlatmasını kapatır. Şarj ve önemli uyarılar görünür kalır.
+
+
+
+ Keep mode indicators on
+ Mod göstergelerini açık tut
+
+
+
+ Keep the small charging-mode indicators visible while the LED ring is saving energy.
+ LED halkası enerji tasarrufu yaparken küçük şarj modu göstergelerini görünür tutun.
+
+
+
+ Service diagnostics
+ Servis tanılama
+
+
+
+ These service options can replace normal status animations. Leave them off unless you are diagnosing the LED hardware.
+ Bu servis seçenekleri normal durum animasyonlarının yerini alabilir. LED donanımını tanılamıyorsanız bunları kapalı bırakın.
+
+
+
+ Factory LED test
+ Fabrika LED testi
+
+
+
+ LED diagnostics
+ LED tanılama
+
+
+
+ Choose color for %1
+ %1 için renk seçin
+ LicensesPage
diff --git a/evcharger-app/qml/LedPage.qml b/evcharger-app/qml/LedPage.qml
index a3c5a69..4594835 100644
--- a/evcharger-app/qml/LedPage.qml
+++ b/evcharger-app/qml/LedPage.qml
@@ -1,13 +1,438 @@
+pragma ComponentBehavior: Bound
+
import QtQuick
import QtQuick.Controls
+import QtQuick.Dialogs
import QtQuick.Layouts
+import EVChargerApp
NavigationPage {
+ id: page
+
+ property string selectedColorKey: "cid"
+ property string selectedColorName
+ property string previewMode: "live"
+
title: qsTr("LED")
- Text {
- text: "TODO"
+ function colorOptions() {
+ const result = []
+ if (idleColor.exists) {
+ result.push({
+ key: "cid",
+ title: qsTr("Ready"),
+ description: qsTr("Color shown while the charger is ready and no car is connected."),
+ value: idleColor.value
+ })
+ }
+ if (waitingColor.exists) {
+ result.push({
+ key: "cwc",
+ title: qsTr("Waiting for car"),
+ description: qsTr("Color shown while the charger is waiting for the vehicle."),
+ value: waitingColor.value
+ })
+ }
+ if (chargingColor.exists) {
+ result.push({
+ key: "cch",
+ title: qsTr("Charging"),
+ description: qsTr("Color of the rotating tails while the vehicle is charging."),
+ value: chargingColor.value
+ })
+ }
+ if (finishedColor.exists) {
+ result.push({
+ key: "cfi",
+ title: qsTr("Finished"),
+ description: qsTr("Color shown when charging has finished."),
+ value: finishedColor.value
+ })
+ }
+ return result
+ }
- Layout.fillHeight: true
+ function previewOptions() {
+ const result = []
+ if (liveAnimation.exists)
+ result.push({text: qsTr("Live device"), value: "live"})
+ if (idleColor.exists)
+ result.push({text: qsTr("Ready"), value: "idle"})
+ if (waitingColor.exists)
+ result.push({text: qsTr("Waiting for car"), value: "waiting"})
+ if (chargingColor.exists)
+ result.push({text: qsTr("Charging"), value: "charging"})
+ if (finishedColor.exists)
+ result.push({text: qsTr("Finished"), value: "finished"})
+ return result
+ }
+
+ function previewTitle() {
+ switch (previewMode) {
+ case "idle": return qsTr("Ready")
+ case "waiting": return qsTr("Waiting for car")
+ case "charging": return qsTr("Charging")
+ case "finished": return qsTr("Finished")
+ default: return qsTr("Live LED ring")
+ }
+ }
+
+ function animationName() {
+ const data = liveAnimation.value
+ if (data === null || data === undefined || !data.name)
+ return qsTr("No animation data")
+ switch (String(data.name)) {
+ case "Ready": return qsTr("Ready")
+ case "WaitCar": return qsTr("Waiting for car")
+ case "WaitAuth": return qsTr("Waiting for authorization")
+ case "Charging": return qsTr("Charging")
+ case "Finished": return qsTr("Finished")
+ case "Rainbow": return qsTr("Rainbow")
+ case "Pulsate": return qsTr("Pulsating")
+ case "OtaProgress": return qsTr("Firmware update")
+ case "OtaFinished": return qsTr("Firmware update finished")
+ case "OtaFailed": return qsTr("Firmware update failed")
+ default:
+ return String(data.name).replace(/([a-z])([A-Z])/g, "$1 $2")
+ }
+ }
+
+ function previewDetail() {
+ if (previewMode !== "live")
+ return qsTr("Configured preview")
+ return animationName()
+ }
+
+ function normalizeColor(value) {
+ const text = String(value)
+ return text.length === 9 ? "#" + text.substring(3) : text
+ }
+
+ function editColor(option) {
+ selectedColorKey = option.key
+ selectedColorName = option.title
+ colorDialog.selectedColor = option.value || "#000000"
+ colorDialog.open()
+ }
+
+ ApiKeyValueHelper {
+ id: liveAnimation
+ deviceConnection: theDeviceConnection
+ apiKey: "led"
+ }
+
+ ApiKeyValueHelper {
+ id: ledCount
+ deviceConnection: theDeviceConnection
+ apiKey: "nld"
+ }
+
+ ApiKeyValueHelper {
+ id: brightness
+ deviceConnection: theDeviceConnection
+ apiKey: "lbr"
+ }
+
+ ApiKeyValueHelper {
+ id: idleColor
+ deviceConnection: theDeviceConnection
+ apiKey: "cid"
+ }
+
+ ApiKeyValueHelper {
+ id: waitingColor
+ deviceConnection: theDeviceConnection
+ apiKey: "cwc"
+ }
+
+ ApiKeyValueHelper {
+ id: chargingColor
+ deviceConnection: theDeviceConnection
+ apiKey: "cch"
+ }
+
+ ApiKeyValueHelper {
+ id: finishedColor
+ deviceConnection: theDeviceConnection
+ apiKey: "cfi"
+ }
+
+ ApiKeyValueHelper {
+ id: energySaving
+ deviceConnection: theDeviceConnection
+ apiKey: "lse"
+ }
+
+ ApiKeyValueHelper {
+ id: modeLedsWhileSaving
+ deviceConnection: theDeviceConnection
+ apiKey: "mws"
+ }
+
+ ApiKeyValueHelper {
+ id: factoryDebug
+ deviceConnection: theDeviceConnection
+ apiKey: "fldb"
+ }
+
+ ApiKeyValueHelper {
+ id: ledDebug
+ deviceConnection: theDeviceConnection
+ apiKey: "ldb"
+ }
+
+ SetValueHelper {
+ id: colorSetter
+ deviceConnection: theDeviceConnection
+ apiKey: page.selectedColorKey
+ }
+
+ Text {
+ Layout.fillWidth: true
+ text: qsTr("Adjust how the LED ring communicates charging states and preview the result before using it on the charger.")
+ wrapMode: Text.Wrap
+ color: "#5f6368"
+ }
+
+ SettingsSectionLabel {
+ text: qsTr("LED ring preview")
+ }
+
+ SettingsCard {
+ RowLayout {
+ Layout.fillWidth: true
+
+ SettingsLabel {
+ Layout.fillWidth: true
+ text: qsTr("Preview")
+ }
+
+ ComboBox {
+ id: previewSelector
+ model: previewOptions()
+ textRole: "text"
+ valueRole: "value"
+ onActivated: page.previewMode = currentValue
+
+ function selectCurrentMode() {
+ const index = indexOfValue(page.previewMode)
+ if (index >= 0)
+ currentIndex = index
+ else if (count > 0) {
+ currentIndex = 0
+ page.previewMode = currentValue
+ }
+ }
+
+ Component.onCompleted: selectCurrentMode()
+ onModelChanged: Qt.callLater(selectCurrentMode)
+ }
+ }
+
+ LedRingPreview {
+ Layout.alignment: Qt.AlignHCenter
+ Layout.preferredWidth: Math.min(280, page.width - 50)
+ Layout.preferredHeight: width
+ animationData: liveAnimation.value
+ previewMode: page.previewMode
+ configuredLedCount: ledCount.exists ? Number(ledCount.value) : 32
+ configuredBrightness: brightness.exists ? Number(brightness.value) : 255
+ idleColor: idleColor.value || "#0000ff"
+ waitingColor: waitingColor.value || "#ffff00"
+ chargingColor: chargingColor.value || "#00ffff"
+ finishedColor: finishedColor.value || "#00ff00"
+ statusText: previewTitle()
+ detailText: previewDetail()
+ }
+
+ Text {
+ Layout.fillWidth: true
+ text: qsTr("The live preview follows the animation reported by the charger. Select another state to preview its configured color; the charging preview includes the rotating tails.")
+ wrapMode: Text.Wrap
+ horizontalAlignment: Text.AlignHCenter
+ color: "#5f6368"
+ }
+ }
+
+ SettingsSectionLabel {
+ visible: brightness.exists
+ text: qsTr("Brightness")
+ }
+
+ EditValueItem {
+ apiKey: "lbr"
+ text: qsTr("LED brightness")
+ visible: exists
+ valueText: value === null || value === undefined
+ ? "—"
+ : qsTr("%1%").arg(Math.round(Number(value) / 255 * 100))
+ fullWidth: true
+
+ editableItem: ColumnLayout {
+ property alias value: brightnessSlider.value
+
+ Label {
+ Layout.fillWidth: true
+ text: qsTr("%1%").arg(Math.round(brightnessSlider.value / 255 * 100))
+ horizontalAlignment: Text.AlignHCenter
+ font.bold: true
+ }
+
+ Slider {
+ id: brightnessSlider
+ Layout.minimumWidth: 250
+ Layout.fillWidth: true
+ from: 0
+ to: 255
+ stepSize: 1
+ snapMode: Slider.SnapAlways
+ }
+
+ Text {
+ Layout.fillWidth: true
+ text: qsTr("Lower brightness is less distracting at night. Set it to zero to turn the ring off completely.")
+ wrapMode: Text.Wrap
+ color: "#5f6368"
+ }
+ }
+ }
+
+ SettingsSectionLabel {
+ visible: colorOptions().length > 0
+ text: qsTr("Status colors")
+ }
+
+ Text {
+ Layout.fillWidth: true
+ visible: colorOptions().length > 0
+ text: qsTr("Tap a charging state to choose the color used by the LED ring.")
+ wrapMode: Text.Wrap
+ color: "#5f6368"
+ }
+
+ Repeater {
+ model: colorOptions()
+
+ delegate: WhiteItemDelegate {
+ id: colorItem
+ required property var modelData
+
+ Layout.fillWidth: true
+ implicitHeight: colorContent.implicitHeight + 20
+ onClicked: editColor(modelData)
+
+ contentItem: RowLayout {
+ id: colorContent
+
+ Rectangle {
+ Layout.preferredWidth: 34
+ Layout.preferredHeight: 34
+ radius: 17
+ color: colorItem.modelData.value || "#000000"
+ border.color: "#5f6368"
+ border.width: 1
+ }
+
+ ColumnLayout {
+ Layout.fillWidth: true
+ spacing: 2
+
+ SettingsLabel {
+ Layout.fillWidth: true
+ text: colorItem.modelData.title
+ }
+
+ Text {
+ Layout.fillWidth: true
+ text: colorItem.modelData.description
+ wrapMode: Text.Wrap
+ color: "#5f6368"
+ }
+ }
+
+ Text {
+ text: normalizeColor(colorItem.modelData.value).toUpperCase()
+ color: "#5f6368"
+ }
+
+ Text {
+ text: ">"
+ }
+ }
+ }
+ }
+
+ BusyIndicator {
+ Layout.alignment: Qt.AlignHCenter
+ visible: colorSetter.pending
+ }
+
+ RequestStatusText {
+ Layout.fillWidth: true
+ request: colorSetter
+ }
+
+ SettingsSectionLabel {
+ visible: energySaving.exists || modeLedsWhileSaving.exists
+ text: qsTr("Energy saving")
+ }
+
+ GeneralOnOffSwitch {
+ apiKey: "lse"
+ visible: exists
+ text: checked ? qsTr("Energy saving on") : qsTr("Energy saving off")
+ }
+
+ Text {
+ Layout.fillWidth: true
+ visible: energySaving.exists
+ text: qsTr("Energy saving turns off status lighting when it is not needed. Charging and important warnings remain visible.")
+ wrapMode: Text.Wrap
+ color: "#5f6368"
+ }
+
+ GeneralOnOffSwitch {
+ apiKey: "mws"
+ visible: exists
+ text: qsTr("Keep mode indicators on")
+ }
+
+ Text {
+ Layout.fillWidth: true
+ visible: modeLedsWhileSaving.exists
+ text: qsTr("Keep the small charging-mode indicators visible while the LED ring is saving energy.")
+ wrapMode: Text.Wrap
+ color: "#5f6368"
+ }
+
+ SettingsSectionLabel {
+ visible: factoryDebug.exists || ledDebug.exists
+ text: qsTr("Service diagnostics")
+ }
+
+ Text {
+ Layout.fillWidth: true
+ visible: factoryDebug.exists || ledDebug.exists
+ text: qsTr("These service options can replace normal status animations. Leave them off unless you are diagnosing the LED hardware.")
+ wrapMode: Text.Wrap
+ color: "#5f6368"
+ }
+
+ GeneralOnOffSwitch {
+ apiKey: "fldb"
+ visible: exists
+ text: qsTr("Factory LED test")
+ }
+
+ GeneralOnOffSwitch {
+ apiKey: "ldb"
+ visible: exists
+ text: qsTr("LED diagnostics")
+ }
+
+ ColorDialog {
+ id: colorDialog
+ title: qsTr("Choose color for %1").arg(page.selectedColorName)
+ onAccepted: colorSetter.setValue(page.normalizeColor(selectedColor))
}
}
diff --git a/evcharger-app/qml/LedRingPreview.qml b/evcharger-app/qml/LedRingPreview.qml
new file mode 100644
index 0000000..56ef8a0
--- /dev/null
+++ b/evcharger-app/qml/LedRingPreview.qml
@@ -0,0 +1,224 @@
+pragma ComponentBehavior: Bound
+
+import QtQuick
+
+Item {
+ id: preview
+
+ property var animationData: null
+ property string previewMode: "live"
+ property color idleColor: "#0000ff"
+ property color waitingColor: "#ffff00"
+ property color chargingColor: "#00ffff"
+ property color finishedColor: "#00ff00"
+ property int configuredLedCount: 32
+ property int configuredBrightness: 255
+ property string statusText
+ property string detailText
+ property double animationTime: Date.now()
+
+ readonly property int actualLedCount: Math.max(1, Math.min(128, Number(configuredLedCount) || 32))
+ readonly property real ringDiameter: Math.min(width, height)
+ readonly property real ringRadius: ringDiameter * 0.39
+ readonly property real ledDiameter: Math.max(5, Math.min(14, ringDiameter * 1.55 / actualLedCount))
+
+ implicitWidth: 260
+ implicitHeight: 260
+
+ function normalizeIndex(index) {
+ let result = Math.floor(Number(index) || 0) % actualLedCount
+ if (result < 0)
+ result += actualLedCount
+ return result
+ }
+
+ function colorComponents(value) {
+ let text = String(value || "#000000")
+ if (text.length === 9)
+ text = "#" + text.substring(3)
+ if (!/^#[0-9a-fA-F]{6}$/.test(text))
+ text = "#000000"
+ return [
+ parseInt(text.substring(1, 3), 16) / 255,
+ parseInt(text.substring(3, 5), 16) / 255,
+ parseInt(text.substring(5, 7), 16) / 255
+ ]
+ }
+
+ function mixColor(first, second, amount) {
+ const left = colorComponents(first)
+ const right = colorComponents(second)
+ const factor = Math.max(0, Math.min(1, amount))
+ return Qt.rgba(left[0] + (right[0] - left[0]) * factor,
+ left[1] + (right[1] - left[1]) * factor,
+ left[2] + (right[2] - left[2]) * factor,
+ 1)
+ }
+
+ function scaleColor(value, intensity) {
+ const rgb = colorComponents(value)
+ const brightness = Math.max(0, Math.min(1, configuredBrightness / 255))
+ * Math.max(0, Math.min(1, intensity))
+ return Qt.rgba(rgb[0] * brightness, rgb[1] * brightness, rgb[2] * brightness, 1)
+ }
+
+ function durationMilliseconds(value) {
+ const text = String(value || "")
+ if (text.endsWith("ms"))
+ return Math.max(1, Number(text.substring(0, text.length - 2)) || 1)
+ if (text.endsWith("s"))
+ return Math.max(1, (Number(text.substring(0, text.length - 1)) || 1) * 1000)
+ return Math.max(1, Number(text) || 1000)
+ }
+
+ function rangePosition(index, from, to) {
+ const start = normalizeIndex(from)
+ const end = normalizeIndex(to)
+ let current = start
+ for (let offset = 0; offset < actualLedCount; ++offset) {
+ if (current === index)
+ return offset
+ if (current === end)
+ break
+ current = (current + 1) % actualLedCount
+ }
+ return -1
+ }
+
+ function repeatingColor(colors, position) {
+ if (colors === null || colors === undefined || colors.length < 1)
+ return "#000000"
+ return colors[position % colors.length]
+ }
+
+ function renderCommandColor(index, data) {
+ let result = "#000000"
+ const ranges = data && data.ranges ? data.ranges : []
+ for (let rangeIndex = 0; rangeIndex < ranges.length; ++rangeIndex) {
+ const range = ranges[rangeIndex]
+ const position = rangePosition(index, range.from, range.to)
+ if (position < 0)
+ continue
+
+ if (range.blink !== null && range.blink !== undefined) {
+ const duration = durationMilliseconds(range.blink)
+ const secondColor = Math.floor(animationTime / (duration / 2)) % 2 === 1
+ result = repeatingColor(secondColor ? range.colors1 : range.colors0, position)
+ } else if (range.fade !== null && range.fade !== undefined) {
+ const duration = durationMilliseconds(range.fade)
+ const progress = (animationTime % duration) / duration
+ const amount = (1 - Math.cos(progress * Math.PI * 2)) / 2
+ result = mixColor(repeatingColor(range.colors0, position),
+ repeatingColor(range.colors1, position), amount)
+ } else {
+ result = repeatingColor(range.colors, position)
+ }
+ }
+ return scaleColor(result, 1)
+ }
+
+ function tailColor(index, data) {
+ const count = Math.max(1, Math.min(3, Number(data.count) || 1))
+ const speed = Math.max(1, Number(data.speed) || 20)
+ const ampere = Math.max(0, Math.min(32, 35 - speed))
+ const tailLength = Math.max(0.1, Math.min(0.94, (ampere + 3) / 35))
+ const rotation = (animationTime / (speed * 256)) % 1
+ let distance = ((index / actualLedCount) * count - rotation * count) % 1
+ if (distance < 0)
+ distance += 1
+ const intensity = distance <= tailLength ? 1 - distance / tailLength : 0
+ return scaleColor(chargingColor, Math.pow(intensity, 1.45))
+ }
+
+ function effectiveAnimation() {
+ switch (previewMode) {
+ case "idle": return {subtype: "solid", color: idleColor}
+ case "waiting": return {subtype: "solid", color: waitingColor}
+ case "charging": return {subtype: "schweif", count: 3, speed: 14}
+ case "finished": return {subtype: "solid", color: finishedColor}
+ default: return animationData || {subtype: "solid", color: "#303030"}
+ }
+ }
+
+ function ledColor(index) {
+ const data = effectiveAnimation()
+ switch (data.subtype) {
+ case "solid":
+ return scaleColor(data.color, 1)
+ case "rainbow":
+ return scaleColor(Qt.hsva(index / actualLedCount, 0.94, 1, 1), 1)
+ case "schweif":
+ return tailColor(index, data)
+ case "colors":
+ return scaleColor(repeatingColor(data.colors, index), 1)
+ case "renderCmds":
+ return renderCommandColor(index, data)
+ default:
+ return scaleColor("#303030", 1)
+ }
+ }
+
+ Timer {
+ interval: 40
+ repeat: true
+ running: preview.visible
+ onTriggered: preview.animationTime = Date.now()
+ }
+
+ Rectangle {
+ anchors.centerIn: parent
+ width: preview.ringDiameter * 0.64
+ height: width
+ radius: width / 2
+ color: "#202124"
+ border.color: "#44474a"
+ border.width: 2
+
+ Column {
+ anchors.centerIn: parent
+ width: parent.width * 0.78
+ spacing: 3
+
+ Text {
+ width: parent.width
+ text: preview.statusText
+ color: "white"
+ font.bold: true
+ horizontalAlignment: Text.AlignHCenter
+ wrapMode: Text.Wrap
+ }
+
+ Text {
+ width: parent.width
+ text: preview.detailText
+ visible: text.length > 0
+ color: "#bdc1c6"
+ font.pixelSize: 12
+ horizontalAlignment: Text.AlignHCenter
+ wrapMode: Text.Wrap
+ }
+ }
+ }
+
+ Repeater {
+ model: preview.actualLedCount
+
+ delegate: Rectangle {
+ required property int index
+ readonly property real angle: index / preview.actualLedCount * Math.PI * 2
+
+ x: preview.width / 2 + Math.sin(angle) * preview.ringRadius - width / 2
+ y: preview.height / 2 - Math.cos(angle) * preview.ringRadius - height / 2
+ width: preview.ledDiameter
+ height: width
+ radius: width / 2
+ color: preview.ledColor(index)
+ border.color: "#5f6368"
+ border.width: 1
+
+ Behavior on color {
+ ColorAnimation { duration: 35 }
+ }
+ }
+ }
+}
diff --git a/evcharger-app/qml/qmldir b/evcharger-app/qml/qmldir
index f06a160..e9f182b 100644
--- a/evcharger-app/qml/qmldir
+++ b/evcharger-app/qml/qmldir
@@ -56,6 +56,7 @@ EVChargerApp 1.0 IndexedEditValueItem.qml
EVChargerApp 1.0 IndexedOnOffSwitch.qml
EVChargerApp 1.0 KwhLimitPage.qml
EVChargerApp 1.0 LedPage.qml
+EVChargerApp 1.0 LedRingPreview.qml
EVChargerApp 1.0 LicensesPage.qml
EVChargerApp 1.0 LoadBalancingPage.qml
EVChargerApp 1.0 LogicModeButton.qml