Skip to content

Commit 8ef2e5c

Browse files
authored
Zendure API (#7)
* Erster Test Daten von Zendure lesen * Zendure-Werte auf dem Dashboard darstellen. Akku Ladung/Entladung berechnen. * Zenduredaten konfigurable, Anleitung erweitert * Zendure: - Akkustandsanzeige - Ladezeit der Statusseiten optimiert Bugfixes: - Falscher Einkaufswert in den Übersichtsseiten in der obersten Zeile - Richtige Kurzschreibweise Monat März * Zendure: Darstellung und Logmeldungen verbessert * Zendure simple Stats * Bugfix: Berechnung Einspeisung + Ersparnis Energietabelle: Ersparnis in 1. Spalte * Readme angepasst, kleine Anpassungen
1 parent 0736a7e commit 8ef2e5c

36 files changed

Lines changed: 1427 additions & 252 deletions

README.md

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
<img src="./images/gallery/dashboard_mobile.png" alt="Mobile Dashboardansicht" width="250">
66

7+
<img src="./images/gallery/hours-overview_mobile.png" alt="Mobile Stundenübersicht" width="250">
8+
79
Zur Bildergallerie [gallery.md](gallery.md)
810

911
## Beschreibung
@@ -17,7 +19,7 @@ Der Benutzer muss einen eigenen PHP- und MySQL-Provider anmieten / bereitstellen
1719

1820
### Zielsetzung
1921

20-
Das Projekt richtet sich an technisch erfahrene Benutzer, die ihren privaten Echtzeit-Energieverbrauch und/oder ihre private Echtzeit-Stromerzeugung durch PV-Anlagen, Balkonkraftwerke oder andere Energieerzeuger im Detail analysieren möchten. Die Software kann mobil auf dem Handy als auch auf dem PC benutzt werden.
22+
Das Projekt richtet sich an technisch erfahrene Benutzer, die ihren privaten Echtzeit-Energieverbrauch und/oder ihre private Echtzeit-Stromerzeugung durch PV-Anlagen, Balkonkraftwerke, Akkusysteme oder andere Energieerzeuger in der eigenen Datenbank speichern möchten. Es werden umfangreiche Analyseansichten angeboten, wie z.B. eine nahezu Echtzeitübersicht, eine Eigenverbrauchsquote oder eine Autarkieansicht jeweils für Stunden, Tage, Monate oder Jahre. Die Software kann mobil auf dem Handy als auch auf dem PC benutzt werden.
2123

2224
Beispielsweise können Stromspitzen in Echtzeit erkannt und mithilfe von zwei Berechnungslinien analysiert werden. Dies ermöglicht es, den Energieverbrauch oberhalb, unterhalb oder zwischen den definierten Linien zu ermitteln.
2325

@@ -56,7 +58,8 @@ In der Datenbank ist pro Zeitabschnitt ein Wert für Verbrauchsdaten vorgesehen,
5658
- **Netzeinspeisung**: Definiert die überschüssige erzeugte Energie, die nicht selbst verbraucht wird.
5759

5860
### Echtzeitdaten und Daten-Logger
59-
Die Echtzeitdaten und Stundenübersicht sind nur in Verbindung mit Echtzeitdaten sinnvoll nutzbar. Gleiches gilt für die Tagesansicht, da man in der Regel nur Werte für einen ganzen Monat manuell eingibt.
61+
Die Echtzeitdaten und Stundenübersicht sind nur in Verbindung mit Echtzeitdaten sinnvoll nutzbar. Gleiches gilt für die Tagesansicht, da man in der Regel nur Werte für einen ganzen Monat manuell eingibt. Es handelt sich hierbei um eine nahezu Echtzeitanzeige, d.h. es tritt immer eine geringe Verzögerung im Sekundenbereich auf.
62+
6063
Für das Datenlogging der Echtzeitdaten gibt es eine API, die diese entgegennimmt und in die Datenbank speichert. Dieses Projekt enthält Skripte für die Shelly-Energiemesssensoren. Bitte unbedingt die Sicherheitshinweise beachten, falls Sensoren genutzt werden, die in die Elektroinstallation eingebaut werden.
6164
Die API kann auch mit anderen Energiedaten bedient werden, man kann sich also auch ein Skript für andere Geräte programmieren.
6265

@@ -78,6 +81,10 @@ Preisdaten können ebenfalls manuell für mehrere Zeiträume eingegeben werden.
7881
### Status fehlender Werte
7982
Hier wird ein Status angezeigt, der einen Überblick über die Datenabdeckung gibt und die Möglichkeit bietet, fehlende Daten manuell nachzupflegen. Falls bei der Berechnung der Echtzeitdaten ein Fehler beim Cronjob aufgetreten ist, kann der Monat manuell nachberechnet werden. Fehlen allerdings die Echtzeitdaten vollständig, bleibt die Lücke bestehen.
8083

84+
### Zendure (Hyper 2000 System)
85+
Es können Daten von dem Zendure System zusätzlich mit angezeigt werden. Derzeit ist es nur mit dem Hyper 2000 System getestet, da keine spezifischen Hyper 2000 Werte benutzt werden, sollten auch die anderen Zendure Systeme funktionieren.
86+
Die Daten werden von der offiziellen Zendure-API aus deren Cloud ausgelesen.
87+
8188
## Lizenz
8289

8390
Dieses Projekt ist unter der [GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.html) lizenziert. Sie dürfen es verwenden, modifizieren und weitergeben, solange alle Kopien und abgeleiteten Werke ebenfalls unter dieser Lizenz stehen.
@@ -117,6 +124,14 @@ Das Projekt nutzt folgende Open-Source-Bibliotheken:
117124
7. **Bootstrap Icons** - [Bootstrap Icons](https://icons.getbootstrap.com/)
118125
- **Funktion**: Sammlung von Icons für die Verwendung in Bootstrap-basierten Webseiten.
119126

127+
8. **Bluerhinos phpmqtt** - [Bluerhinos phpmqtt](https://github.com/bluerhinos/phpMQTT/)
128+
- **Funktion**: Optional Bluerhinos phpmqtt Bibliothek, derzeit für die Zendure Anbindung.
129+
130+
9. **Zendure API** - [Zendure API](https://github.com/Zendure/developer-device-data-report)
131+
- **Funktion**: Optional, falls ein Zendure Akkusystem benutzt wird, um die Daten aus der Zendure API zu lesen.
132+
133+
134+
120135
## Shelly-Geräte und Skripte
121136

122137
### Verwendung von Shelly-Geräten und -Skripten
@@ -142,3 +157,9 @@ Ebenso wird keine Haftung für die erfassten Daten, deren Speicherung oder deren
142157
Darüber hinaus wird keine Verantwortung für etwaige Datenverluste, Abwärtskompatibilitätsprobleme (z. B. nach einem Update) oder andere technische Probleme übernommen. Es wird ausdrücklich empfohlen, regelmäßig ein Backup der Datenbank zu erstellen, um den Verlust wichtiger Informationen zu vermeiden.
143158

144159
**Wichtiger Hinweis**: Die Geräte und Skripte dürfen nur in Übereinstimmung mit den geltenden gesetzlichen Bestimmungen und Sicherheitsvorgaben genutzt werden.
160+
161+
## Zendure Geräte und API (Optional)
162+
163+
### Auslesen von PV Ertrag sowie Akkudaten
164+
165+
Falls entsprechend konfiguriert, wird die Zendure-API benutzt um den Erzeugten PV-Ertrag und den aktuellen Akkustand auszulesen. Aktuell nur mit dem Hyper 2000 System getestet.

api/get-dashboard-data.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44

55
include_once("lib/appLibLoader.php");
66

7-
//ApiHelper::assertApiKeyIsCorrect(isset($_REQUEST["apikey"]) ? $_REQUEST["apikey"] : "");
7+
#ApiHelper::assertApiKeyIsCorrect(isset($_REQUEST["apikey"]) ? $_REQUEST["apikey"] : "");
88

99
$actualConfig = Configuration::getInstance()->monthsOverview();
1010

1111
$dashboardService = new DashboardService();
1212
$dashboardService->prepareInstantData();
13-
$jsondData = $dashboardService->getInstantDataAsJson();
13+
$jsonData = $dashboardService->getInstantDataAsJson();
1414

15-
ApiHelper::dieWithJsonResponse($jsondData);
15+
ApiHelper::dieWithJsonResponse($jsonData);

api/get-hasAlert.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
include_once("lib/appLibLoader.php");
66

7-
//ApiHelper::assertApiKeyIsCorrect(isset($_REQUEST["apikey"]) ? $_REQUEST["apikey"] : "");
7+
#ApiHelper::assertApiKeyIsCorrect(isset($_REQUEST["apikey"]) ? $_REQUEST["apikey"] : "");
88
$hasAlert = TaskService::hasAlertStatus();
99
$jsondData = json_encode(["hasAlert" => $hasAlert]);
1010

api/taskrunner.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111

1212
TaskService::checkRealtimeEnergyData();
1313

14+
if ($currentMinute % 1 === 0) {
15+
// Every minute
16+
TaskService::readZendureData();
17+
}
18+
1419
if ($currentMinute % 5 === 0) {
1520
// Every 5 minutes
1621
TaskService::unifyRealTimeData();

config/local-config.php.sample

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ define('SYSTEM_EMAIL', 'mail@example.org'); // Mailempfänger für Systemnachri
2525
$config = Configuration::getInstance();
2626

2727
// Konfiguriert, den Alarmstatus, falls keine Daten geloggt werden.
28-
$config->configRealtimeAlert()->setSendAlertMail(true);
29-
$config->configRealtimeAlert()->setAlertThresholdInMinutes(5); // Wenn x Minuten keine Einträge gefunden werden, wird ein Mail und ein Hinweis in der Navigation gezeigt, solange das Problem besteht.
30-
$config->configRealtimeAlert()->setSendAlertMailEveryXMinutes(30); // Die Mail wird alle x Minuten erneut gesendet, solange das Problem besteht.
31-
$config->configRealtimeAlert()->setShouldAlertForEnergyType(EnergyTypeEnum::EM, true); // Welche Kanäle überwacht werden
32-
$config->configRealtimeAlert()->setShouldAlertForEnergyType(EnergyTypeEnum::PM1, true);
33-
$config->configRealtimeAlert()->setShouldAlertForEnergyType(EnergyTypeEnum::PM3, true);
28+
$config->realtimeAlert()->setSendAlertMail(true);
29+
$config->realtimeAlert()->setAlertThresholdInMinutes(5); // Wenn x Minuten keine Einträge gefunden werden, wird ein Mail und ein Hinweis in der Navigation gezeigt, solange das Problem besteht.
30+
$config->realtimeAlert()->setSendAlertMailEveryXMinutes(30); // Die Mail wird alle x Minuten erneut gesendet, solange das Problem besteht.
31+
$config->realtimeAlert()->setShouldAlertForEnergyType(EnergyTypeEnum::EM, true); // Welche Kanäle überwacht werden
32+
$config->realtimeAlert()->setShouldAlertForEnergyType(EnergyTypeEnum::PM1, true);
33+
$config->realtimeAlert()->setShouldAlertForEnergyType(EnergyTypeEnum::PM3, true);
3434

3535
// Konfiguriert einige Werte auf der Energy-Chart-Seite
3636
// Es gibt jeweils 2 Energiesets, welche Energie1 und Energie2 heißen und einzeln konfiguriert werden können.
@@ -80,4 +80,17 @@ $config->hoursOverview()->configEnergy1()->setTablePageLength(10);
8080
// Die Echtzeitübersichtsseite hat zusätzlich folgende Optionen, es sind nicht alle Optionen der Übersichtsseite benutzbar
8181
$config->realtimeOverview()->setPastPeriodPossibilities([0.5, 1, 2, 4, 6, 8, 12, 24, 24*7, 24*14, 24*28]);
8282
$config->realtimeOverview()->setRefreshIntervalInSec(5);
83+
84+
// Zendure
85+
$config->zendure()->setAppKey("DeinAppKey"); // Der AppKey, siehe Installationsanleitung
86+
$config->zendure()->setAppSecret("DeinAppSecret"); // Das AppSecret, siehe Installationsanleitung
87+
$config->zendure()->setReadTimeInSec(60); // Wie lange ein Request die Zendure Nachrichten abfragt, hängt vom Timeout des Webservers ab.
88+
$config->zendure()->setDisplayName("Akku"); // Name auf dem Dashboard
89+
$config->zendure()->setConnectedToPmPort("PM3"); // An welcher Phase der Zendure angeschlossen ist. Kann auch in der Echtzeitübersicht erkannt werden
90+
$config->zendure()->setCalculatePackData(true); // Wenn Zendure im Smart Mode, also mit Nulleinspeisung betrieben wird, bekommt man schnellere ungefähr Werte, wenn der Akku berechnet wird.
91+
92+
$config->dashboardPage()->setShowZendureOnDashboard(false); // Falls ein Zendure-System benutzt wird, das die Werte auf dem Dashboard angezeigt werden
93+
$config->dashboardPage()->setConsumptionIndicatedAs100Percent(6000); // Max. Wert für 100% Hausverbrauch, z.B. 6000W
94+
$config->dashboardPage()->setMaxEnergyProduction(1600); // Max. Wert für Energieproduktion, z.B. 1600W PV-Panel Leistung
95+
8396
?>

css/allPages.css

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ body {
100100
--autarky-color2: rgba(97, 141, 141, 0.6);
101101
--self-consumption-color: rgba(127, 181, 181, 0.3);
102102
--self-consumption-color2: rgba(97, 141, 141, 0.3);
103+
--akku-red-color: rgba(233, 115, 115, 0.8);
104+
--akku-orange-color: rgba(239, 180, 120, 0.8);
105+
--akku-yellow-color: rgba(240, 210, 130, 0.8);
106+
--akku-green-color: rgba(145, 195, 165, 0.8);
107+
--akku-greenfull-color: rgba(102, 179, 102, 0.8);
103108
}
104109

105110
.em-color {
@@ -181,3 +186,23 @@ body {
181186
.self-consumption-color2 {
182187
background-color: var(--self-consumption-color2);
183188
}
189+
190+
.akku-red-color {
191+
background-color: var(--akku-red-color);
192+
}
193+
194+
.akku-orange-color {
195+
background-color: var(--akku-orange-color);
196+
}
197+
198+
.akku-yellow-color {
199+
background-color: var(--akku-yellow-color);
200+
}
201+
202+
.akku-green-color {
203+
background-color: var(--akku-green-color);
204+
}
205+
206+
.akku-greenfull-color {
207+
background-color: var(--akku-greenfull-color);
208+
}

css/dashboardPage.css

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,27 @@
5050
position: relative;
5151
}
5252

53-
.progress-bar-1 {
53+
.progress-bar-house {
5454
height: 100%;
5555
width: 0%;
5656
transition: width 1.5s ease-in-out;
5757
background: linear-gradient(90deg, var(--em-over-zero-color), var(--em-over-zero-color));
5858
}
5959

60-
.progress-bar-2 {
60+
.progress-bar-production {
6161
height: 100%;
6262
width: 0%;
6363
transition: width 1.5s ease-in-out;
6464
background: linear-gradient(90deg, var(--pm-total-color), var(--pm-total-color));
6565
}
6666

67+
.progress-bar-akkupack {
68+
height: 100%;
69+
width: 0%;
70+
transition: width 1.5s ease-in-out;
71+
background: var(--akku-orange-color)
72+
}
73+
6774
.table-custom th,
6875
.table-custom td {
6976
text-align: center;

dashboard.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
include_once("lib/appLibLoader.php");
66

77
// Defaults
8-
$actualConfig = Configuration::getInstance()->configDashboardPage();;
8+
$actualConfig = Configuration::getInstance()->dashboardPage();;
99
$dashboardsServce = new DashboardService();
1010
$dashboardsServce->prepareStaticData();
1111
$overviewPageService = new OverviewPageService();

install.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,47 @@ AuthName "Bitte Anmelden"
144144
AuthUserFile /www/htdocs/[pfad]/[zum]/[projekt]/.htpasswd
145145
Require valid-user
146146
```
147+
## Zendure (optional, rudimentär)
148+
149+
Es kann der aktuelle Wert der PV Stromgenerierung und der Akkustand aus dem Zendure-System ausgelesen und mit angezeigt werden. Die Werte werden dann außerdem auf dem Dashboard auch für die Anzeige der gesamten Energieproduktion berücksichtigt. Dies zeigt dann auch die PV-Energie an, welche für das Laden des Akkus verwendet wird.
150+
Die Werte werden über die API ausgelesen und in der DB zwischengespeichert.
151+
152+
Beim Lesen der Zendure-Werte kann es zu geringfügigen Datenverlusten, insbesondere bei der aktuellen PV-Leistung kommen, wodurch ggfls. die Echtzeitanzeige etwas verfälscht ist. Die Akkudaten können auch berechnet werden, weil die API die Akkudaten nur ~ alle Minute sendet und im Smart-Modus dann nur ein Indiz sind.
153+
154+
Hintergrund: Das Auslesen erfolgt per einzelne Requests durch den TaskManager welcher dann einen gewissen Zeitraum läuft, da auf dem Webserver kein dauerhafter Prozess laufen kann. Dies ist nicht so, wie das MQQT-Protokoll es vorsieht, funktioniert aber auch. Deshalb ist das Feature als rudimentär gekennzeichnet.
155+
156+
Um ein Zendure-System anzubinden, sind folgende Schritt notwendig:
157+
158+
1. AppKey und AppSecret für die Zendure API besorgen
159+
Als Vorbereitung muss man die Seriennummer aus der Zendure-App im Einstellungsbereich auslesen.
160+
Mit der Seriennummer und die E-Mail, mit welcher man sich registriert hat setzt man folgenden Befehl ab, um die Zugangsdaten zu erhalten:
161+
- Eingabeaufforderung (cmd) öffnen
162+
- Die Werte in diesem Befehl entsprechend ersetzen und abschicken:
163+
- Nicht empfohlen: Bei Zertifikatsfehlermeldung am Ende --insecure anhängen.
164+
165+
```
166+
curl -i --json "{'snNumber': '<deine Seriennummer>', 'account': '<dein Account>'}" https://app.zendure.tech/eu/developer/api/apply
167+
168+
```
169+
170+
Als Ergebnis erhält man ein JSON, das so aussieht:
171+
```
172+
{"code":200,"success":true,"data":{"appKey":"DeinAppKey","secret":"DeinAppSecret","mqttUrl":"mqtt.zen-iot.com","port":1883},"msg":"Successful operation"}
173+
```
174+
175+
Die Werte von DeinAppKey + DeinAppSecret werden in der local-config.php eingetragen.
176+
Folgende Einstellungen können für Zendure vorgenommen werden:
177+
178+
```
179+
// Zendure
180+
$config->zendure()->setAppKey("DeinAppKey"); // Der oben gelesene AppKey
181+
$config->zendure()->setAppSecret("DeinAppSecret"); // Das oben gelesene AppSecret
182+
$config->zendure()->setReadTimeInSec(60); // Wie lange ein Request die Zendure Nachrichten abfragt, hängt vom Timeout des Webservers ab.
183+
$config->zendure()->setDisplayName("Akku"); // Name auf dem Dashboard
184+
$config->zendure()->setConnectedToPmPort("PM3"); // An welcher Phase der Zendure angeschlossen ist. Kann auch in der Echtzeitübersicht erkannt werden
185+
$config->zendure()->setCalculatePackData(true); // Wenn Zendure im Smart Mode, also mit Nulleinspeisung betrieben wird, bekommt man schnellere ungefähre Werte, wenn der Akku berechnet wird.
186+
187+
$config->dashboardPage()->setShowZendureOnDashboard(true); // Falls ein Zendure-System benutzt wird, das die Werte auf dem Dashboard angezeigt werden
188+
$config->dashboardPage()->setConsumptionIndicatedAs100Percent(6000); // Max. Wert für 100% Hausverbrauch, z.B. 6000W
189+
$config->dashboardPage()->setMaxEnergyProduction(1600); // Max. Wert für Energieproduktion, z.B. 1600W PV-Panel Leistung
190+
```

js/dashboard/documentReady.js

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,6 @@
33

44
$(document).ready(function() {
55

6-
function prepareCircle(id, color) {
7-
return new ProgressBar.Circle(id, {
8-
color: color,
9-
strokeWidth: 10,
10-
trailColor: '#e0e0e0',
11-
duration: 500,
12-
easing: 'easeInOut',
13-
text: {
14-
value: '0%',
15-
className: 'progress-text'
16-
},
17-
step: function(state, bar) {
18-
bar.setText(Math.round(bar.value() * 100) + '%');
19-
}
20-
});
21-
}
22-
236
// Prepare Cirlce for now
247
var autarkyColorRGB = autarkyColor.replace(/rgba?\(([^,]+),([^,]+),([^,]+),?.*\)/, 'rgb($1,$2,$3)'); // Extracts RGB-Part from RGBA
258
var circleNow = prepareCircle('#circle-now', autarkyColorRGB);
@@ -56,13 +39,22 @@ $(document).ready(function() {
5639
circleNow.animate(response.now.autInPct / 100);
5740
circleToday.animate(response.today.autInPct / 100);
5841

42+
// Bar 1 (Hausdaten)
5943
$("#em-now-bar").css("width", (response.now.emPercent) + "%");
6044
$("#em-now-bar").css("background", response.now.em > 0 ? emOverZeroColor : feedInColor);
6145
$('#now-em-caption').html(response.now.em > 0 ? "Einkauf" : "Einspeisung");
62-
$("#pm-now-bar").css("width", (response.now.pmPercent) + "%");
6346

64-
// set zero feed in active
65-
$('#zeroFeedInActive').toggle(response.now.isZeroFeedInActive);
47+
// Bar 2 (Produktionsdaten)
48+
$("#pm-now-bar").css("width", (response.now.productionPercent) + "%");
49+
$('#zeroFeedInActive').toggle(response.now.isZeroFeedInActive); // Set zero feed in active msg
50+
51+
// Bar 3 (Zendure Batteriedaten)
52+
$("#pm-pack-bar").css("width", (response.zendure.akkuPackLevelPercent) + "%");
53+
$("#pm-pack-bar").css("background-color", "var(--" + getAkkuColor(response.zendure.akkuPackLevelPercent) + ")");
54+
$('#zendure-chargeActive').toggle(response.zendure.isZendureChargeActive);
55+
$('#zendure-dischargeActive').toggle(response.zendure.isZendureDischargeActive);
56+
$('#zendure-dataloss').toggle(response.zendure.isDataloss);
57+
$('#zendure-akkuPackLevelPercent').toggle(!response.zendure.isDataloss);
6658

6759
},
6860

@@ -72,20 +64,45 @@ $(document).ready(function() {
7264
});
7365
}
7466

75-
// Initialer Aufruf
67+
// Initial call + intervall
7668
fetchDashboardData();
77-
78-
// Wiederhole den Abruf alle 1 Sekunden
7969
setInterval(fetchDashboardData, 2000);
8070

71+
// Format helper
8172
function formatJsValue(category, key, value) {
8273
if (key.toLowerCase().includes("price")) {
8374
return formatPrice(value);
84-
}
85-
if (category.toLowerCase().includes("now")) {
75+
} else if (category.toLowerCase().includes("now")) {
8676
return formatCurrent(value);
77+
} else if (key.toLowerCase().includes("percent")) {
78+
return formatNumber(value, 0) + "%";
8779
}
8880

8981
return formatCurrent(value, "h");
9082
}
83+
84+
// Prepare circle
85+
function prepareCircle(id, color) {
86+
return new ProgressBar.Circle(id, {
87+
color: color,
88+
strokeWidth: 10,
89+
trailColor: '#e0e0e0',
90+
duration: 500,
91+
easing: 'easeInOut',
92+
text: {
93+
value: '0%',
94+
className: 'progress-text'
95+
},
96+
step: function(state, bar) {
97+
bar.setText(Math.round(bar.value() * 100) + '%');
98+
}
99+
});
100+
}
101+
102+
function getAkkuColor(stateInPercent) {
103+
if (stateInPercent < 9) return "akku-red-color";
104+
if (stateInPercent >= 9 && stateInPercent < 25) return "akku-orange-color";
105+
if (stateInPercent >= 25 && stateInPercent < 85) return "akku-green-color";
106+
if (stateInPercent >= 85) return "akku-greenfull-color";
107+
}
91108
});

0 commit comments

Comments
 (0)