Shelly Verbrauchs-Historie für Tag, Woche, Monat, Jahr

Lesedauer: 9 Minuten

Hinweis: für dieses Skript steht ein Update zur Verfügung!
Es wird nun auch der Shelly 3EM unterstützt.

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:

FunktionBeschreibung
Verbrauch heuteabgefragter Verbrauch heute
Verbrauch gesternabgefragter Verbrauch gestern
Verbrauch diese Wocheabgefragter Verbrauch für die gesamte Woche
Verbrauch letzte Wocheabgefragter Verbrauch für die gesamte letzte Woche
Verbrauch dieser Monatabgefragter Verbrauch für den gesamten Monat
Verbrauch letzter Monatabgefragter Verbrauch für den gesamten letzten Monat
Verbrauch dieses Jahrabgefragter Verbrauch für das gesamte Jahr
Verbrauch letztes Jahrabgefragter Verbrauch für das gesamte letzte Jahr
Verbrauch Gesamtabgefragter Verbrauch gesamt
NameZugewiesener Name des Shelly zum einfachen Wiederfinden
Übersicht über die einzelnen Datenpunkte

Screenshot der verfügbaren Variablen

Screenshot der verfügbaren Variablen
Screenshot der verfügbaren Variablen

Installation des Shelly Adapter

Installation des Shelly Adapter
Installation des Shelly Adapter

Nach kurzer Zeit stehen die Datenpunkte aller gefundenen Shellys unter shelly.0 zur Verfügung.

Skript

/*
 * @copyright 2021 Stephan Kreyenborg <stephan@kreyenborg.koeln>
 *
 * @author 2021 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.60
 * Erstell-Datum:    08. Oktober 2021 | Update: 20. Juli 2022
 * 
 */

// Datenpunkte neu erstellen
var ueberschreiben = false;

// Hauptdatenpunkt unterhalb javascript
var datenpunkt = "ShellyVerbrauch."; // Abschließender Punkt !!! WICHTIG !!!

// Verbrauchs Objekte der einzelnen Shelly
var objekt = ["gesamt", "dieses_jahr", "letztes_jahr", "letzter_monat", "dieser_monat", "letzte_woche",
    "diese_woche", "gestern", "heute", "alter_wert", "aktueller_wert"
];

// Beschreibung der Objekte
var 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 !!!)
var shellyDps = $('state[id=' + shelly_dp + '.*.*.Energy]');

// Datenpunkte der Shelly 3EM DP
var shelly3EMDps = $('state[id=' + shelly_dp + '.*.*.Total]');

// Datenpunkte der Shelly 3EM DP - Total
var shelly3EMTotalDps = $('state[id=' + shelly_dp + '.*.*.ConsumedPower]');

// Datenpunkte der Shelly 3EM DP - Total
var shelly3EMTotalReturned = $('state[id=' + shelly_dp + '.*.*.Total_Returned]');

// Datenpunkte der Shelly Namen (!!! Bitte nicht ändern !!!)
var 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, true);
                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, true);
                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, true);
            // Alter und neuer Wert -> aktuelle Differenz

            var verbrauch = parseFloat(shelly_verbrauch) - alter_wert;
            // Tagesverbrauch aktualisieren
            aktualisiere_vebrauch_objekt(shelly_DP(id), "heute", verbrauch);

            // Wochenverbrauch aktualisieren
            aktualisiere_vebrauch_objekt(shelly_DP(id), "diese_woche", verbrauch);

            // Monatsverbrauch aktualisieren
            aktualisiere_vebrauch_objekt(shelly_DP(id), "dieser_monat", verbrauch);

            // Jahresverbrauch aktualisieren
            aktualisiere_vebrauch_objekt(shelly_DP(id), "dieses_jahr", verbrauch);

            // Gesamten Vebrauch aktualisieren
            aktualisiere_vebrauch_objekt(shelly_DP(id), "gesamt", verbrauch);
        }
    });
    shelly3EMDps.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, true);
                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, true);
                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, true);
            // Alter und neuer Wert -> aktuelle Differenz

            var verbrauch = parseFloat(shelly_verbrauch) - alter_wert;
            // Tagesverbrauch aktualisieren
            aktualisiere_vebrauch_objekt(shelly_DP(id), "heute", verbrauch);

            // Wochenverbrauch aktualisieren
            aktualisiere_vebrauch_objekt(shelly_DP(id), "diese_woche", verbrauch);

            // Monatsverbrauch aktualisieren
            aktualisiere_vebrauch_objekt(shelly_DP(id), "dieser_monat", verbrauch);

            // Jahresverbrauch aktualisieren
            aktualisiere_vebrauch_objekt(shelly_DP(id), "dieses_jahr", verbrauch);

            // Gesamten Vebrauch aktualisieren
            aktualisiere_vebrauch_objekt(shelly_DP(id), "gesamt", verbrauch);
        }
    });
    shelly3EMTotalDps.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, true);
                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, true);
                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, true);
            // Alter und neuer Wert -> aktuelle Differenz

            var verbrauch = parseFloat(shelly_verbrauch) - alter_wert;
            // Tagesverbrauch aktualisieren
            aktualisiere_vebrauch_objekt(shelly_DP(id), "heute", verbrauch);

            // Wochenverbrauch aktualisieren
            aktualisiere_vebrauch_objekt(shelly_DP(id), "diese_woche", verbrauch);

            // Monatsverbrauch aktualisieren
            aktualisiere_vebrauch_objekt(shelly_DP(id), "dieser_monat", verbrauch);

            // Jahresverbrauch aktualisieren
            aktualisiere_vebrauch_objekt(shelly_DP(id), "dieses_jahr", verbrauch);

            // Gesamten Vebrauch aktualisieren
            aktualisiere_vebrauch_objekt(shelly_DP(id), "gesamt", verbrauch);
        }
    });
    shelly3EMTotalReturned.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, true) + "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, true) + "alter_wert", aktueller_wert, true);
                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, true) + "alter_wert", 0, true);
                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, true) + "aktueller_wert", shelly_verbrauch, true);
            // Alter und neuer Wert -> aktuelle Differenz

            var verbrauch = parseFloat(shelly_verbrauch) - alter_wert;
            // Tagesverbrauch aktualisieren
            aktualisiere_vebrauch_objekt(shelly_DP(id, true), "heute", verbrauch);

            // Wochenverbrauch aktualisieren
            aktualisiere_vebrauch_objekt(shelly_DP(id, true), "diese_woche", verbrauch);

            // Monatsverbrauch aktualisieren
            aktualisiere_vebrauch_objekt(shelly_DP(id, true), "dieser_monat", verbrauch);

            // Jahresverbrauch aktualisieren
            aktualisiere_vebrauch_objekt(shelly_DP(id, true), "dieses_jahr", verbrauch);

            // Gesamten Vebrauch aktualisieren
            aktualisiere_vebrauch_objekt(shelly_DP(id, true), "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) {
    // Hole alten Verbrauch
    let alter_verbrauch = getState(dp + objekt).val;
    let verbrauch = 0;
    // Kein Wert vorhanden - nutze den übermittelten Wert
    if (alter_verbrauch < 1 || alter_verbrauch == null) {
        verbrauch = parseFloat(wert)
    } else {
        verbrauch = parseFloat(alter_verbrauch) + parseFloat(wert);
    }
    setState(dp + objekt, parseFloat(verbrauch.toFixed(2)), true);
}

// 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, true);
        }
        // Setze "von" zurück
        setState(id, 0, true);
    });
}

// Funktion um die aktuellen Namen des Shelly abzuholen
function aktualisiere_namen() {
    if (typeof extendObject === "function") {
        shellyDpsName.each(function (id, i) {
            if (existsState(id)) {
                setState(shelly_DP_Name(id), String(getState(id).val), true);
                extendObject("javascript.0." + shelly_DP_Name_Main(id), {
                    common: {
                        name: String(getState(id).val),
                        desc: String(getState(id).val)
                    },
                    type: "channel"
                });
            }
        });
    }
}

// Erstelle die benötigten Datenpunkte
function datenpunkte_erstellen() {
    // Anzahl der gefundenen Shelly
    var anzahl = shellyDps.length;

    shellyDps.each(function (id, j) {
        var initial_wert = 0.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"
            });
        }
    });

    // Anzahl der gefundenen Shelly 3EM
    var anzahl_3em = shelly3EMDps.length;

    shelly3EMDps.each(function (id, j) {
        var initial_wert = 0.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"
            });
        }
    });

    // Anzahl der gefundenen Shelly 3EM - Total
    var anzahl_3em_total = shelly3EMTotalDps.length;

    shelly3EMTotalDps.each(function (id, j) {
        var initial_wert = 0.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"
            });
        }
    });

    // Anzahl der gefundenen Shelly 3EM - Total
    var anzahl_3em_total_returned = shelly3EMTotalReturned.length;

    shelly3EMTotalReturned.each(function (id, j) {
        var initial_wert = 0.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, true) + objekt[i], initial_wert, ueberschreiben, {
                name: beschreibung[i],
                desc: beschreibung[i],
                type: "number",
                role: "value.power",
                unit: "Wh"
            });
        }
    });

    // Alle Datenpunkte erstellt. Frage ersten Verbrauch ab!
    log("Shelly Verbrauch: Datenpunkte erstellt! Erster Verbrauch steht nach 30 Sekunden zur Verfügung! Anzahl gefundener Shelly Datenpunkte: " + (anzahl_3em + anzahl + anzahl_3em_total + anzahl_3em_total_returned));
    setTimeout(shelly_verbrauch_update, 30000);

    // 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: ""
        });
    });
}

/**
 * Wenn 3EM DP, dann anderen Wert zurückgeben
 * @param {any} dp
 * @param {boolean} extended
 */
function shelly_DP(dp, extended = false) {
    dp = dp.split(".");
    dp = datenpunkt + dp[2] + "." + dp[3];
    if (extended) {
        dp = dp + "_Returned.";
    } else {
        dp = dp + ".";
    }
    return dp;
}

function shelly_DP_Name(dp) {
    dp = dp.split(".");
    dp = datenpunkt + dp[2] + "." + dp[3];
    return dp;
}

function shelly_DP_Name_Main(dp) {
    dp = dp.split(".");
    dp = datenpunkt + dp[2];
    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

Fehlersuche

Fehlermeldung im Log

javascript.0 2022-01-25 17:41:56.234	error	Function "extendObject" is not allowed. Use adapter settings to allow it.

Solltest Du diese Fehlermeldung erhalten, dann werden die Namen deiner Shelly dem Datenpunkt nicht zugewiesen. Hierzu musst Du im Javascript – Adapter die Funktion “setObject” erlauben. Dies bedeutet, das Skripte die Eigenschaften von Objekten verändern dürfen. Hier dient es dazu, dem Objekt den Namen des jeweiligen Shelly zu geben.

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.

Wie hat Dir der Beitrag gefallen?
Bewertung: 4.9/5 - abgegebene Bewertungen: 21

476 Gedanken zu „Shelly Verbrauchs-Historie für Tag, Woche, Monat, Jahr

  1. Lars Antworten

    Hallo,
    vielen Dank für Dein tolles Script. Habe versucht es soweit anzupassen, dass noch jeweils Verbrauch der letzten Stunde angezeigt wird…. leider bin ich gescheitert.
    Ist es möglich das “Feature” bitte noch einzubauen oder die passenden Zeilen Codes zur Verfügung zu stellen?
    Danke!

  2. hotspot2 Antworten

    Hallo, tolles Skript. Habe ich bei mir gleich mal reingemacht und leicht modifiziert. Ich hätte gerne die Werte alle im Userdata Bereich. Das klappt auch soweit. Ich habe aktuell nur Shelly Plug S in Verwendung (mehrere) und würde die gerne aufzeichnen. Vom Skript werden aber für jeden Shelly ein Ordner angelegt (z.B. auch Plus1 usw.) und nur der Name hinterlegt. Kann ich das irgendwie anpassen das nur die angelegt werden, die auch Energie messen können? Danke schon mal für einen Tipp.

    • Stephan Autor des BeitragsAntworten

      Hallo,
      Das Skript sucht alle Shelly – auch die, die zwar einen Power Datenpunkt haben, jedoch keine Power liefern.

      Gruß,
      Stephan

  3. MichaelB Antworten

    Hallo, vielen Dank erstmal für das tolle Script. Ich setze es seit ein paar Monaten ein. Jetzt fällt mir auf, dass sämtliche Wh-Werte unter Emeter2 (anders als die bei 0, 1 und “Total”) ohne Nachkommastellen gespeichert werden. Das kann doch kaum am Script liegen, oder? Hast du einen Tipp?

  4. Stefan Antworten

    Hi Stephan,

    total geiles Script. Funktioniert auf Anhieb fehlerlos. Größter Respekt von meiner Seite 🙂

    Wie immer werden Entwickler mit nem Wunschkonzert zugeballert. So auch von mir noch ne Frage:

    Könnte man mit dem Teil auch die Sonoff Schiene abklappern und wenigstens die Daten von “Total, Today und Yesterday” mitnehmen?

    Wäre super.
    Danke noch Mal

    • Stephan Autor des BeitragsAntworten

      Hallo Stefan,
      danke für deine Rückmeldung. Das Skript nennt sich ja “Shelly Verbrauch” – daher fließen dort auch nur Verbräuche vom Shelly mit ein.

      Gruß,
      Stephan

      • Stefan Antworten

        Wow, das hat sich ja erledigt!! Habe eben Dein Script für die Sonoff-Geräte gefunden. Natürlich genau so geil. Danke Dir. 🙂 🙂

  5. Uli Antworten

    Hi Stephan,
    vielen Dank für das super Skript. Es macht genau das, was es soll! Aber…………:-), ich habe da ein kleines Problem.
    Datenpunkte sollen ja in IoBroker nicht mehr unterhalb des Adapters, sondern unterhalb von 0_userdata im Objektbaum angelegt werden.
    Also habe ich mir Dein Skript angeschaut und Zeile 317 auf “extendObject(“0_userdata.0.” + shelly_DP_Name_Main(id), {” geändert.
    Das funtioniert teilweise auf wunderbar. Esw rid der Ordner ShellyVerbaruch mit den einzelenen Shelly-Objekten angelegt.
    Leider unterhalb der Objekte nicht die Datenpunkte erstellt. Diese (und somit die gesamte Struktur noch einmal) werden weiterhin unter javascript.0 angelegt.
    Ich dachte, dass ich Dein Skript verstanden hätte, aber ich finde nicht die Stelle, an der diese DPs unter Javascript.0 angelegt werden.
    Kannst Du mir helfen bzw. auf die Sprüneg helfen?

    Vielen Dank und Gruß aus Münster!

    Uli

    • Stephan Autor des BeitragsAntworten

      Hallo Uli,
      gerne 😉

      Die Datenpunkte in Userdata ist weiterhin nur eine Empfehlung von ioBroker – kein Muss. Da meine Skripts zu Javascript gehören, legen diese ihre Hierachie auch dort ab.

      Gruß,
      Stephan

  6. Marco Antworten

    * Erstell-Datum: 08. Oktober 2021 | Update: 20. Juli 2022

    Hallo, was wurde mit dem Update zum 20.Juli verändert.

    aktuell (vermutlich seit Anfang September) hatte ich gerade eine Änderung des Monatlichen und somit Jährlichen Verbrauches um 1300kwh. ich verwende noch die 1.50Version.
    Shelly 3EM, dort gab es dem jump.

    Jetzt hab ich erst mal den dazu gehörigen Datensatz gelöscht und nun fängt er wieder bei 0 an.

  7. Jens Antworten

    Moin
    ich habe das Script hier durch Zufall gefunden.
    1000 Dank für die tolle Arbeit.
    Bei mir funktioniert es zu 100%.

    Was mich nur stutzig macht ist, das der gesamte Verbrauch in Wh angezeigt wird.
    Sollte da nicht nur W stehen ??

    • Stephan Autor des BeitragsAntworten

      Hallo Jens,
      danke für die Rückmeldung.

      Verbrauch wird immer in Wh (Watt-Stunden) oder kWh (kiloWatt-Stunden) angegeben 😉

      Gruß,
      Stephan

  8. Peter Antworten

    Hallo Stefan,

    vielen Dank für dieses tolle Skipt. Läuft bei mir soweit sehr gut.

    Ich habe 2 Fragen (sorry, wenn diese in den vielen Kommentaren schon einmal beantwortet wurden):

    1. Kann man das Skipt auch so ändern, dass man mit Alias der Shellys arbeiten kann? So kann man dann ggf. defekte Shellys austuaschen und die Daten hängen am Alias und nicht an der Shelly-ID. Oder habe ich hier eine Denkfehler?

    2. Ich besitze eine openWB Wallbox, die über MQTT jede Menge Daten in den ioBroker bringt. Könnte man das Skipt auch dementsprechend umschreiben, dass summierte Daten nach Tag/Monat/Jahr usw. auch von dieser Quelle so gesammelt werden in z.B. influxDB?

    Danke und Gruß

    Peter

    • Stephan Autor des BeitragsAntworten

      Hallo Peter,
      danke für Deine Rückmeldung. Solltest Du einen defekten Shelly haben, kannst Du das Skript einmal stoppen, den neuen Shelly in Betrieb nehmen, dann das Skript erneut starten, so das seine ID angelegt wird. Dann stoppst Du das Skript erneut und nennst die “alte” ID so wie die neue ID (Umbennenen im Objekt-Browser von ioBroker). Dann das Skript wieder starten.

      Du kannst meine Skripte natürlich nach deinen Bedürfnissen umbauen 🙂

      Gruß,
      Stephan

  9. SpacerX Antworten

    Hallo

    Erst mal danke für dein Script. Läuft bei mir seit einem Jahr perfekt.

    Habe nun gesehen das es ein Update gibt.

    Ich habe mir damals das Script so angepasst das die Datenpunkte unter 0_userdata.0 angelegt werden.
    Könntest du diese Option mit einbauen? Dann würde mir und anderen diese Anpassung bei einem Update erspart bleiben.

    mfg Ralf

  10. SpacerX Antworten

    Hallo.

    Ich benutze dein Skript nun schon längere Zeit und habe nun gesehen das es ein Update gibt.

    Ich hab mir in deinem Script noch die Möglichkeit eingebaut auch die Datenpunkte unter ‘0_userdata.0’ erzeugen zu lassen.
    Vielleicht wäre es dir möglich von vorn herein in deinem Code die Wahlmöglichkeit einzubauen ob
    die Datenpunkte unter ‘javascript.0’ oder ‘0_userdate.0’ angelegt werden.
    Man kann sich das zwar auch schnell selbst zusammenstricken nur wird in Zeile 317 direkt Bezug auf javascipt.0 genommen.

    MfG Ralf

    • Stephan Autor des BeitragsAntworten

      Hallo Ralf,
      da meine Skripte zu Javascript gehören, erstellen sie dort auch ihre Ordner.

      Die Struktur Userdata ist nur eine Empfehlung von ioBroker. Aus diesem Grunde bleiben die Skripte auch weiterhin unter JavaScript.
      Wenn ein User dies ändern möchte, so kann dieser den Skript-Pfad für sich anpassen.

      Zeile 317 werde icj diesbezüglich noch anpassen. Danke für den Hinweis.

      Gruß,
      Stephan

      • SpacerX Antworten

        Hallo und danke für deine Rückmeldung.

        Es geht mir nicht darum das Skript in einen anderen Pfad zu legen, sondern nur die Datenpunkte wenn ich das möchte unter ‘0_userdata.0’ anzulegen.

        Aber gut, dein Skript, deine Linie. 😉

        MfG Ralf

  11. Timo Antworten

    Hallo,

    vielen Dank für das gute Script! Ich suche schon länger nach solch einem Script, mit dem ich über mein Shelly EM3 mein Stromverbrauch und mein Balkonkraftwerk “visualisieren” und “auswerten” kann. Ich habe das Script jetzt ein paar Tage im ioBroker laufen.

    Jetzt habe ich mir die Zahlen mal genauer angeschaut und komme damit bezgl. der Auswertung nicht so ganz klar. Vielleicht ist es aber nur ein Denkfehler… Oder ich bin einer großen Sache auf der Spur. 😉

    Ich logge u.a. den Datenpunkt “Total – Verbrauch heute” in eine Influx-DB. Mit Grafana visualisiere ich dann die Daten. Zum einen in ein “Verbrauchsdiagramm” mit den “positiven” und ein “Einspeisediagramm” mit den “negativen” Werten des Tagesverbrauchs aus Deinem Script. Soweit, sogut.

    Wenn ich aber das Diagramm mit den “Einspeisewerten” mit dem Wert “Total returned – Verbrauch heute” aus dem Script vergleiche, habe ich über 2/3 der erzeugten Solarenergie ins Netz eingespeisst. Kommt mir etwas hoch vor.

    Um einen Wert mal zu überschlagen, habe ich den höchsten Wert aus dem heutigen “Einspeisediagramm” genommen (150 Watt) und das 8 Stunden hochgerechnet. Damit komme ich auf ein Wert von 1,2 kWh (150 Watt Dauerleistung mal 8 Stunden). Meine “Einspeisung” vom Balkonkraftwerk logge ich über ein Fritz!Dect210-Adpater. Heute sind 3,68 kWh erzeugt worden. Der Wert aus dem Script (Total returned – Verbrauch heute) beträgt stolze 2,9 kWh. Bedeutet, ich hätte heute “nur” 0,78 kWh selbst verbraucht,

    Wie kommt diese “große” Abweichung zustande?

    Gruß

    Timo

    • Stephan Autor des BeitragsAntworten

      Hallo Timo,
      Das Skript sammelt nur die Daten der Shelly ein. Sollten die Daten fehlerhaft sein, so wäre der Fehler im Shelly zu suchen.

      Gruß,
      Stephan

  12. Timekeeper Antworten

    Herzlichen Dank!!
    Skript läuft und alle 6 Shelly´s wurden gefunden und aktuell berechnet.
    Hast mir eine menge Zeit erspart!!
    Danke!!

  13. Stefan Antworten

    Hallo Stephan,
    vielen Dank für das tolle Script!
    Ich bin blutiger Anfänger mit IOBroker und nutze dein Script um mein Balkonsolar besser darzustellen.

    Jetzt wollte ich mit InfluxDB täglich 23:30 den Tageswert mitschreiben um eine Grafik damit zu erstellen.
    Doch leider kann InfluxDB das nicht mit einem Zeitplan.
    Ich dachte, dann schreibe ich den Tageswert um 23:30 in einen selbst angelegten Datenpunkt. Aber da scheitere ich an der Umsetzung. Bin halt kein Programierer.
    Hast du eine Idee wie ich das umsetzen könnte?

    Beste Grüße,
    Stefan

    • Stephan Autor des BeitragsAntworten

      Hallo Stefan,
      am Besten kannst Du den Wert “heute” über den influx Adapter in die Influx DB schreiben lassen. In Grafana kannst Du dazu dann Auswertungen erstellen.

      Gruß,
      Stephan

  14. Sebastian Antworten

    Hallo,

    ich musste mein Proxmox über ein Paar Tage ausschalten, da das Netzteil kaputt gegangen ist und ausgetauscht werden musste.
    Nach der Wiederinbetriebnahme schreibt das Skript keine neuen Werte mehr in die Datenpunkte.
    Neustarts des Adapters, des Skripts sowie der Shellys hat nicht geholfen.
    Ich verwende die aktuellste Version des Skripts.

    Kann mir jemand helfen, wie ich das Problem näher untersuchen kann?
    Danke!

    • Stephan Autor des BeitragsAntworten

      Hallo Sebastian,
      laufen denn andere Javascripte bei dir? Hast Du dem Skript erlaubt, Datenpunkte (setObject) zu ändern?

      Gruß,
      Stephan

  15. Stefan Antworten

    Hallo Stephan,

    ich nutze den Shelly 3EM um meinen Verbrauch und die Einspeisung meiner PV Anlage zu überwachen.

    Der 3EM hat dazu die Variable “Total_Returned” und kann auch “InstantPower” mit negativem Vorzeichen ausgeben, um Einspeisung anzuzeigen.
    Könnte man das Script einfach um Einspeisung Heute, Gestern, Woche, letzte Woche, Jahr erweitern?

    Vielen Dank
    Grüße Stefan

    • Stephan Autor des BeitragsAntworten

      Hallo Stefan,
      für dieses Vorhaben gibt es eine neue Version des Skriptes.

      Bitte einmal ausprobieren 😉

      Gruß,
      Stephan

  16. Dirk Antworten

    Vielen Dank für dieses tolle Skript!

    Ich bin darauf gestoßen nachdem ein Shelly einfach wieder bei 0 angefangen hat zu zählen. Den alten Stand habe ich aber noch. Ich habe allerdings keine Möglichkeit gesehen im Skript nun einen anderen Startwert als 0 anzugeben. Wo könnte ich das tun?

    Grüße

    • Stephan Autor des BeitragsAntworten

      Hallo Dirk,
      das funktioniert wie folgt.

      Wenn Du das Skript einmal gestartet hast, erstellt dieses die Datenpunkte für die Shelly. Danach stoppst Du das Skript und gehst zum Datenpunkt des Shelly. Dort nullst Du “aktueller_wert” und gibst bei “alter_wert” den alten Wert ein.

      Dann das Skript wieder starten.

      • Dirk Antworten

        Hi Stephan, das hat so leider nicht geklappt. Der alte Wert nullt sich nach dem starten vom script wieder und aktueller wert springt wieder auf den Wert bevor ich manuell genullt habe.

        Aber ich habe es hinbekommen indem ich “gesamt” mit dem alten wert addiert habe abzüglich von aktueller wert, das addiert er dann auf. Jetzt passt es zumindest im gesamt Ergebnis.

  17. Frank Antworten

    Hallo,

    das ist ja genial.
    Weiß jemand, ob man das Ganze auch in Home-Assistant einbinden kann?

    Liebe Grüße
    Frank

    • Stephan Autor des BeitragsAntworten

      Hallo Frank,
      danke für die Rückmeldung.
      Meine Skripte sind nur für ioBroker geeignet.

      Gruß,
      Stephan

  18. Ralf Antworten

    Hallo Stephan

    Ein absolut super Skript. Tolle Arbeit, genau das was ich gesucht habe.
    Gibt es eigentlich schon eine Lösung für das 3EM Total_Returned, oder wie kann ich das noch hinzufügen?
    Lars hatte ja schon mal gefragt. Ich bräuchte den nur für Total nicht für Emeter0-2
    Es gibt ja den Datenpunkt:
    48. // Datenpunkte der Shelly 3EM DP – Total
    49. var shelly3EMTotalDps = $(‘state[id=’ + shelly_dp + ‘.*.*.ConsumedPower]’);

    Den bräuchte ich noch mit “Total_Returned”
    Bei mir wird der ganz normal aufgezählt, wenn die Solaranlage einspeist.
    Wäre echt super.
    Danke.
    Gruß Ralf

    • Stephan Autor des BeitragsAntworten

      Hallo Ralf,
      danke für die Rückmeldung. Leider kann ich das Skript aktuell aus zeitlichen Gründen nicht erweitern. Diese Änderung, obwohl sie klein ist, erfordert eine komplette Restrukturierung.

      Vielen Dank für dein Verständnis!

      Gruß,
      Stephan

      • Thomas Antworten

        Hi Stephan,
        danke für das tolle Skript 🙂

        Ich hoffe es ergibt sich bei dir bald ein Zeitfenster, die Total_Returned-Werte wären wirklich spitze 🤩🤤

        Gruß,
        Thomas

      • Kevin Antworten

        Ah okay … Das beantwortet auch meine Frage oben 🙂

        Dann hoffe ich auf mehr Zeit 😀

        Grüße
        Kevin

      • Ralf Antworten

        Hallo Stephan

        Ich habe das mal angepasst.
        Unter “Total” wird da noch ein Datenpunkt mit “Return” angelegt.
        Habe das Skript einmal angehängt.
        Hoffe das ich das so darf.
        Meine Programmierkünste sind aber leider nicht die besten.
        Ich bekomme bei der Ausführung auch immer Warnungen. Wenn einer eine Lösung hat bitte melden.
        Habe die einmal angefügt:
        23:14:00.137 warn javascript.0 (1521) at Object.shelly_verbrauch_update (script.js.Shelly_Auslesen:232:22)
        23:14:00.139 warn javascript.0 (1521) at aktualisiere_vebrauch_objektRet (script.js.Shelly_Auslesen:305:23)
        23:14:00.139 warn javascript.0 (1521) at script.js.Shelly_Auslesen:271:1
        23:14:00.139 warn javascript.0 (1521) at Object.shelly_verbrauch_update (script.js.Shelly_Auslesen:232:22)
        23:14:00.142 warn javascript.0 (1521) at aktualisiere_vebrauch_objektRet (script.js.Shelly_Auslesen:313:1)
        23:14:00.142 warn javascript.0 (1521) at script.js.Shelly_Auslesen:271:1
        23:14:00.142 warn javascript.0 (1521) at Object.shelly_verbrauch_update (script.js.Shelly_Auslesen:232:22)
        23:14:00.149 warn javascript.0 (1521) at aktualisiere_vebrauch_objektRet (script.js.Shelly_Auslesen:305:23)
        23:14:00.149 warn javascript.0 (1521) at script.js.Shelly_Auslesen:274:1
        23:14:00.150 warn javascript.0 (1521) at Object.shelly_verbrauch_update (script.js.Shelly_Auslesen:232:22)
        23:14:00.152 warn javascript.0 (1521) at aktualisiere_vebrauch_objektRet (script.js.Shelly_Auslesen:313:1)
        23:14:00.152 warn javascript.0 (1521) at script.js.Shelly_Auslesen:274:1
        23:14:00.152 warn javascript.0 (1521) at Object.shelly_verbrauch_update (script.js.Shelly_Auslesen:232:22)
        23:14:00.154 warn javascript.0 (1521) at aktualisiere_vebrauch_objektRet (script.js.Shelly_Auslesen:305:23)
        23:14:00.154 warn javascript.0 (1521) at script.js.Shelly_Auslesen:277:1
        23:14:00.154 warn javascript.0 (1521) at Object.shelly_verbrauch_update (script.js.Shelly_Auslesen:232:22)
        23:14:00.156 warn javascript.0 (1521) at aktualisiere_vebrauch_objektRet (script.js.Shelly_Auslesen:313:1)
        23:14:00.156 warn javascript.0 (1521) at script.js.Shelly_Auslesen:277:1
        23:14:00.157 warn javascript.0 (1521) at Object.shelly_verbrauch_update (script.js.Shelly_Auslesen:232:22)
        23:14:00.158 warn javascript.0 (1521) at script.js.Shelly_Auslesen:239:22
        23:14:00.159 warn javascript.0 (1521) at Object.shelly_verbrauch_update (script.js.Shelly_Auslesen:232:22)
        23:14:00.160 warn javascript.0 (1521) at script.js.Shelly_Auslesen:244:1
        23:14:00.161 warn javascript.0 (1521) at Object.shelly_verbrauch_update (script.js.Shelly_Auslesen:232:22)
        23:14:00.163 warn javascript.0 (1521) at script.js.Shelly_Auslesen:260:1
        23:14:00.163 warn javascript.0 (1521) at Object.shelly_verbrauch_update (script.js.Shelly_Auslesen:232:22)
        23:14:00.165 warn javascript.0 (1521) at aktualisiere_vebrauch_objektRet (script.js.Shelly_Auslesen:305:23)
        23:14:00.165 warn javascript.0 (1521) at script.js.Shelly_Auslesen:265:1
        23:14:00.165 warn javascript.0 (1521) at Object.shelly_verbrauch_update (script.js.Shelly_Auslesen:232:22)
        23:14:00.170 warn javascript.0 (1521) at aktualisiere_vebrauch_objektRet (script.js.Shelly_Auslesen:313:1)
        23:14:00.170 warn javascript.0 (1521) at script.js.Shelly_Auslesen:265:1
        23:14:00.170 warn javascript.0 (1521) at Object.shelly_verbrauch_update (script.js.Shelly_Auslesen:232:22)

        Geändertes Skript:

        /*
        * @copyright 2021 Stephan Kreyenborg
        *
        * @author 2021 Stephan Kreyenborg
        *
        * 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.60
        * Erstell-Datum: 08. Oktober 2021 | Update: 21. April 2022
        *
        */

        // Datenpunkte neu erstellen
        var ueberschreiben = false;

        // Hauptdatenpunkt unterhalb javascript
        var datenpunkt = “ShellyVerbrauch.”; // Abschließender Punkt !!! WICHTIG !!!

        // Verbrauchs Objekte der einzelnen Shelly
        var objekt = [“gesamt”, “dieses_jahr”, “letztes_jahr”, “letzter_monat”, “dieser_monat”, “letzte_woche”,
        “diese_woche”, “gestern”, “heute”, “alter_wert”, “aktueller_wert”];

        // Beschreibung der Objekte
        var 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 !!!)
        var shellyDps = $(‘state[id=’ + shelly_dp + ‘.*.*.Energy]’);

        // Datenpunkte der Shelly 3EM DP
        var shelly3EMDps = $(‘state[id=’ + shelly_dp + ‘.*.*.Total]’);

        // Datenpunkte der Shelly 3EM DP – Total
        var shelly3EMTotalDps = $(‘state[id=’ + shelly_dp + ‘.*.*.ConsumedPower]’);
        var shelly3EMTotalRetDps = $(‘state[id=’ + shelly_dp + ‘.*.*.Total_Returned]’);

        // Datenpunkte der Shelly Namen (!!! Bitte nicht ändern !!!)
        var 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, true);
        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, true);
        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, true);
        // Alter und neuer Wert -> aktuelle Differenz

        var verbrauch = parseFloat(shelly_verbrauch) – 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);
        }
        });
        shelly3EMDps.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, true);
        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, true);
        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, true);
        // Alter und neuer Wert -> aktuelle Differenz

        var verbrauch = parseFloat(shelly_verbrauch) – 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);
        }
        });

        shelly3EMTotalDps.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, true);
        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, true);
        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, true);
        // Alter und neuer Wert -> aktuelle Differenz

        var verbrauch = parseFloat(shelly_verbrauch) – 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);
        }
        });

        shelly3EMTotalRetDps.each(function (id, i) {
        var shelly_verbrauch = getState(id).val;
        // setState(“javascript.0.ShellyVerbrauch.SHEM-3#40F52001BCB8#1.Total.Return.alter_wert”,shelly_DPRet(id),true);

        // 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_DPRet(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_DPRet(id) + “alter_wert”, aktueller_wert, true);
        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_DPRet(id) + “alter_wert”, 0, true);
        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_DPRet(id) + “aktueller_wert”, shelly_verbrauch, true);
        // Alter und neuer Wert -> aktuelle Differenz

        var verbrauch = parseFloat(shelly_verbrauch) – alter_wert;
        // Tagesverbrauch aktualisieren
        aktualisiere_vebrauch_objektRet(id, “heute”, verbrauch);

        // Wochenverbrauch aktualisieren
        aktualisiere_vebrauch_objektRet(id, “diese_woche”, verbrauch);

        // Monatsverbrauch aktualisieren
        aktualisiere_vebrauch_objektRet(id, “dieser_monat”, verbrauch);

        // Jahresverbrauch aktualisieren
        aktualisiere_vebrauch_objektRet(id, “dieses_jahr”, verbrauch);

        // Gesamten Vebrauch aktualisieren
        aktualisiere_vebrauch_objektRet(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) {
        // Hole alten Verbrauch
        let alter_verbrauch = getState(shelly_DP(dp) + objekt).val;
        let verbrauch = 0;
        // Kein Wert vorhanden – nutze den übermittelten Wert
        if (alter_verbrauch<1 || alter_verbrauch==null) {
        verbrauch = parseFloat(wert)
        } else {
        verbrauch = parseFloat(alter_verbrauch) + parseFloat(wert);
        }
        setState(shelly_DP(dp) + objekt, parseFloat(verbrauch.toFixed(2)), true);
        }

        // aktualisiert das jeweilige Verbrauchs-Objekt Für 3EMReturn und addiert den Verbrauch dazu
        function aktualisiere_vebrauch_objektRet(dp, objekt, wert) {
        // Hole alten Verbrauch
        let alter_verbrauch = getState(shelly_DPRet(dp) + objekt).val;
        let verbrauch = 0;
        // Kein Wert vorhanden – nutze den übermittelten Wert
        if (alter_verbrauch<1 || alter_verbrauch==null) {
        verbrauch = parseFloat(wert)
        } else {
        verbrauch = parseFloat(alter_verbrauch) + parseFloat(wert);
        }
        setState(shelly_DPRet(dp) + objekt, parseFloat(verbrauch.toFixed(2)), true);
        }

        // 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, true);
        }
        // Setze "von" zurück
        setState(id, 0, true);
        });
        }

        // Funktion um die aktuellen Namen des Shelly abzuholen
        function aktualisiere_namen() {
        if (typeof extendObject === "function") {
        shellyDpsName.each(function (id, i) {
        if (existsState(id)) {
        setState(shelly_DP_Name(id), String(getState(id).val), true);
        extendObject("javascript.0." + shelly_DP_Name_Main(id), {
        common: {
        name: String(getState(id).val),
        desc: String(getState(id).val)
        }, type: "channel"
        });
        }
        });
        }
        }

        // Erstelle die benötigten Datenpunkte
        function datenpunkte_erstellen() {
        // Anzahl der gefundenen Shelly
        var anzahl = shellyDps.length;

        shellyDps.each(function (id, j) {
        var initial_wert = 0.0;
        for (var i = 0; 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”
        });
        }
        });

        // Anzahl der gefundenen Shelly 3EM
        var anzahl_3em = shelly3EMDps.length;

        shelly3EMDps.each(function (id, j) {
        var initial_wert = 0.0;
        for (var i = 0; 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”
        });
        }
        });

        // Anzahl der gefundenen Shelly 3EM – Total
        var anzahl_3em_total = shelly3EMTotalDps.length;

        shelly3EMTotalDps.each(function (id, j) {
        var initial_wert = 0.0;
        for (var i = 0; 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”
        });
        createState(shelly_DPRet(id) + objekt[i], initial_wert, ueberschreiben, {
        name: beschreibung[i],
        desc: beschreibung[i],
        type: “number”,
        role: “value.power”,
        unit: “Wh”
        });
        }
        });

        // Alle Datenpunkte erstellt. Frage ersten Verbrauch ab!
        log(“Shelly Verbrauch: Datenpunkte erstellt! Erster Verbrauch steht nach 30 Sekunden zur Verfügung! Anzahl gefundener Shelly Datenpunkte: ” + (anzahl_3em + anzahl + anzahl_3em_total));
        setTimeout(shelly_verbrauch_update, 30000);

        // 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_DPRet(dp) {
        dp = dp.split(“.”);
        dp = datenpunkt + dp[2] + “.” + dp[3] + “.Return.”;
        return dp;
        }

        function shelly_DP_Name(dp) {
        dp = dp.split(“.”);
        dp = datenpunkt + dp[2] + “.” + dp[3];
        return dp;
        }

        function shelly_DP_Name_Main(dp) {
        dp = dp.split(“.”);
        dp = datenpunkt + dp[2];
        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);

  19. Markus Antworten

    Hallo Stephan,
    vielen Dank für das tolle Skript. Das läuft super mit meinen Shelly 1PM Plus und Shelly Dimmer 2. Nun habe ich mir auch noch einen Shelly 3EM dazugekauft, aber leider werden dafür keine Datenpunkte erstellt. Im Shelly-Adapter taucht der 3EM auf und liefert Werte. Aber die Datenpunkte werden nicht angelegt. Skript habe ich natürlich schon ein paar Mal gestoppt und neu gestartet. Aber es werden immer nur alle anderen Shellys gefunden.
    Woran könnte das liegen? Ich bin am Ende meiner Weisheit.

    Danke,

    Gruß Markus

    • Stephan Autor des BeitragsAntworten

      Hallo Markus,
      danke für die Rückmeldung.

      Das hört sich für mich so an, als wenn die Instanz eine andere wäre.

      Bitte hier einmal prüfen, ob alle Shelly in einer Instanz laufen.

      Gruß,
      Stephan

      • Markus Antworten

        Hallo Stephan,

        das war der entscheidende Tip. Habe jetzt alle in einer Instanz laufen und die Datenpunkte für den 3EM wurden einwandfrei erzeugt.
        Ganz herzlichen Dank für Deine Unterstützung!

        Gruß,
        Markus

      • Markus Antworten

        Hallo Stephan,
        jetzt habe ich trotzdem noch eine Frage:
        und zwar ist mir wieder eingefallen, warum ich zwei Instanzen für die Shellys hatte. Die Shelly 1PM plus funktionieren nur mit MQTT, aber bei dem Shelly 3EM habe ich MQTT nicht eingeschaltet, weil sonst die Cloud nicht mehr funktioniert. Daher die zwei Instanzen (einmal für 1PM mit MQTT und einmal für 3EM mit CoAP). Gibt es da trotzdem eine Möglichkeit, dass Dein Skript mit beiden Instanzen funktioniert?

        Danke und Gruß,
        Markus

        • Marks Antworten

          sorry, ich habe ein paar Kommentare oberhalb eine mögliche Lösung gefunden. Die werde ich mal ausprobieren…

      • Markus Antworten

        sorry, ich habe ein paar Kommentare weiter oben die Lösung gefunden. Mit den zwei Skripten funktioniert es jetzt.

  20. Ede Antworten

    Hallo Stephan,

    auch ich bin begeistert von deinem Script und setzte es ein.

    Eine Frage habe ich. Da manche (neueren) Shellys nicht mit COAP funktionieren, sondern mit MQTT, habe ich zwei Shelly Adapter laufen .0 und .1. Bekomme es leider nicht hin, das ich diese mit zwei Scripte den Verbrauch erfasse. Wie kann ich das am besten lösen?

    Danke für deine Zeit im voraus.

    Gruß
    Ede

    • Stephan Autor des BeitragsAntworten

      Halloo Ede,
      Du kannst das Skript 2 Mal anlegen – in einem Skript änderst Du Zeile 40 in “shelly.1”.

      Gruß,
      Stephan

      • Ede Antworten

        Danke für schnelle Antwort.

        Das mit zwei Skripten habe ich schon probiert. Aber wenn ich das Skript 2x anlege, natürlich mit unterschiedlichen Namen, wird jede Änderung in einem Skript zeitgleich auch im anderem Skript geändert. Wie ein digitaler Zwilling. Ich habe keine Ahnung, was ich da falsch mache.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert