Sonoff/Tasmota Verbrauchs-Historie für Tag, Woche, Monat, Jahr

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);

Schreibe einen Kommentar

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