Dieser Artikel wurde zuletzt am 01.01.2021 um 18:51 Uhr aktualisiert
Hinweis: für dieses Skript steht ein Update zur Verfügung!
In der Shelly Cloud App für iOS oder Android sieht man natürlich immer auf einen Blick, wie der Verbrauch der einzelnen oder aller Shelly ist.
Was ist aber, wenn man diese Daten auch gerne Offline zur weiteren Verarbeitung speichern möchte?
Hier stößt man leider schnell auf ein Problem, das der Verbrauch des Shelly zwar abgelesen werden kann – jedoch nur der Verbrauch seit dem letzten Neustart.
Somit würde sich der Verbrauch immer verändern, wenn der Shelly aufgrund von Stromausfall oder Software-Update neugestartet wurde.
Hierzu habe ich mir lange Gedanken gemacht und ein Skript entwickelt, welches die Werte aus den einzelnen Shelly in einer einstellbaren Zeit abfragt und in eigene Datenpunkte speichert. Auch ist eine Korrektur von Reboot Werten vorhanden. Somit werden die Zähler der temporären Berechnung genullt, sobald festgestellt wurde, das der Shelly neu gestartet wurde. Dies hat keinen Einfluss auf die gesamte Berechnung des Verbrauchs – im Gegenteil: Die Berechnung des Verbrauchs wird genauer!
Übersicht der Funktionen
Folgende Verbrauchswerte stehen in der Historie für jeden der Shelly zur Verfügung:
Funktion | Beschreibung |
---|---|
Verbrauch heute | abgefragter Verbrauch heute |
Verbrauch gestern | abgefragter Verbrauch gestern |
Verbrauch diese Woche | abgefragter Verbrauch für die gesamte Woche |
Verbrauch letzte Woche | abgefragter Verbrauch für die gesamte letzte Woche |
Verbrauch dieser Monat | abgefragter Verbrauch für den gesamten Monat |
Verbrauch letzter Monat | abgefragter Verbrauch für den gesamten letzten Monat |
Verbrauch dieses Jahr | abgefragter Verbrauch für das gesamte Jahr |
Verbrauch letztes Jahr | abgefragter Verbrauch für das gesamte letzte Jahr |
Verbrauch Gesamt | abgefragter Verbrauch gesamt |
Name | Zugewiesener Name des Shelly zum einfachen Wiederfinden |
Screenshot der verfügbaren Variablen

Installation des Shelly Adapter

Nach kurzer Zeit stehen die Datenpunkte aller gefundenen Shellys unter shelly.0
zur Verfügung.
Skript
/* * @copyright 2020 Stephan Kreyenborg <stephan@kreyenborg.koeln> * * @author 2020 Stephan Kreyenborg <stephan@kreyenborg.koeln> * * Dieses Skript dient zur freien Verwendung in ioBroker zur Verbrauchserfassung der Shelly Geräte. * Jegliche Verantwortung liegt beim Benutzer. Das Skript wurde unter Berücksichtigung der bestmöglichen Nutzung * und Performance entwickelt. * Der Entwickler versichert, das keine böswilligen Systemeingriffe im originalen Skript vorhanden sind. * * Sollte das Skript wider erwarten nicht korrekt funktionieren, so hast Du jederzeit die Möglichkeit, Dich auf * https://www.kreyenborg.koeln * für Unterstützung zu melden. Jedes Skript besitzt seine eigene Kommentarseite, auf der, * nach zeitlicher Möglichkeit des Autors, Hilfe angeboten wird. Ein Anrecht hierauf besteht nicht! * * Ansprüche gegenüber Dritten bestehen nicht. * * Skript Name: Shelly-Verbrauch * Skript Version: 1.21 * Erstell-Datum: 01. Januar 2021 * */ // Datenpunkte neu erstellen var ueberschreiben = false; // Hauptdatenpunkt unterhalb javascript var datenpunkt = "ShellyVerbrauch."; // Verbrauchs Objekte der einzelnen Shelly const objekt = ["gesamt", "dieses_jahr", "letztes_jahr", "letzter_monat", "dieser_monat", "letzte_woche", "diese_woche", "gestern", "heute", "alter_wert", "aktueller_wert"]; // Beschreibung der Objekte const beschreibung = ["Gesamter Vebrauch des Shelly", "Verbrauch aktuelles Jahr", "Verbrauch letztes Jahr", "Verbrauch letzten Monat", "Verbrauch aktueller Monat", "Verbrauch letzte Woche", "Verbrauch diese Woche", "Verbrauch gestern", "Verbrauch heute", "Messwert alt", "Messwert neu"]; // Datenpunkt der Shelly (Standard: shelly.0) var shelly_dp = "shelly.0"; // Datenpunkte der Shelly (!!! Bitte nicht ändern !!!) const shellyDps = $('state[id=' + shelly_dp + '.*.*.Energy]'); // Datenpunkte der Shelly Namen (!!! Bitte nicht ändern !!!) const shellyDpsName = $('state[id=' + shelly_dp + '.*.name]'); // Shelly Verbrauch aktualisieren - nachts um 00:00 Uhr function shelly_vebrauch_tag() { // Nochmals das Tagesupdate durchlaufen, damit die restlichen Werte gelesen werden shelly_verbrauch_update(); // Datumsvariable var heute = new Date(); // Heute zu Gestern verschieben. Täglich um 00:00 Uhr verschiebe_verbrauch_objekt("heute", "gestern"); log ("Shelly Verbrauch: Werte für gestern und heute aktualisiert!"); // aktuelle Woche in letzte Woche verschieben. Am Montag um 00:00 Uhr if (heute.getDay() === 1) { verschiebe_verbrauch_objekt("diese_woche", "letzte_woche"); log ("Shelly Verbrauch: Werte für diese und letzte Woche aktualisiert!"); } // aktueller Monat in letzten Monat verschieben. Am 1. des Monats um 00:00 Uhr if (heute.getDate() === 1) { verschiebe_verbrauch_objekt("dieser_monat", "letzter_monat"); log ("Shelly Verbrauch: Werte für diesen und letzten Monat aktualisiert!"); } // aktuelles Jahr in letztes Jahr verschieben. Am 1. des Monats am 1. Monat um 00:00 Uhr if (heute.getDate() === 1 && heute.getMonth() === 0) { verschiebe_verbrauch_objekt("dieses_jahr", "letztes_jahr"); log ("Shelly Verbrauch: Werte für dieses und letztes Jahr aktualisiert!"); } } // Tagesverbrauch alle 15 Min von der Original Variable des Shelly in eigene Variable kopieren function shelly_verbrauch_update() { var anzahl_updates = 0; var anzahl_reboots = 0; var anzahl_gleich = 0; shellyDps.each(function (id, i) { var shelly_verbrauch = getState(id).val; // Einige Shelly haben keine Verbrauchswerte (noch nicht) if (shelly_verbrauch != null) { // Hole aktuellen Wert, um zu kontrollieren, ob ein Reboot stattgefunden hat var aktueller_wert = getState(shelly_DP(id) + "aktueller_wert").val; var alter_wert = 0; // Prüfe alten und neuen Wert if (shelly_verbrauch > aktueller_wert) { // Verbrauchswert ist größer als alter Wert -> es wurde kein Reboot durchgeführt setState(shelly_DP(id) + "alter_wert", aktueller_wert); alter_wert = aktueller_wert; anzahl_updates++; } if (aktueller_wert > shelly_verbrauch) { // Verbrauchswert ist kleiner als alter Wert -> es wurde ein Reboot durchgeführt setState(shelly_DP(id) + "alter_wert", 0); alter_wert = 0; anzahl_reboots++; } if (shelly_verbrauch == aktueller_wert) { // Verbrauchswert ist gleich wie alter Wert -> kein Update notwendig alter_wert = aktueller_wert; anzahl_gleich++; } setState(shelly_DP(id) + "aktueller_wert", shelly_verbrauch); // Alter und neuer Wert -> aktuelle Differenz var verbrauch = (parseFloat(shelly_verbrauch) - parseFloat(alter_wert)); // Tagesverbrauch aktualisieren aktualisiere_vebrauch_objekt(id, "heute", verbrauch); // Wochenverbrauch aktualisieren aktualisiere_vebrauch_objekt(id, "diese_woche", verbrauch); // Monatsverbrauch aktualisieren aktualisiere_vebrauch_objekt(id, "dieser_monat", verbrauch); // Jahresverbrauch aktualisieren aktualisiere_vebrauch_objekt(id, "dieses_jahr", verbrauch); // Gesamten Vebrauch aktualisieren aktualisiere_vebrauch_objekt(id, "gesamt", verbrauch); } }); aktualisiere_namen(); log("Shelly Verbrauch: Verbrauchswerte aktualisiert: " + anzahl_updates + " | Reboots korrigiert: " + anzahl_reboots + " | Unveränderte Werte: " + anzahl_gleich); } // aktualisiert das jeweilige Verbrauchs-Objekt und addiert den Verbrauch dazu function aktualisiere_vebrauch_objekt(dp, objekt, wert) { var verbrauch = parseFloat(getState(shelly_DP(dp) + objekt).val) + parseFloat(wert); verbrauch = parseFloat(verbrauch.toFixed(2)); setState(shelly_DP(dp) + objekt, verbrauch); } // Verschiebt das jeweilige Verbrauchs-Objekt und nullt den Ursprung (Tag, Woche, Monat, Jahr) function verschiebe_verbrauch_objekt(von, nach) { $('state[id=*.' + datenpunkt + '*.*.' + von + ']').each(function (id, i) { // Temporärer Gruppen-Datenpunkt var tmp_dp = id.slice(0, -(von.length)); var verbrauch = getState(id).val; if (verbrauch != null) { setState(tmp_dp + nach, verbrauch); } // Setze heute zurück setState(id, 0.0); }); } // Funktion um die aktuellen Namen des Shelly abzuholen function aktualisiere_namen() { shellyDpsName.each(function (id, i) { setState(shelly_DP_Name(id),String(getState(id).val)); }); } // Erstelle die benötigten Datenpunkte function datenpunkte_erstellen() { // Anzahl der gefundenen Shelly var anzahl = shellyDps.length; // Gesamt Anzahl der zu erstellenden Datenpunkte var gesamt = objekt.length * anzahl; shellyDps.each(function (id, j) { var initial_wert = 0; for (var i = 0; i < objekt.length; i++) { // Startwerte werden nur bei alter_wert und aktueller_wert eingetragen if (i > 8) { initial_wert = getState(id).val; } createState(shelly_DP(id) + objekt[i], initial_wert, ueberschreiben, { name: beschreibung[i], desc: beschreibung[i], type: "number", role: "value.power", unit: "Wh" }, function () { gesamt--; if (gesamt === 0) { // Alle Datenpunkte erstellt. Frage ersten Verbrauch ab! log("Shelly Verbrauch: Datenpunkte erstellt! Erster Verbrauch steht nach 1 Minute zur Verfügung!"); setTimeout(shelly_verbrauch_update, 60000); } }); } }); // Datenpunkte für die Namen der Shelly erstellen shellyDpsName.each(function(id, j) { createState(shelly_DP_Name(id), "", ueberschreiben, { name: "Name des Shelly", desc: "Name des Shelly", type: "string", role: "value", unit: "" }); }); } function shelly_DP(dp) { dp = dp.split("."); dp = datenpunkt + dp[2] + "." + dp[3] + "."; return dp; } function shelly_DP_Name(dp) { dp = dp.split("."); dp = datenpunkt + dp[2] + "." + dp[3]; return dp; } function shelly_verbrauch_erster_start() { log("Shelly Verbrauch: Erster Start des Skriptes! Datenpunkte werden erstellt!"); // Datenpunkte werden erstellt datenpunkte_erstellen(); } // Erster Start und Initialisierung shelly_verbrauch_erster_start(); // Alle 15 Minuten das Skript für den Tagesverbrauch ausführen schedule('*/15 * * * *', shelly_verbrauch_update); // Nachts um 24 Uhr werden die Werte in andere Variablen gespeichert, um den Verlauf zu erstellen schedule('0 0 * * *', shelly_vebrauch_tag);
Datenpunkte
Nachdem das Skript angelaufen ist und regelmäßig die Verbräuche der Shelly abgefragt wurden, findest Du diese im Datenpunkt: javascript.0.ShellyVerbrauch
Neue Shelly eingebunden, das Skript liest die Daten nicht aus!
Solltest Du zur Laufzeit des Skripts neue Shelly eingebunden haben, so kannst du das Skript einmal stoppen und erneut starten. Dann werden auch die passenden Datenpunkte für die neuen Shelly gefunden und ausgelesen.
interessanter artikel, aber nur sub-elemente von dem was der ioBroker adapter SourceAnalytix bereits alles kan 🙂
[Link entfernt – keine Werbung]
Wenn man eben nur die Shelly tracken möchte, benötigt man keinen Adapter, der 80MB RAM frisst 🙂
Es steht ja jedem frei, das zu nutzen, was er für richtig hält. Wenn Dein Adapter nützlich für jemanden ist, dann kann dieser ihn doch auch gerne benutzen. Wenn jemand nur ein Skript haben möchte, welches die Verbräuche seiner Shelly ausliest, dann reicht ihm mein Skript, da der JavaScript Adapter eh läuft.
Klasse Script, danach habe ich schon länger gesucht. Danke.
Eine direkte Umrechnung in kWh wäre noch toll.
Vielen Dank 😉
Die Umrechnung kann ja mit (Wh/1000) auch in dem jeweilig benötigten Bereich erfolgen.
Ich hatte es in Wh gelassen, da ich so auch kleinere Werte ablesen kann und bei den Werten, wo ich weiss, dass sie “größer” werden, rechne ich mit Wh/1000 um.
Hallo,
super! Vielen Dank!
Genau das wonach ich gesucht habe 😉
Hatte es mit SourceAnalytix probiert, doch das ist scheinbar (lt. diversen Kommis in Foren) ziemlich buggy
und für mich auch viel zu viele Datenpunkte. Ich will einfach nur die Shellys korrekt aufzeichnen.
Bin noch relativ neu in iobroker, daher weiß ich nicht genau wie & wo ich das nun einfügen muss und
auch nicht an welcher Stelle ich meinen Startwert (alter_wert) im Script eintragen muss…!?
(Muss ggf. noch iwas eingestellt werden?)
Kann mir bitte jemand helfen?
Danke!
Hallo Yvonne,
dieses Skript wird im Bereich “Javascript” eingefügt.
Bei ioBroker auf der linken Seite unter “Skripte” zu finden 😉
Dort bei “Common” den gesamten Text des Skriptes einfügen, abspeichern und auf den Play Button drücken. Die Datenpunkte werden automatisch gefüllt.
Es ist kein Benutzereingriff notwendig – auch keine Startvariablen.
Gruß,
Stephan
Hallo Stephan,
super!
Hab´s am Laufen.
Vielen lieben Dank!
Grüße
Yvonne
Prima 😉