Dieses Skript ist eine Abwandlung des Skriptes, welches bereits für die Shelly Adapter zur Verfügung steht. Hier werden die Tasmota und Sonoff Geräte unterstützt.

Übersicht der Funktionen

Folgende Verbrauchswerte stehen in der Historie für jeden der Sonoff Geräte 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 Sonoff 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 Sonoff Adapter

Installation des Sonoff Adapter

Nach kurzer Zeit stehen die Datenpunkte aller gefundenen Sonoff Geräte unter sonoff.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 Tasmota 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:     Tasmota-Verbrauch
 * Skript Version:  1.1
 * Erstell-Datum:   19. März 2021
 *
 */
 
// Datenpunkte neu erstellen
var ueberschreiben = false;
 
// Hauptdatenpunkt unterhalb javascript
var datenpunkt = "TasmotaVerbrauch.";
 
// Verbrauchs Objekte der einzelnen Tasmota
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 Tasmota", "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 Tasmota Geräte (Standard: sonoff.0)
var tasmota_dp = "sonoff.0";
 
// Datenpunkte der Tasmota (!!! Bitte nicht ändern !!!)
const tasmotaDps = $('state[id=' + tasmota_dp + '.*.ENERGY_Total]');
 
// Datenpunkte der Tasmota Namen (!!! Bitte nicht ändern !!!)
const tasmotaDpsName = $('state[id=' + tasmota_dp + '.*.DeviceName]');
 
// Tasmota Verbrauch aktualisieren - nachts um 00:00 Uhr
function tasmota_vebrauch_tag() {
    // Nochmals das Tagesupdate durchlaufen, damit die restlichen Werte gelesen werden
    tasmota_verbrauch_update();
 
    // Datumsvariable
    var heute = new Date();
 
    // Heute zu Gestern verschieben. Täglich um 00:00 Uhr
    verschiebe_verbrauch_objekt("heute", "gestern");
    log ("Tasmota 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 ("Tasmota 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 ("Tasmota 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 ("Tasmota Verbrauch: Werte für dieses und letztes Jahr aktualisiert!");
    }
}
 
// Tagesverbrauch alle 15 Min von der Original Variable des Tasmota in eigene Variable kopieren
function tasmota_verbrauch_update() {
    var anzahl_updates = 0;
    var anzahl_reboots = 0;
    var anzahl_gleich = 0;
    tasmotaDps.each(function (id, i) {
        var tasmota_verbrauch = getState(id).val;
        // Einige Tasmota haben keine Verbrauchswerte (noch nicht)
        if (tasmota_verbrauch != null) {
            // Hole aktuellen Wert, um zu kontrollieren, ob ein Reboot stattgefunden hat
            var aktueller_wert = getState(tasmota_DP(id) + "aktueller_wert").val;
            var alter_wert = 0;
            // Prüfe alten und neuen Wert
            if (tasmota_verbrauch > aktueller_wert) {
                // Verbrauchswert ist größer als alter Wert -> es wurde kein Reboot durchgeführt
                setState(tasmota_DP(id) + "alter_wert", aktueller_wert,true);
                alter_wert = aktueller_wert;
                anzahl_updates++;
            }
            if (aktueller_wert > tasmota_verbrauch) {
                // Verbrauchswert ist kleiner als alter Wert -> es wurde ein Reboot durchgeführt
                setState(tasmota_DP(id) + "alter_wert", 0,true);
                alter_wert = tasmota_verbrauch;
                anzahl_reboots++;
            }
            if (tasmota_verbrauch == aktueller_wert) {
                // Verbrauchswert ist gleich wie alter Wert -> kein Update notwendig
                alter_wert = aktueller_wert;
                anzahl_gleich++;
            }
 
            setState(tasmota_DP(id) + "aktueller_wert", tasmota_verbrauch);
            // Alter und neuer Wert -> aktuelle Differenz
 
            var verbrauch = parseFloat(tasmota_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);
        }
    });
    aktualisiere_namen();
    log("Tasmota 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(tasmota_DP(dp) + objekt).val) + parseFloat(wert);
    verbrauch = parseFloat(verbrauch.toFixed(3));
    setState(tasmota_DP(dp) + objekt, verbrauch,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 heute zurück
        setState(id, 0,true);
    });
}
 
// Funktion um die aktuellen Namen der Tasmota abzuholen
function aktualisiere_namen() {
    tasmotaDpsName.each(function (id, i) {
        setState(tasmota_DP_Name(id),String(getState(id).val),true);
    });
}
 
// Erstelle die benötigten Datenpunkte
function datenpunkte_erstellen() {
    // Anzahl der gefundenen Tasmota
    var anzahl = tasmotaDps.length;
 
    tasmotaDps.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(tasmota_DP(id) + objekt[i], initial_wert, ueberschreiben, {
                name: beschreibung[i],
                desc: beschreibung[i],
                type: "number",
                role: "value.power",
                unit: "kWh"
            });
        }
    });
     
    // Alle Datenpunkte erstellt. Frage ersten Verbrauch ab!
    log("Tasmota Verbrauch: Datenpunkte erstellt! Erster Verbrauch steht nach 1 Minute zur Verfügung! Anzahl gefundener Tasmota Datenpunkte: " + anzahl);
    setTimeout(tasmota_verbrauch_update, 20000);
     
    // Datenpunkte für die Namen der Tasmota erstellen
    tasmotaDpsName.each(function(id, j) {
        createState(tasmota_DP_Name(id), "", ueberschreiben, {
            name: "Name des Tasmota",
            desc: "Name des Tasmota",
            type: "string",
            role: "value",
            unit: ""
        });
    });
}
 
function tasmota_DP(dp) {
    dp = dp.split(".");
    dp = datenpunkt + dp[2] + ".";
    return dp;
}
 
function tasmota_DP_Name(dp) {
    dp = dp.split(".");
    dp = datenpunkt + dp[2] + "." + dp[3];
    return dp;
}
 
function tasmota_verbrauch_erster_start() {
    log("Tasmota Verbrauch: Erster Start des Skriptes! Datenpunkte werden erstellt!");
    // Datenpunkte werden erstellt
    datenpunkte_erstellen();
}
 
// Erster Start und Initialisierung
tasmota_verbrauch_erster_start();
 
// Alle 15 Minuten das Skript für den Tagesverbrauch ausführen
schedule('*/15 * * * *', tasmota_verbrauch_update);
 
// Nachts um 24 Uhr werden die Werte in andere Variablen gespeichert, um den Verlauf zu erstellen
schedule('0 0 * * *', tasmota_vebrauch_tag);

Kategorien:

8 Kommentare

  1. Hallo Stephan Kreyenborg,

    Ganz großes Kompliment, genau was ich gesucht habe! Dank deines Skriptes muss ich jetzt nicht mehr alle paar Tage zum Zettel greifen und die Werte notieren, wieviel Energie mein Plug in Hybrid getankt hat. Ohne dein Skript hätte ich wahrscheinlich wochenlang daran gebastelt oder hätte es gar nicht hinbekommen. Habe mich noch ein bisschen in deiner Anleitung zum SHELLY eingelesen, auch die Kommentare. Dann wurde mir der Zusammenhang klarer und nach kopieren und einfügen hat es auf Anhieb funktioniert. Für dich als Rückmeldung:
    Betreibe eine (demnächst mehrere) Sonoff POW R1 mit Version 2022.01.3(tasmota).

    Vielen Dank nochmal

    Tom

    P.S.: Finde ich die Werte auf dem Raspi auch in einer Datei? Falls nicht, nicht schlimm, dann bastel ich mir was 🙂 oder hast du dafür noch einen Trick in der Tasche oder auch schon mal was dazu geschrieben? Bis bald 🙂

    • Hallo Tom,
      freut mich, wenn das Skript läuft.
      Eine Datei stelle ich aktuell nicht zur Verfügung – da wäre der Umfang zu groß, da jeder ein anderes Format haben wollen würde.

      Gruß,
      Stephan

      • Hallo Stephan,
        nochmal danke für das Skript und danke für deine Antwort!
        Hatte in meinem 1. Post einen Schreibfehler, ist natürlich ein POW R2, bzw. war. Denn zwischenzeitlich habe ich den 2ten im System angemeldet und auch dieser hat sich sofort an deinem Skript angemeldet und läuft einwandfrei! Toll !!!
        Die Frage zur Datei:
        Ich bin zwar noch blutiger Anfänger, habe aber eine Lösung für mich gefunden.
        Konnte mir im Blockly selbst ein Skript schreiben, “JS-Funktion mit Ergebnis “Datei” mit; Dateiname…….”
        In unterschiedlichen Kombinationen kann ich damit den Tagesverlauf, Tageswerte, Wochenwerte, Monatswerte und Jahreswerte, dank deiner Datenpunkte wegspeichern. Wie ich die mal auswerte und grafisch darstelle weiß ich noch nicht, hat aber auch keine Priorität. Hauptsache sie sind da und gehen nicht verloren.
        Also alles super, weiter so!
        Gruß Tom

        P.S.: Wenn ich die Zeit finde, werde ich versuchen dein Skript auf einen oder mehrere SONOFF TH16 umzuschreiben (denke die Erlaubnis besteht) vom Prinzip sind die ankommenden Werte ja ähnlich, heißen nur anders.
        Oder hast du da schon was fertiges? Vorsichtig mit einem dezenten Grinsen gefragt! Nochmal Gruß

  2. Hallo Stephan,

    danke für die Bereitstellung Deines Scriptes.
    Besteht die Möglichkeit auch jeden einzelnen Monat, also Januar bis Dezember, darzustellen? Ich möcvhte meine Solarmodule loggen, sodass ich die einzelnen Monatserträge
    angezeigt bekomme. Mit Grafana und Influx funktioniert das nicht richtig.
    Gruß
    Thomas

    • Hallo Thomas,
      am Besten nutzt Du influx über den Influx-Adapter und lässt den Datenpunkt “heute” immer aktualisieren. Diesen kannst Du dann in Grafana perfekt auswerten.
      So mache ich dies auch 😉

      Gruß,
      Stephan

  3. Danke für Deine kleinen netten Scripte 🙂

    Musste bei mir allerdings etwas umändern damit es lief bei mir.

    // Datenpunkte der Tasmota (!!! Bitte nicht ändern !!!)
    //const tasmotaDps = $(‘state[id=’ + tasmota_dp + ‘.*.ENERGY_Total]’);
    const tasmotaDps = $(‘state[id=’ + tasmota_dp + ‘.*.ENERGY.Total]’);

    Gruß Henry

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.