Skip to content
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Skripten / Logik
  4. JavaScript
  5. Anpassung eines Scripts / Hilfe benötigt

NEWS

  • UPDATE 31.10.: Amazon Alexa - ioBroker Skill läuft aus ?
    apollon77A
    apollon77
    48
    3
    8.8k

  • Monatsrückblick – September 2025
    BluefoxB
    Bluefox
    13
    1
    2.2k

  • Neues Video "KI im Smart Home" - ioBroker plus n8n
    BluefoxB
    Bluefox
    16
    1
    3.2k

Anpassung eines Scripts / Hilfe benötigt

Geplant Angeheftet Gesperrt Verschoben JavaScript
14 Beiträge 4 Kommentatoren 866 Aufrufe 3 Watching
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • O Offline
    O Offline
    opöl
    schrieb am zuletzt editiert von opöl
    #1

    Hallo zusammen,
    erst einmal ein verspätetes „Frohes neues Jahr“.

    Sorry, viel Text.

    Ich habe ein Problem mit einem Script, dass ich mit meinen Kenntnissen leider noch nicht in den Griff bekomme. Vielleicht kann mir da jemand auf die Sprünge helfen.

    Das hier bekannte Script des Users @skb mit den Ergänzungen von @SpacerX : „Shelly Verbrauchs-Historie für Tag, Woche, Monat, Jahr“ von hier:
    https://forum.iobroker.net/topic/37262/shelly-verbrauchs-historie-für-tag-woche-monat-jahr/82?_=1736424008402&lang=de
    habe ich seit langem erfolgreich im Einsatz und seit einem Jahr auch für Sonoff Geräte (z.B. für Nous A1T Steckdosen mit Tasmota) adaptiert. Läuft soweit prima. Hier für interessierte das Script für die Nous Steckdosen (leider noch nicht ganz aufgeräumt):

     /*
     *
     * Dieses Skript dient zur Verbrauchserfassung von Tasmota Geräten
     * Z.B. Nous Steckdosen oder auf Tasmota geflashte Shelly Geräte.
     * 
     * Das Script ermittelt aus dem Zählerstand der Geräte die Tages- Wochen- Monats- 
     * und Jahresverbräuche und legt diese in neuen Objekten unter "0_userdata.0.NousVerbrauch"
     * im iobroker ab. Damit ist eine einfachere grafische Darstellung und Auswertung möglich.
     * 
     * Die Verbreitung, Anpassung und Optimierung zu privaten Zwecken ist ausdrücklich gestattet.
     * 
     * Jegliche Verantwortung liegt beim Benutzer. 
     * 
     * 
     * Skript Name:      Nous-Verbrauch
     * Skript Version:   1.70  | 25. April 2024
     * Erstell-Datum:    08. Oktober 2023
     *
     * Das Script basiert auf dem Shelly-Verbrauch Script des Autors 
     * Stephan Kreyenborg sowie den Anpassungen von SpacerX.
     * 
     */
    
    // Datenpunkte neu erstellen
    var ueberschreiben = false;
    // Hauptdatenpunkt unterhalb javascript
    var datenpunkt = "NousVerbrauch."; // Abschließender Punkt !!! WICHTIG !!!
    // Verbrauchs Objekte der einzelnen Nous
    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 Nous", "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 Nous (Standard: sonoff.0)
    var Nous_dp = "sonoff.0";
    // Datenpunkte der Nous (!!! Bitte nicht ändern !!!)
    var NousDps = $('state[id=' + Nous_dp + '.*.*.Total]');  
    // Datenpunkte der Nous Namen (!!! Bitte nicht ändern !!!)
    var NousDpsName = $('state[id=' + Nous_dp + '.*.name]');
    // Nous Verbrauch aktualisieren - nachts um 00:00 Uhr
    function Nous_vebrauch_tag() {
        // Nochmals das Tagesupdate durchlaufen, damit die restlichen Werte gelesen werden
        Nous_verbrauch_update();
        // Datumsvariable
        var heute = new Date();
        // Heute zu Gestern verschieben. Täglich um 00:00 Uhr
        verschiebe_verbrauch_objekt("heute", "gestern");
        log("Nous 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("Nous 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("Nous 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("Nous Verbrauch: Werte für dieses und letztes Jahr aktualisiert!");
        }
    }
    // Tagesverbrauch alle 15 Min von der Original Variable des Nous in eigene Variable kopieren
    function Nous_verbrauch_update() {
        var anzahl_updates = 0;
        var anzahl_reboots = 0;
        var anzahl_gleich = 0;
        NousDps.each(function (id, i) {
            //var Nous_verbrauch = getState(id).val; 
            var Nous_verbrauch = 1000 * getState(id).val; // Nous Steckdoesen geben die Leistungswerte in kWH an, Shellys in Wh
            if (Nous_verbrauch != null) {
                // Hole aktuellen Wert, um zu kontrollieren, ob ein Reboot stattgefunden hat
                var aktueller_wert = getState(Nous_DP(id) + "aktueller_wert").val;
                var alter_wert = 0;
                // Prüfe alten und neuen Wert
                if (Nous_verbrauch > aktueller_wert) {
                    // Verbrauchswert ist größer als alter Wert -> es wurde kein Reboot durchgeführt
                    setState(Nous_DP(id) + "alter_wert", aktueller_wert, true);
                    alter_wert = aktueller_wert;
                    anzahl_updates++;
                }
                
    
                if (aktueller_wert > Nous_verbrauch) {
                    // Verbrauchswert ist kleiner als alter Wert -> es wurde ein Reboot durchgeführt
                    // setState(Nous_DP(id) + "alter_wert", 0, true);
                    // alter_wert = 0;
                    alter_wert = aktueller_wert; // Um Rechenfegler durch fehlende Messwerte zu verhindern
                    anzahl_reboots++;
                }
    
                if (Nous_verbrauch == aktueller_wert) {
                    // Verbrauchswert ist gleich altem Wert -> kein Update notwendig
                    alter_wert = aktueller_wert;
                    anzahl_gleich++;
                }
                setState(Nous_DP(id) + "aktueller_wert", Nous_verbrauch, true);
                // Alter und neuer Wert -> aktuelle Differenz
                var verbrauch = parseFloat(Nous_verbrauch) - alter_wert;
                // Tagesverbrauch aktualisieren
                aktualisiere_vebrauch_objekt(Nous_DP(id), "heute", verbrauch);
                // Wochenverbrauch aktualisieren
                aktualisiere_vebrauch_objekt(Nous_DP(id), "diese_woche", verbrauch);
                // Monatsverbrauch aktualisieren
                aktualisiere_vebrauch_objekt(Nous_DP(id), "dieser_monat", verbrauch);
                // Jahresverbrauch aktualisieren
                aktualisiere_vebrauch_objekt(Nous_DP(id), "dieses_jahr", verbrauch);
                // Gesamten Vebrauch aktualisieren
                aktualisiere_vebrauch_objekt(Nous_DP(id), "gesamt", verbrauch);
            }
        });
        
        aktualisiere_namen();
        log("Nous 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 Nous abzuholen
    function aktualisiere_namen() {
        if (typeof extendObject === "function") {
            NousDpsName.each(function (id, i) {
                if (existsState(id)) {
                    setState(Nous_DP_Name(id), String(getState(id).val), true);
                    extendObject("javascript.0." + Nous_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 Nous
        var anzahl = NousDps.length;
    log("Nous Datenpukte erstellt: " + anzahl);	    
        NousDps.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(Nous_DP(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("Nous Verbrauch: Datenpunkte erstellt! Erster Verbrauch steht nach 30 Sekunden zur Verfügung! Anzahl gefundener Nous Datenpunkte: " + anzahl );
        setTimeout(Nous_verbrauch_update, 30000);
        // Datenpunkte für die Namen der Nous erstellen
        NousDpsName.each(function (id, j) {
            createState(Nous_DP_Name(id), "", ueberschreiben, {
                name: "Name des Nous",
                desc: "Name des Nous",
                type: "string",
                role: "value",
                unit: ""
            });
        });
    }
    /**
     * Wenn 3EM DP, dann anderen Wert zurückgeben
     * @param {any} dp
     * @param {boolean} extended
     */
    function Nous_DP(dp, extended = false) {
        dp = dp.split(".");
        dp = datenpunkt + dp[2] + "." + dp[3];
        if (extended) {
            dp = dp + "_Returned.";
        } else {
            dp = dp + ".";
        }
        return dp;
    }
    function Nous_DP_Name(dp) {
        dp = dp.split(".");
        dp = datenpunkt + dp[2] + "." + dp[3];
        return dp;
    }
    function Nous_DP_Name_Main(dp) {
        dp = dp.split(".");
        dp = datenpunkt + dp[2];
        return dp;
    }
    function Nous_verbrauch_erster_start() {
        log("Nous Verbrauch: Erster Start des Skriptes! Datenpunkte werden erstellt!");
        // Datenpunkte werden erstellt
        datenpunkte_erstellen();
    }
    /*
     * Override Functions
     * @autor 2022 SpacerX <spacerx@rbe-base.de>
     * Überschreibt Funktionen um Datenpunkte unter 0_userdata.0 zu erstellen
     *
     *** START SpacerX ***/
    // Userdatenpunkt
    var userdir = "0_userdata.0."; // Abschließender Punkt !!! WICHTIG !!!
    /**
     * Letzten des Monats berechnen.
     * @param {Date} oHeute
     */
    function letzterDesMonats(oHeute) {
        return new Date(oHeute.getFullYear(), oHeute.getMonth() + 1, 0).getDate();
    }
    //Override at row 48
    // Nous Verbrauch aktualisieren - nachts um 23:59 Uhr
    function Nous_vebrauch_tag() {
        // Nochmals das Tagesupdate durchlaufen, damit die restlichen Werte gelesen werden
        Nous_verbrauch_update();
        // Datumsvariable
        var heute = new Date();
        // Heute zu Gestern verschieben. Täglich um 23:59 Uhr
        verschiebe_verbrauch_objekt("heute", "gestern");
        log("Nous Verbrauch: Werte für gestern und heute aktualisiert!");
        // aktuelle Woche in letzte Woche verschieben. Am Sonntag um 23:59 Uhr
        if (heute.getDay() === 0) {   /*line changed by spacerx (Sonntag=0, Montag=1)*/
            verschiebe_verbrauch_objekt("diese_woche", "letzte_woche");
            log("Nous Verbrauch: Werte für diese und letzte Woche aktualisiert!");
        }
        // aktueller Monat in letzten Monat verschieben. Am letzten des Monats um 23:59 Uhr
        if (heute.getDate() === letzterDesMonats(heute)) {   /*line changed by spacerx*/
            verschiebe_verbrauch_objekt("dieser_monat", "letzter_monat");
            log("Nous Verbrauch: Werte für diesen und letzten Monat aktualisiert!");
        }
        // aktuelles Jahr in letztes Jahr verschieben. Am letzten Tag des Jahres um 23:59 Uhr
        if (heute.getDate() === letzterDesMonats(heute) && heute.getMonth() === 11) { /*line changed by spacerx (Jan=0, Dez=11)*/
            verschiebe_verbrauch_objekt("dieses_jahr", "letztes_jahr");
            log("Nous Verbrauch: Werte für dieses und letztes Jahr aktualisiert!");
        }
    }
    //Override at row 254
    //Verschiebt das jeweilige Verbrauchs-Objekt und nullt den Ursprung (Tag, Woche, Monat, Jahr)
    function verschiebe_verbrauch_objekt(von, nach) {
        $('state[id=' + userdir + datenpunkt + '*.*.' + von + ']').each(function (id, i) {   /*line changed by spacerx*/
            // 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);
        });
    }
    //Override at row 267
    // Funktion um die aktuellen Namen des Nous abzuholen
    function aktualisiere_namen() {
        if (typeof extendObject === "function") {
            NousDpsName.each(function (id, i) {
                if (existsState(id)) {
                    setState(Nous_DP_Name(id), String(getState(id).val), true);
                    extendObject(Nous_DP_Name_Main(id), {   /*line changed by spacerx*/
                        common: {
                            name: String(getState(id).val),
                            desc: String(getState(id).val)
                        },
                        type: "channel"
                    });
                }
            });
        }
    }
    //Override at row 377
    function Nous_DP(dp, extended = false) {
        dp = dp.split(".");
        dp = userdir + datenpunkt + dp[2] + "." + dp[3];   /*line changed by spacerx*/
        if (extended) {
            dp = dp + "_Returned.";
        } else {
            dp = dp + ".";
        }
        return dp;
    }
    //Override at row 387
    function Nous_DP_Name(dp) {
        dp = dp.split(".");
        dp = userdir + datenpunkt + dp[2] + "." + dp[3];   /*line changed by spacerx*/
        return dp;
    }
    //Override at row 392
    function Nous_DP_Name_Main(dp) {
        dp = dp.split(".");
        dp = userdir + datenpunkt + dp[2];   /*line changed by spacerx*/
        return dp;
    }
    /*** END SpacerX ***/
    // Erster Start und Initialisierung
    Nous_verbrauch_erster_start();
    // Alle 15 Minuten das Skript für den Tagesverbrauch ausführen
    schedule('*/15 * * * *', Nous_verbrauch_update);
    /*** START Edit SpacerX ***/
    // Nachts um 24 Uhr werden die Werte in andere Variablen gespeichert, um den Verlauf zu erstellen
    //schedule('0 0 * * *', Nous_vebrauch_tag);
    // Nachts um 23:59 Uhr werden die Werte in andere Variablen gespeichert, um den Verlauf zu erstellen
    schedule('59 23 * * *', Nous_vebrauch_tag);
    /*** END Edit SpacerX ***/
    

    Nun möchte ich dieses Script so adaptieren, dass für von mir in einem Array vorgegebene (virtuelle) Zählerwerte* die Tages-, Wochen-, Monats- und Jahreswerte ermittelt und in die entsprechenden Datenpunkte geschrieben werden. Das klappt auch soweit bis auf das Verschieben der Werte „heute -> gestern“, „diese Woche -> letzte Woche“ etc. Die zuständige Routine verstehe ich leider nicht. Es sollte die Funktion ab Zeile 175 in diesem Script sein:
    function verschiebe_verbrauch_objekt(von, nach) {

    /*
     * Dieses Script dient dazu, aus definierten Datenpunkten (zumeist Zählerständen) 
     * den jeweils letzten Tages- Wochen- Monats- und Jahreswert auszulesen und in
     * separate Datenpunkte zu schreiben. 
     * Damit erhält man besser auswertbare Daten eines Zeitraums und umgeht die nicht 
     * ausreichenden bzw. nicht vorhandenen Gruppierungsmöglichkeiten in Grafana.
     * 
     * In der Regel wird man diese Methode anwenden, wenn es keinen geräteseitigen Zählerstand gibt, 
     * etwa bei errechneten Werten und der "Source Analytics" Adapter nicht zur Anwendung kommen soll."
     * 
     * Die Funktionsweise:
     * Zuerst werden viertelstündlich die Zählerwerte (in Wm) aus den Quelldatenpunkten ausgelesen, in Wh umgerechnet und in die Datenpunkte 
     * "gesamt", "dieses Jahr", "dieser Monat", "diese Woche" und "heute" für die weitere Verarbeitung geschrieben.
     * Diese Werte werden alle 15 Minuten um die angefallene Different erhöht.
     * Jeweils um 23:59 eines jeden Tages wird der letzte Tageswert aus dem "heute" Datenpunkt gelesen und in den Datenpunkt "gestern" kopiert.
     * Jeweils um 23:59 jeden Sonntag wird der letzte Wert aus "diese_woche" in den Datenpunkt "letzte_woche" kopiert.
     * Jeweils am Monatsletzten um 23:59 wird der letzte Wert aus "dieser_monat" in den Datenpunkt "letzter_monat" kopiert.
     * Am 31.12. jedes Jahres um 23:59 wird der letzte Wert aus "dieses_jahr" in den Datenpunkt "letztes_jahr" kopiert.
     * Damit sind die Tages-, Wochen-, Monats- und Jahreswerte in sepataten Datenpunkten verfügbar.
     * 
     * Skript Name:      Tag-Woche-Monat-Jahr
     * Skript Version:   0.4
     * Erstell-Datum:    11. September 2024 | Last Update: 7.01.2025
     * 
     */
    
    // Datenpunkte, aus denen Tages- Wochen- Monats- und Jahreswerte erstellt werden sollen:
    var quelldatenpunkt = ["0_userdata.0.Einspeisung.PV-Erzeugung-Counter", "0_userdata.0.Einspeisung.PV-Eigenverbrauch-Counter", "0_userdata.0.Einspeisung.PV-Einspeisung-Counter"];
    var zieldatenpunkt = ["0_userdata.0.Einspeisung.PV-Erzeugung", "0_userdata.0.Einspeisung.PV-Eigenverbrauch", "0_userdata.0.Einspeisung.PV-Einspeisung"];
    var anz1;                   //Zähler für Quell- und Zieldatenpunkt Verzeichnisse
    var anz2;                   //Innerer Zähler für die Objekte (Zieldatenpunkte)
    var verbrauch_wm;           // Werte in Wm!!!
    var verbrauch;              // Umgewandelt in Wh!!!
    var ueberschreiben = false;
    var anzahl_updates = 0;
    var anzahl_reboots = 0;
    var anzahl_gleich = 0;
    
    // Datenpunkte neu erstellen unterhalb 0.userdata.0
    // Verbrauchs Objekte 
    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 = ["Gesamt", "Aktuelles Jahr", "Letztes Jahr", "Letzter Monat", "Aktueller Monat", "Letzte Woche", "Aktuelle Woche", "Gestern", "Heute", "Messwert alt", "Messwert neu"];
    
    datenpunkte_erstellen()
    
    // Erstelle die benötigten Datenpunkte
    function datenpunkte_erstellen() {
        // Anzahl der Quelldatenpunkt Ordner
        for (anz1 = 0; anz1 < quelldatenpunkt.length ; anz1++) {
            var initial_wert = 0.0;
            // Anzahl der neuen Datenpunkte
            for (anz2 = 0; anz2 < objekt.length; anz2++) {
                createState(zieldatenpunkt[anz1] + "." + objekt[anz2], initial_wert, ueberschreiben, {
                    name: beschreibung[anz2],
                    desc: beschreibung[anz2],
                    type: "number",
                    role: "value.power",
                    unit: "Wh"
                });
            }
        }
    }
    
    // Verbrauch alle 15 Min ermitteln
    function verbrauch_update() {
        anzahl_updates = 0;
        anzahl_reboots = 0;
        anzahl_gleich = 0;
        for (anz1 = 0; anz1 < quelldatenpunkt.length; anz1++) {
    		// Zählerwerte liegen in Wm vor und müssen erst in Wh umgewandelt werden
            verbrauch_wm  = getState(quelldatenpunkt[anz1]).val; 
    		// Runden auf 2 Stellen	
            verbrauch = Math.round(verbrauch_wm / 60*100) /100; 					
            if (verbrauch != null) {
                // Hole aktuellen Wert, um zu kontrollieren, ob ein Reboot stattgefunden hat
    			// In den Zieldatenpunkten liegen die Werte in der Einheit Wh vor
                var aktueller_wert = getState(zieldatenpunkt[anz1] + ".aktueller_wert").val;  
                var alter_wert = 0;
                // Prüfe alten und neuen Wert
                if (verbrauch > aktueller_wert) {
                    // Verbrauchswert ist größer als alter Wert -> es wurde kein Reboot durchgeführt
                    setState(zieldatenpunkt[anz1] + ".alter_wert", aktueller_wert, true);   		// "Aktueller Wert" wird aktualisiert
                    alter_wert = aktueller_wert;												// "Alter Wert" wird aktualisiert
                    anzahl_updates++;
                }
    			// Kommt nicht vor, da die Werte errechnet werden. Kein Gerät, das resettet werden könnte
                // 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 (verbrauch == aktueller_wert) {
                    // Verbrauchswert ist gleich dem alten Wert -> kein Update notwendig
                    alter_wert = aktueller_wert;
                    anzahl_gleich++;
                }
                 setState(zieldatenpunkt[anz1] + ".aktueller_wert", verbrauch, true);
                // Neuer Wert - alter Wert = aktuelle Differenz
                var differenz = parseFloat(verbrauch) - alter_wert;
                //console.log("Alter Wert = " + alter_wert);
                //console.log("Neuer Wert = " + verbrauch);
                //console.log("Differenz = " + differenz);
                
                // Tagesverbrauch aktualisieren
                aktualisiere_vebrauch_objekt(zieldatenpunkt[anz1], ".heute", differenz);
                // Wochenverbrauch aktualisieren
                aktualisiere_vebrauch_objekt(zieldatenpunkt[anz1], ".diese_woche", differenz);
                // Monatsverbrauch aktualisieren
                aktualisiere_vebrauch_objekt(zieldatenpunkt[anz1], ".dieser_monat", differenz);
                // Jahresverbrauch aktualisieren
                aktualisiere_vebrauch_objekt(zieldatenpunkt[anz1], ".dieses_jahr", differenz);
                // Gesamten Vebrauch aktualisieren
                aktualisiere_vebrauch_objekt(zieldatenpunkt[anz1], ".gesamt", differenz);
            }
        };
    }
    
    // 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);
    }
    
    function shelly_verbrauch_erster_start() {
        log("Shelly Verbrauch: Erster Start des Skriptes! Datenpunkte werden erstellt!");
        // Datenpunkte werden erstellt
        datenpunkte_erstellen();
    }
    
    // Userdatenpunkt
    var userdir = "0_userdata.0."; // Abschließender Punkt !!! WICHTIG !!!
    
    // Letzten des Monats berechnen.
    function letzterDesMonats(oHeute) {
        return new Date(oHeute.getFullYear(), oHeute.getMonth() + 1, 0).getDate();
    }
    
    // Shelly Verbrauch aktualisieren - nachts um 23:59 Uhr
    function verbrauch_tag() {
        // Nochmals das Tagesupdate durchlaufen, damit die restlichen Werte gelesen werden
        verbrauch_update();
        // Datumsvariable
        var heute = new Date();
        // Heute zu Gestern verschieben. Täglich um 23:59 Uhr
        verschiebe_verbrauch_objekt("heute", "gestern");
        log("Shelly Verbrauch: Werte für gestern und heute aktualisiert!");
        // aktuelle Woche in letzte Woche verschieben. Am Sonntag um 23:59 Uhr
        if (heute.getDay() === 0) {   // (Sonntag=0, Montag=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 letzten des Monats um 23:59 Uhr
        if (heute.getDate() === letzterDesMonats(heute)) {   /*line changed by spacerx*/
            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 letzten Tag des Jahres um 23:59 Uhr
        if (heute.getDate() === letzterDesMonats(heute) && heute.getMonth() === 11) { /*line changed by spacerx (Jan=0, Dez=11)*/
            verschiebe_verbrauch_objekt("dieses_jahr", "letztes_jahr");
            log("Shelly Verbrauch: Werte für dieses und letztes Jahr aktualisiert!");
        }
    }
    
    // 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) {
    	$('state[id=' + zieldatenpunkt(anz1)+ '*.*.' + von + ']').each(function (id, anz2) {	
            // 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);
        });
    }
    
    //Verschiebt das jeweilige Verbrauchs-Objekt und nullt den Ursprung (Tag, Woche, Monat, Jahr)
    function verschiebe_verbrauch_objekt(von, nach) {
        //$('state[id=' + userdir + datenpunkt + '*.*.' + von + ']').each(function (id, anz2) {   
    	$('state[id=' + zieldatenpunkt[anz1]+ '*.*.' + von + ']').each(function (id, anz2) {	
            // 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);
        });
    }
    
    // Erster Start und Initialisierung
    shelly_verbrauch_erster_start();
    
    // Alle 15 Minuten das Skript für den Tagesverbrauch ausführen
    schedule('*/15 * * * *', verbrauch_update);
    
    // Nachts um 23:59 Uhr werden die Werte in andere Variablen gespeichert, um den Verlauf zu erstellen
    schedule('59 23 * * *', verbrauch_tag);
    
    

    *Die virtuellen Zählerwerte errechne ich aus den Ertrags- und Einspeiseleistungen meiner PV, die jede Minute ermittelt werden. Mein Zähler zeigt leider nur die eingespeiste Leistung, aber nicht den zugehörigen Zählerstand an.

    Und da die Fragen sicher kommen werden:

    • Ich habe keine Möglichkeit, einen Shelly 3EM etc. unterzubringen und der Source Analytics Adapter soll auch nicht zum Einsatz kommen.
    • Und ja, ich könnte die „heute“ Werte auch manuell nach „gestern“ schreiben und anschließend nullen, dann hätte ich das Konstrukt aber immer noch nicht verstanden.

    Ich hoffe, ich konnte mein Anliegen verständlich beschreiben und hoffe auf Eure Hilfestellung.

    Gruß

    paul53P OliverIOO 2 Antworten Letzte Antwort
    0
    • O opöl

      Hallo zusammen,
      erst einmal ein verspätetes „Frohes neues Jahr“.

      Sorry, viel Text.

      Ich habe ein Problem mit einem Script, dass ich mit meinen Kenntnissen leider noch nicht in den Griff bekomme. Vielleicht kann mir da jemand auf die Sprünge helfen.

      Das hier bekannte Script des Users @skb mit den Ergänzungen von @SpacerX : „Shelly Verbrauchs-Historie für Tag, Woche, Monat, Jahr“ von hier:
      https://forum.iobroker.net/topic/37262/shelly-verbrauchs-historie-für-tag-woche-monat-jahr/82?_=1736424008402&lang=de
      habe ich seit langem erfolgreich im Einsatz und seit einem Jahr auch für Sonoff Geräte (z.B. für Nous A1T Steckdosen mit Tasmota) adaptiert. Läuft soweit prima. Hier für interessierte das Script für die Nous Steckdosen (leider noch nicht ganz aufgeräumt):

       /*
       *
       * Dieses Skript dient zur Verbrauchserfassung von Tasmota Geräten
       * Z.B. Nous Steckdosen oder auf Tasmota geflashte Shelly Geräte.
       * 
       * Das Script ermittelt aus dem Zählerstand der Geräte die Tages- Wochen- Monats- 
       * und Jahresverbräuche und legt diese in neuen Objekten unter "0_userdata.0.NousVerbrauch"
       * im iobroker ab. Damit ist eine einfachere grafische Darstellung und Auswertung möglich.
       * 
       * Die Verbreitung, Anpassung und Optimierung zu privaten Zwecken ist ausdrücklich gestattet.
       * 
       * Jegliche Verantwortung liegt beim Benutzer. 
       * 
       * 
       * Skript Name:      Nous-Verbrauch
       * Skript Version:   1.70  | 25. April 2024
       * Erstell-Datum:    08. Oktober 2023
       *
       * Das Script basiert auf dem Shelly-Verbrauch Script des Autors 
       * Stephan Kreyenborg sowie den Anpassungen von SpacerX.
       * 
       */
      
      // Datenpunkte neu erstellen
      var ueberschreiben = false;
      // Hauptdatenpunkt unterhalb javascript
      var datenpunkt = "NousVerbrauch."; // Abschließender Punkt !!! WICHTIG !!!
      // Verbrauchs Objekte der einzelnen Nous
      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 Nous", "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 Nous (Standard: sonoff.0)
      var Nous_dp = "sonoff.0";
      // Datenpunkte der Nous (!!! Bitte nicht ändern !!!)
      var NousDps = $('state[id=' + Nous_dp + '.*.*.Total]');  
      // Datenpunkte der Nous Namen (!!! Bitte nicht ändern !!!)
      var NousDpsName = $('state[id=' + Nous_dp + '.*.name]');
      // Nous Verbrauch aktualisieren - nachts um 00:00 Uhr
      function Nous_vebrauch_tag() {
          // Nochmals das Tagesupdate durchlaufen, damit die restlichen Werte gelesen werden
          Nous_verbrauch_update();
          // Datumsvariable
          var heute = new Date();
          // Heute zu Gestern verschieben. Täglich um 00:00 Uhr
          verschiebe_verbrauch_objekt("heute", "gestern");
          log("Nous 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("Nous 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("Nous 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("Nous Verbrauch: Werte für dieses und letztes Jahr aktualisiert!");
          }
      }
      // Tagesverbrauch alle 15 Min von der Original Variable des Nous in eigene Variable kopieren
      function Nous_verbrauch_update() {
          var anzahl_updates = 0;
          var anzahl_reboots = 0;
          var anzahl_gleich = 0;
          NousDps.each(function (id, i) {
              //var Nous_verbrauch = getState(id).val; 
              var Nous_verbrauch = 1000 * getState(id).val; // Nous Steckdoesen geben die Leistungswerte in kWH an, Shellys in Wh
              if (Nous_verbrauch != null) {
                  // Hole aktuellen Wert, um zu kontrollieren, ob ein Reboot stattgefunden hat
                  var aktueller_wert = getState(Nous_DP(id) + "aktueller_wert").val;
                  var alter_wert = 0;
                  // Prüfe alten und neuen Wert
                  if (Nous_verbrauch > aktueller_wert) {
                      // Verbrauchswert ist größer als alter Wert -> es wurde kein Reboot durchgeführt
                      setState(Nous_DP(id) + "alter_wert", aktueller_wert, true);
                      alter_wert = aktueller_wert;
                      anzahl_updates++;
                  }
                  
      
                  if (aktueller_wert > Nous_verbrauch) {
                      // Verbrauchswert ist kleiner als alter Wert -> es wurde ein Reboot durchgeführt
                      // setState(Nous_DP(id) + "alter_wert", 0, true);
                      // alter_wert = 0;
                      alter_wert = aktueller_wert; // Um Rechenfegler durch fehlende Messwerte zu verhindern
                      anzahl_reboots++;
                  }
      
                  if (Nous_verbrauch == aktueller_wert) {
                      // Verbrauchswert ist gleich altem Wert -> kein Update notwendig
                      alter_wert = aktueller_wert;
                      anzahl_gleich++;
                  }
                  setState(Nous_DP(id) + "aktueller_wert", Nous_verbrauch, true);
                  // Alter und neuer Wert -> aktuelle Differenz
                  var verbrauch = parseFloat(Nous_verbrauch) - alter_wert;
                  // Tagesverbrauch aktualisieren
                  aktualisiere_vebrauch_objekt(Nous_DP(id), "heute", verbrauch);
                  // Wochenverbrauch aktualisieren
                  aktualisiere_vebrauch_objekt(Nous_DP(id), "diese_woche", verbrauch);
                  // Monatsverbrauch aktualisieren
                  aktualisiere_vebrauch_objekt(Nous_DP(id), "dieser_monat", verbrauch);
                  // Jahresverbrauch aktualisieren
                  aktualisiere_vebrauch_objekt(Nous_DP(id), "dieses_jahr", verbrauch);
                  // Gesamten Vebrauch aktualisieren
                  aktualisiere_vebrauch_objekt(Nous_DP(id), "gesamt", verbrauch);
              }
          });
          
          aktualisiere_namen();
          log("Nous 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 Nous abzuholen
      function aktualisiere_namen() {
          if (typeof extendObject === "function") {
              NousDpsName.each(function (id, i) {
                  if (existsState(id)) {
                      setState(Nous_DP_Name(id), String(getState(id).val), true);
                      extendObject("javascript.0." + Nous_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 Nous
          var anzahl = NousDps.length;
      log("Nous Datenpukte erstellt: " + anzahl);	    
          NousDps.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(Nous_DP(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("Nous Verbrauch: Datenpunkte erstellt! Erster Verbrauch steht nach 30 Sekunden zur Verfügung! Anzahl gefundener Nous Datenpunkte: " + anzahl );
          setTimeout(Nous_verbrauch_update, 30000);
          // Datenpunkte für die Namen der Nous erstellen
          NousDpsName.each(function (id, j) {
              createState(Nous_DP_Name(id), "", ueberschreiben, {
                  name: "Name des Nous",
                  desc: "Name des Nous",
                  type: "string",
                  role: "value",
                  unit: ""
              });
          });
      }
      /**
       * Wenn 3EM DP, dann anderen Wert zurückgeben
       * @param {any} dp
       * @param {boolean} extended
       */
      function Nous_DP(dp, extended = false) {
          dp = dp.split(".");
          dp = datenpunkt + dp[2] + "." + dp[3];
          if (extended) {
              dp = dp + "_Returned.";
          } else {
              dp = dp + ".";
          }
          return dp;
      }
      function Nous_DP_Name(dp) {
          dp = dp.split(".");
          dp = datenpunkt + dp[2] + "." + dp[3];
          return dp;
      }
      function Nous_DP_Name_Main(dp) {
          dp = dp.split(".");
          dp = datenpunkt + dp[2];
          return dp;
      }
      function Nous_verbrauch_erster_start() {
          log("Nous Verbrauch: Erster Start des Skriptes! Datenpunkte werden erstellt!");
          // Datenpunkte werden erstellt
          datenpunkte_erstellen();
      }
      /*
       * Override Functions
       * @autor 2022 SpacerX <spacerx@rbe-base.de>
       * Überschreibt Funktionen um Datenpunkte unter 0_userdata.0 zu erstellen
       *
       *** START SpacerX ***/
      // Userdatenpunkt
      var userdir = "0_userdata.0."; // Abschließender Punkt !!! WICHTIG !!!
      /**
       * Letzten des Monats berechnen.
       * @param {Date} oHeute
       */
      function letzterDesMonats(oHeute) {
          return new Date(oHeute.getFullYear(), oHeute.getMonth() + 1, 0).getDate();
      }
      //Override at row 48
      // Nous Verbrauch aktualisieren - nachts um 23:59 Uhr
      function Nous_vebrauch_tag() {
          // Nochmals das Tagesupdate durchlaufen, damit die restlichen Werte gelesen werden
          Nous_verbrauch_update();
          // Datumsvariable
          var heute = new Date();
          // Heute zu Gestern verschieben. Täglich um 23:59 Uhr
          verschiebe_verbrauch_objekt("heute", "gestern");
          log("Nous Verbrauch: Werte für gestern und heute aktualisiert!");
          // aktuelle Woche in letzte Woche verschieben. Am Sonntag um 23:59 Uhr
          if (heute.getDay() === 0) {   /*line changed by spacerx (Sonntag=0, Montag=1)*/
              verschiebe_verbrauch_objekt("diese_woche", "letzte_woche");
              log("Nous Verbrauch: Werte für diese und letzte Woche aktualisiert!");
          }
          // aktueller Monat in letzten Monat verschieben. Am letzten des Monats um 23:59 Uhr
          if (heute.getDate() === letzterDesMonats(heute)) {   /*line changed by spacerx*/
              verschiebe_verbrauch_objekt("dieser_monat", "letzter_monat");
              log("Nous Verbrauch: Werte für diesen und letzten Monat aktualisiert!");
          }
          // aktuelles Jahr in letztes Jahr verschieben. Am letzten Tag des Jahres um 23:59 Uhr
          if (heute.getDate() === letzterDesMonats(heute) && heute.getMonth() === 11) { /*line changed by spacerx (Jan=0, Dez=11)*/
              verschiebe_verbrauch_objekt("dieses_jahr", "letztes_jahr");
              log("Nous Verbrauch: Werte für dieses und letztes Jahr aktualisiert!");
          }
      }
      //Override at row 254
      //Verschiebt das jeweilige Verbrauchs-Objekt und nullt den Ursprung (Tag, Woche, Monat, Jahr)
      function verschiebe_verbrauch_objekt(von, nach) {
          $('state[id=' + userdir + datenpunkt + '*.*.' + von + ']').each(function (id, i) {   /*line changed by spacerx*/
              // 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);
          });
      }
      //Override at row 267
      // Funktion um die aktuellen Namen des Nous abzuholen
      function aktualisiere_namen() {
          if (typeof extendObject === "function") {
              NousDpsName.each(function (id, i) {
                  if (existsState(id)) {
                      setState(Nous_DP_Name(id), String(getState(id).val), true);
                      extendObject(Nous_DP_Name_Main(id), {   /*line changed by spacerx*/
                          common: {
                              name: String(getState(id).val),
                              desc: String(getState(id).val)
                          },
                          type: "channel"
                      });
                  }
              });
          }
      }
      //Override at row 377
      function Nous_DP(dp, extended = false) {
          dp = dp.split(".");
          dp = userdir + datenpunkt + dp[2] + "." + dp[3];   /*line changed by spacerx*/
          if (extended) {
              dp = dp + "_Returned.";
          } else {
              dp = dp + ".";
          }
          return dp;
      }
      //Override at row 387
      function Nous_DP_Name(dp) {
          dp = dp.split(".");
          dp = userdir + datenpunkt + dp[2] + "." + dp[3];   /*line changed by spacerx*/
          return dp;
      }
      //Override at row 392
      function Nous_DP_Name_Main(dp) {
          dp = dp.split(".");
          dp = userdir + datenpunkt + dp[2];   /*line changed by spacerx*/
          return dp;
      }
      /*** END SpacerX ***/
      // Erster Start und Initialisierung
      Nous_verbrauch_erster_start();
      // Alle 15 Minuten das Skript für den Tagesverbrauch ausführen
      schedule('*/15 * * * *', Nous_verbrauch_update);
      /*** START Edit SpacerX ***/
      // Nachts um 24 Uhr werden die Werte in andere Variablen gespeichert, um den Verlauf zu erstellen
      //schedule('0 0 * * *', Nous_vebrauch_tag);
      // Nachts um 23:59 Uhr werden die Werte in andere Variablen gespeichert, um den Verlauf zu erstellen
      schedule('59 23 * * *', Nous_vebrauch_tag);
      /*** END Edit SpacerX ***/
      

      Nun möchte ich dieses Script so adaptieren, dass für von mir in einem Array vorgegebene (virtuelle) Zählerwerte* die Tages-, Wochen-, Monats- und Jahreswerte ermittelt und in die entsprechenden Datenpunkte geschrieben werden. Das klappt auch soweit bis auf das Verschieben der Werte „heute -> gestern“, „diese Woche -> letzte Woche“ etc. Die zuständige Routine verstehe ich leider nicht. Es sollte die Funktion ab Zeile 175 in diesem Script sein:
      function verschiebe_verbrauch_objekt(von, nach) {

      /*
       * Dieses Script dient dazu, aus definierten Datenpunkten (zumeist Zählerständen) 
       * den jeweils letzten Tages- Wochen- Monats- und Jahreswert auszulesen und in
       * separate Datenpunkte zu schreiben. 
       * Damit erhält man besser auswertbare Daten eines Zeitraums und umgeht die nicht 
       * ausreichenden bzw. nicht vorhandenen Gruppierungsmöglichkeiten in Grafana.
       * 
       * In der Regel wird man diese Methode anwenden, wenn es keinen geräteseitigen Zählerstand gibt, 
       * etwa bei errechneten Werten und der "Source Analytics" Adapter nicht zur Anwendung kommen soll."
       * 
       * Die Funktionsweise:
       * Zuerst werden viertelstündlich die Zählerwerte (in Wm) aus den Quelldatenpunkten ausgelesen, in Wh umgerechnet und in die Datenpunkte 
       * "gesamt", "dieses Jahr", "dieser Monat", "diese Woche" und "heute" für die weitere Verarbeitung geschrieben.
       * Diese Werte werden alle 15 Minuten um die angefallene Different erhöht.
       * Jeweils um 23:59 eines jeden Tages wird der letzte Tageswert aus dem "heute" Datenpunkt gelesen und in den Datenpunkt "gestern" kopiert.
       * Jeweils um 23:59 jeden Sonntag wird der letzte Wert aus "diese_woche" in den Datenpunkt "letzte_woche" kopiert.
       * Jeweils am Monatsletzten um 23:59 wird der letzte Wert aus "dieser_monat" in den Datenpunkt "letzter_monat" kopiert.
       * Am 31.12. jedes Jahres um 23:59 wird der letzte Wert aus "dieses_jahr" in den Datenpunkt "letztes_jahr" kopiert.
       * Damit sind die Tages-, Wochen-, Monats- und Jahreswerte in sepataten Datenpunkten verfügbar.
       * 
       * Skript Name:      Tag-Woche-Monat-Jahr
       * Skript Version:   0.4
       * Erstell-Datum:    11. September 2024 | Last Update: 7.01.2025
       * 
       */
      
      // Datenpunkte, aus denen Tages- Wochen- Monats- und Jahreswerte erstellt werden sollen:
      var quelldatenpunkt = ["0_userdata.0.Einspeisung.PV-Erzeugung-Counter", "0_userdata.0.Einspeisung.PV-Eigenverbrauch-Counter", "0_userdata.0.Einspeisung.PV-Einspeisung-Counter"];
      var zieldatenpunkt = ["0_userdata.0.Einspeisung.PV-Erzeugung", "0_userdata.0.Einspeisung.PV-Eigenverbrauch", "0_userdata.0.Einspeisung.PV-Einspeisung"];
      var anz1;                   //Zähler für Quell- und Zieldatenpunkt Verzeichnisse
      var anz2;                   //Innerer Zähler für die Objekte (Zieldatenpunkte)
      var verbrauch_wm;           // Werte in Wm!!!
      var verbrauch;              // Umgewandelt in Wh!!!
      var ueberschreiben = false;
      var anzahl_updates = 0;
      var anzahl_reboots = 0;
      var anzahl_gleich = 0;
      
      // Datenpunkte neu erstellen unterhalb 0.userdata.0
      // Verbrauchs Objekte 
      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 = ["Gesamt", "Aktuelles Jahr", "Letztes Jahr", "Letzter Monat", "Aktueller Monat", "Letzte Woche", "Aktuelle Woche", "Gestern", "Heute", "Messwert alt", "Messwert neu"];
      
      datenpunkte_erstellen()
      
      // Erstelle die benötigten Datenpunkte
      function datenpunkte_erstellen() {
          // Anzahl der Quelldatenpunkt Ordner
          for (anz1 = 0; anz1 < quelldatenpunkt.length ; anz1++) {
              var initial_wert = 0.0;
              // Anzahl der neuen Datenpunkte
              for (anz2 = 0; anz2 < objekt.length; anz2++) {
                  createState(zieldatenpunkt[anz1] + "." + objekt[anz2], initial_wert, ueberschreiben, {
                      name: beschreibung[anz2],
                      desc: beschreibung[anz2],
                      type: "number",
                      role: "value.power",
                      unit: "Wh"
                  });
              }
          }
      }
      
      // Verbrauch alle 15 Min ermitteln
      function verbrauch_update() {
          anzahl_updates = 0;
          anzahl_reboots = 0;
          anzahl_gleich = 0;
          for (anz1 = 0; anz1 < quelldatenpunkt.length; anz1++) {
      		// Zählerwerte liegen in Wm vor und müssen erst in Wh umgewandelt werden
              verbrauch_wm  = getState(quelldatenpunkt[anz1]).val; 
      		// Runden auf 2 Stellen	
              verbrauch = Math.round(verbrauch_wm / 60*100) /100; 					
              if (verbrauch != null) {
                  // Hole aktuellen Wert, um zu kontrollieren, ob ein Reboot stattgefunden hat
      			// In den Zieldatenpunkten liegen die Werte in der Einheit Wh vor
                  var aktueller_wert = getState(zieldatenpunkt[anz1] + ".aktueller_wert").val;  
                  var alter_wert = 0;
                  // Prüfe alten und neuen Wert
                  if (verbrauch > aktueller_wert) {
                      // Verbrauchswert ist größer als alter Wert -> es wurde kein Reboot durchgeführt
                      setState(zieldatenpunkt[anz1] + ".alter_wert", aktueller_wert, true);   		// "Aktueller Wert" wird aktualisiert
                      alter_wert = aktueller_wert;												// "Alter Wert" wird aktualisiert
                      anzahl_updates++;
                  }
      			// Kommt nicht vor, da die Werte errechnet werden. Kein Gerät, das resettet werden könnte
                  // 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 (verbrauch == aktueller_wert) {
                      // Verbrauchswert ist gleich dem alten Wert -> kein Update notwendig
                      alter_wert = aktueller_wert;
                      anzahl_gleich++;
                  }
                   setState(zieldatenpunkt[anz1] + ".aktueller_wert", verbrauch, true);
                  // Neuer Wert - alter Wert = aktuelle Differenz
                  var differenz = parseFloat(verbrauch) - alter_wert;
                  //console.log("Alter Wert = " + alter_wert);
                  //console.log("Neuer Wert = " + verbrauch);
                  //console.log("Differenz = " + differenz);
                  
                  // Tagesverbrauch aktualisieren
                  aktualisiere_vebrauch_objekt(zieldatenpunkt[anz1], ".heute", differenz);
                  // Wochenverbrauch aktualisieren
                  aktualisiere_vebrauch_objekt(zieldatenpunkt[anz1], ".diese_woche", differenz);
                  // Monatsverbrauch aktualisieren
                  aktualisiere_vebrauch_objekt(zieldatenpunkt[anz1], ".dieser_monat", differenz);
                  // Jahresverbrauch aktualisieren
                  aktualisiere_vebrauch_objekt(zieldatenpunkt[anz1], ".dieses_jahr", differenz);
                  // Gesamten Vebrauch aktualisieren
                  aktualisiere_vebrauch_objekt(zieldatenpunkt[anz1], ".gesamt", differenz);
              }
          };
      }
      
      // 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);
      }
      
      function shelly_verbrauch_erster_start() {
          log("Shelly Verbrauch: Erster Start des Skriptes! Datenpunkte werden erstellt!");
          // Datenpunkte werden erstellt
          datenpunkte_erstellen();
      }
      
      // Userdatenpunkt
      var userdir = "0_userdata.0."; // Abschließender Punkt !!! WICHTIG !!!
      
      // Letzten des Monats berechnen.
      function letzterDesMonats(oHeute) {
          return new Date(oHeute.getFullYear(), oHeute.getMonth() + 1, 0).getDate();
      }
      
      // Shelly Verbrauch aktualisieren - nachts um 23:59 Uhr
      function verbrauch_tag() {
          // Nochmals das Tagesupdate durchlaufen, damit die restlichen Werte gelesen werden
          verbrauch_update();
          // Datumsvariable
          var heute = new Date();
          // Heute zu Gestern verschieben. Täglich um 23:59 Uhr
          verschiebe_verbrauch_objekt("heute", "gestern");
          log("Shelly Verbrauch: Werte für gestern und heute aktualisiert!");
          // aktuelle Woche in letzte Woche verschieben. Am Sonntag um 23:59 Uhr
          if (heute.getDay() === 0) {   // (Sonntag=0, Montag=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 letzten des Monats um 23:59 Uhr
          if (heute.getDate() === letzterDesMonats(heute)) {   /*line changed by spacerx*/
              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 letzten Tag des Jahres um 23:59 Uhr
          if (heute.getDate() === letzterDesMonats(heute) && heute.getMonth() === 11) { /*line changed by spacerx (Jan=0, Dez=11)*/
              verschiebe_verbrauch_objekt("dieses_jahr", "letztes_jahr");
              log("Shelly Verbrauch: Werte für dieses und letztes Jahr aktualisiert!");
          }
      }
      
      // 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) {
      	$('state[id=' + zieldatenpunkt(anz1)+ '*.*.' + von + ']').each(function (id, anz2) {	
              // 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);
          });
      }
      
      //Verschiebt das jeweilige Verbrauchs-Objekt und nullt den Ursprung (Tag, Woche, Monat, Jahr)
      function verschiebe_verbrauch_objekt(von, nach) {
          //$('state[id=' + userdir + datenpunkt + '*.*.' + von + ']').each(function (id, anz2) {   
      	$('state[id=' + zieldatenpunkt[anz1]+ '*.*.' + von + ']').each(function (id, anz2) {	
              // 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);
          });
      }
      
      // Erster Start und Initialisierung
      shelly_verbrauch_erster_start();
      
      // Alle 15 Minuten das Skript für den Tagesverbrauch ausführen
      schedule('*/15 * * * *', verbrauch_update);
      
      // Nachts um 23:59 Uhr werden die Werte in andere Variablen gespeichert, um den Verlauf zu erstellen
      schedule('59 23 * * *', verbrauch_tag);
      
      

      *Die virtuellen Zählerwerte errechne ich aus den Ertrags- und Einspeiseleistungen meiner PV, die jede Minute ermittelt werden. Mein Zähler zeigt leider nur die eingespeiste Leistung, aber nicht den zugehörigen Zählerstand an.

      Und da die Fragen sicher kommen werden:

      • Ich habe keine Möglichkeit, einen Shelly 3EM etc. unterzubringen und der Source Analytics Adapter soll auch nicht zum Einsatz kommen.
      • Und ja, ich könnte die „heute“ Werte auch manuell nach „gestern“ schreiben und anschließend nullen, dann hätte ich das Konstrukt aber immer noch nicht verstanden.

      Ich hoffe, ich konnte mein Anliegen verständlich beschreiben und hoffe auf Eure Hilfestellung.

      Gruß

      paul53P Offline
      paul53P Offline
      paul53
      schrieb am zuletzt editiert von paul53
      #2

      @opöl sagte: Funktion ab Zeile 175 in diesem Script

      Die Funktion ist doppelt enthalten (auch ab Zeile 190).
      So ist die Funktion etwas übersichtlicher:

      function verschiebe_verbrauch_objekt(von, nach) {
          $(userdir + datenpunkt + '*.*.' + von).each(function (id) {   /*line changed by spacerx*/
              const verbrauch = getState(id).val;
              if (verbrauch != null) {
                  setState(id.replace(von, nach), verbrauch, true); // Schreibe Verbrauch in "nach"
              }
              setState(id, 0, true); // Setze "von" zurück
          });
      }
      

      Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
      Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

      O 1 Antwort Letzte Antwort
      0
      • paul53P paul53

        @opöl sagte: Funktion ab Zeile 175 in diesem Script

        Die Funktion ist doppelt enthalten (auch ab Zeile 190).
        So ist die Funktion etwas übersichtlicher:

        function verschiebe_verbrauch_objekt(von, nach) {
            $(userdir + datenpunkt + '*.*.' + von).each(function (id) {   /*line changed by spacerx*/
                const verbrauch = getState(id).val;
                if (verbrauch != null) {
                    setState(id.replace(von, nach), verbrauch, true); // Schreibe Verbrauch in "nach"
                }
                setState(id, 0, true); // Setze "von" zurück
            });
        }
        
        O Offline
        O Offline
        opöl
        schrieb am zuletzt editiert von
        #3

        @paul53 ,

        Oops, ist mir entgangen. Habe ich korrigiert. Typischer Fall von Betriebsblindheit. Sorry.

        Das alleine kann es aber nicht gewesen sein, der DP heute ist ja letzte Nacht nicht genullt worden. Das Script läuft ohne Fehler.

        Kannst Du mir die fragliche Funktion entschlüsseln?
        Wenn ich sie verstehe, komme ich vielleicht weiter.
        Wie ich schrieb, geht es mir hauptsächlich um den Lerneffekt.

        Gruß

        paul53P 1 Antwort Letzte Antwort
        0
        • O opöl

          @paul53 ,

          Oops, ist mir entgangen. Habe ich korrigiert. Typischer Fall von Betriebsblindheit. Sorry.

          Das alleine kann es aber nicht gewesen sein, der DP heute ist ja letzte Nacht nicht genullt worden. Das Script läuft ohne Fehler.

          Kannst Du mir die fragliche Funktion entschlüsseln?
          Wenn ich sie verstehe, komme ich vielleicht weiter.
          Wie ich schrieb, geht es mir hauptsächlich um den Lerneffekt.

          Gruß

          paul53P Offline
          paul53P Offline
          paul53
          schrieb am zuletzt editiert von paul53
          #4

          @opöl sagte: Wenn ich sie verstehe, komme ich vielleicht weiter.

          Ich habe Kommentar ergänzt.
          Wo wird die Variable datenpunkt deklariert und gesetzt? Habe ich nicht gefunden.
          Funktioniert es so?

          function verschiebe_verbrauch_objekt(von, nach) {
              $(userdir + 'Einspeisung.*.' + von).each(function (id) { 
                  const verbrauch = getState(id).val;
                  if (verbrauch != null) {
                      setState(id.replace(von, nach), verbrauch, true); // Schreibe Verbrauch in "nach"
                  }
                  setState(id, 0, true); // Setze "von" zurück
              });
          }
          

          Überprüfe den Selektor mit

          log($(userdir + 'Einspeisung.*.heute'));
          

          am Skriptende.

          Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
          Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

          O 1 Antwort Letzte Antwort
          0
          • paul53P paul53

            @opöl sagte: Wenn ich sie verstehe, komme ich vielleicht weiter.

            Ich habe Kommentar ergänzt.
            Wo wird die Variable datenpunkt deklariert und gesetzt? Habe ich nicht gefunden.
            Funktioniert es so?

            function verschiebe_verbrauch_objekt(von, nach) {
                $(userdir + 'Einspeisung.*.' + von).each(function (id) { 
                    const verbrauch = getState(id).val;
                    if (verbrauch != null) {
                        setState(id.replace(von, nach), verbrauch, true); // Schreibe Verbrauch in "nach"
                    }
                    setState(id, 0, true); // Setze "von" zurück
                });
            }
            

            Überprüfe den Selektor mit

            log($(userdir + 'Einspeisung.*.heute'));
            

            am Skriptende.

            O Offline
            O Offline
            opöl
            schrieb am zuletzt editiert von
            #5

            @paul53 ,

            "userdir" + "datenpunkt" sind Benamsungen aus dem originalen Script. Die habe ich auskommentiert (vielleicht nicht komplett), weil sich sie in meinem Script nicht verwende.
            Meine Quell- und Zieldatenpunktordner sind:

            var quelldatenpunkt = ["0_userdata.0.Einspeisung.PV-Erzeugung-Counter", "0_userdata.0.Einspeisung.PV-Eigenverbrauch-Counter", "0_userdata.0.Einspeisung.PV-Einspeisung-Counter"];
            var zieldatenpunkt = ["0_userdata.0.Einspeisung.PV-Erzeugung", "0_userdata.0.Einspeisung.PV-Eigenverbrauch", "0_userdata.0.Einspeisung.PV-Einspeisung"];
            

            indiziert mit dem index (anz1) sowie den daran hängenden Datenpunkten

            var objekt = ["gesamt", "dieses_jahr", "letztes_jahr", "letzter_monat", "dieser_monat", "letzte_woche", "diese_woche", "gestern", "heute", "alter_wert", "aktueller_wert"];
            

            indiziert mit dem Index (anz2).

            Daher hatte ich es in Zeile 177 mit

            $('state[id=' + zieldatenpunkt[anz1]+ '*.*.' + von + ']').each(function (id, anz2) {
            

            versucht, was aber nicht klappt.

            Ich möchte also einen Wert von z.B.

            zieldatenpunkt[anz1].heute 
            

            nach

            zieldatenpunkt[anz1].gestern 
            

            verschieben und dann

            zieldatenpunkt[anz1].heute 
            

            auf "0" setzen.

            Und das ganze dann in einer Schleife für die Zieldatenpunkte 1-3 aus dem 1. Array und für die Objekte heute, diese_woche- dieser_monat und dieses_jahr.

            Und genau da komme ich mit der Funktion ins schleudern, weil ich die Syntax nicht blicke.

            Vielleicht habe ich mich da missverständlich ausgedrückt.

            Gruß

            paul53P 1 Antwort Letzte Antwort
            0
            • O opöl

              @paul53 ,

              "userdir" + "datenpunkt" sind Benamsungen aus dem originalen Script. Die habe ich auskommentiert (vielleicht nicht komplett), weil sich sie in meinem Script nicht verwende.
              Meine Quell- und Zieldatenpunktordner sind:

              var quelldatenpunkt = ["0_userdata.0.Einspeisung.PV-Erzeugung-Counter", "0_userdata.0.Einspeisung.PV-Eigenverbrauch-Counter", "0_userdata.0.Einspeisung.PV-Einspeisung-Counter"];
              var zieldatenpunkt = ["0_userdata.0.Einspeisung.PV-Erzeugung", "0_userdata.0.Einspeisung.PV-Eigenverbrauch", "0_userdata.0.Einspeisung.PV-Einspeisung"];
              

              indiziert mit dem index (anz1) sowie den daran hängenden Datenpunkten

              var objekt = ["gesamt", "dieses_jahr", "letztes_jahr", "letzter_monat", "dieser_monat", "letzte_woche", "diese_woche", "gestern", "heute", "alter_wert", "aktueller_wert"];
              

              indiziert mit dem Index (anz2).

              Daher hatte ich es in Zeile 177 mit

              $('state[id=' + zieldatenpunkt[anz1]+ '*.*.' + von + ']').each(function (id, anz2) {
              

              versucht, was aber nicht klappt.

              Ich möchte also einen Wert von z.B.

              zieldatenpunkt[anz1].heute 
              

              nach

              zieldatenpunkt[anz1].gestern 
              

              verschieben und dann

              zieldatenpunkt[anz1].heute 
              

              auf "0" setzen.

              Und das ganze dann in einer Schleife für die Zieldatenpunkte 1-3 aus dem 1. Array und für die Objekte heute, diese_woche- dieser_monat und dieses_jahr.

              Und genau da komme ich mit der Funktion ins schleudern, weil ich die Syntax nicht blicke.

              Vielleicht habe ich mich da missverständlich ausgedrückt.

              Gruß

              paul53P Offline
              paul53P Offline
              paul53
              schrieb am zuletzt editiert von paul53
              #6

              @opöl sagte: was aber nicht klappt.

              Woher kommt anz1?
              So funktioniert der Selektor nicht. Prüfe den von mir geposteten Selektor. Er sollte 3 Datenpunkt-IDs mit "heute" liefern.

              $(userdir + 'Einspeisung.*.heute').each(function(id) {
                  log(id);
              });
              

              Wenn du das Array zieldatenpunkt verwenden willst, musst du es direkt mit dem Array machen:

              function verschiebe_verbrauch_objekt(von, nach) {
                  zieldatenpunkt.forEach(function(id) { 
                      const verbrauch = getState(id + '.' + von).val;
                      if (verbrauch != null) {
                          setState(id + '.' + nach), verbrauch, true); // Schreibe Verbrauch in "nach"
                      }
                      setState(id + '.' + von, 0, true); // Setze "von" zurück
                  });
              }
              

              oder mit Schleife "for of"

              function verschiebe_verbrauch_objekt(von, nach) {
                  for(let id of zieldatenpunkt) { 
                      const verbrauch = getState(id + '.' + von).val;
                      if (verbrauch != null) {
                          setState(id + '.' + nach), verbrauch, true); // Schreibe Verbrauch in "nach"
                      }
                      setState(id + '.' + von, 0, true); // Setze "von" zurück
                  }
              }
              

              Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
              Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

              O 1 Antwort Letzte Antwort
              1
              • paul53P paul53

                @opöl sagte: was aber nicht klappt.

                Woher kommt anz1?
                So funktioniert der Selektor nicht. Prüfe den von mir geposteten Selektor. Er sollte 3 Datenpunkt-IDs mit "heute" liefern.

                $(userdir + 'Einspeisung.*.heute').each(function(id) {
                    log(id);
                });
                

                Wenn du das Array zieldatenpunkt verwenden willst, musst du es direkt mit dem Array machen:

                function verschiebe_verbrauch_objekt(von, nach) {
                    zieldatenpunkt.forEach(function(id) { 
                        const verbrauch = getState(id + '.' + von).val;
                        if (verbrauch != null) {
                            setState(id + '.' + nach), verbrauch, true); // Schreibe Verbrauch in "nach"
                        }
                        setState(id + '.' + von, 0, true); // Setze "von" zurück
                    });
                }
                

                oder mit Schleife "for of"

                function verschiebe_verbrauch_objekt(von, nach) {
                    for(let id of zieldatenpunkt) { 
                        const verbrauch = getState(id + '.' + von).val;
                        if (verbrauch != null) {
                            setState(id + '.' + nach), verbrauch, true); // Schreibe Verbrauch in "nach"
                        }
                        setState(id + '.' + von, 0, true); // Setze "von" zurück
                    }
                }
                
                O Offline
                O Offline
                opöl
                schrieb am zuletzt editiert von
                #7

                @paul53 ,

                die Variablen anz1 und anz2 sind in Zeile 30/31 definiert und indizieren die Objekte in den Arrays. Siehe ab Zeile 48 „Anlegen der Datenpunkte“.
                Wenn ich so drüber nachdenke, muss eigentlich zieldatenpunkt(anz1).objekt(8) nach
                zieldatenpunkt(anz1).objekt(7) in einer Schleife von anz1 =0 bis anz1= 2 verschoben werden, also von heute nach gestern. Der 1. Wert im Array hat ja den Index 0.

                Ich kann Deinen Vorschlag erst morgen testen. Ich melde mich dann. Vielen Dank erst einmal.

                Gruß

                1 Antwort Letzte Antwort
                0
                • O opöl

                  Hallo zusammen,
                  erst einmal ein verspätetes „Frohes neues Jahr“.

                  Sorry, viel Text.

                  Ich habe ein Problem mit einem Script, dass ich mit meinen Kenntnissen leider noch nicht in den Griff bekomme. Vielleicht kann mir da jemand auf die Sprünge helfen.

                  Das hier bekannte Script des Users @skb mit den Ergänzungen von @SpacerX : „Shelly Verbrauchs-Historie für Tag, Woche, Monat, Jahr“ von hier:
                  https://forum.iobroker.net/topic/37262/shelly-verbrauchs-historie-für-tag-woche-monat-jahr/82?_=1736424008402&lang=de
                  habe ich seit langem erfolgreich im Einsatz und seit einem Jahr auch für Sonoff Geräte (z.B. für Nous A1T Steckdosen mit Tasmota) adaptiert. Läuft soweit prima. Hier für interessierte das Script für die Nous Steckdosen (leider noch nicht ganz aufgeräumt):

                   /*
                   *
                   * Dieses Skript dient zur Verbrauchserfassung von Tasmota Geräten
                   * Z.B. Nous Steckdosen oder auf Tasmota geflashte Shelly Geräte.
                   * 
                   * Das Script ermittelt aus dem Zählerstand der Geräte die Tages- Wochen- Monats- 
                   * und Jahresverbräuche und legt diese in neuen Objekten unter "0_userdata.0.NousVerbrauch"
                   * im iobroker ab. Damit ist eine einfachere grafische Darstellung und Auswertung möglich.
                   * 
                   * Die Verbreitung, Anpassung und Optimierung zu privaten Zwecken ist ausdrücklich gestattet.
                   * 
                   * Jegliche Verantwortung liegt beim Benutzer. 
                   * 
                   * 
                   * Skript Name:      Nous-Verbrauch
                   * Skript Version:   1.70  | 25. April 2024
                   * Erstell-Datum:    08. Oktober 2023
                   *
                   * Das Script basiert auf dem Shelly-Verbrauch Script des Autors 
                   * Stephan Kreyenborg sowie den Anpassungen von SpacerX.
                   * 
                   */
                  
                  // Datenpunkte neu erstellen
                  var ueberschreiben = false;
                  // Hauptdatenpunkt unterhalb javascript
                  var datenpunkt = "NousVerbrauch."; // Abschließender Punkt !!! WICHTIG !!!
                  // Verbrauchs Objekte der einzelnen Nous
                  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 Nous", "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 Nous (Standard: sonoff.0)
                  var Nous_dp = "sonoff.0";
                  // Datenpunkte der Nous (!!! Bitte nicht ändern !!!)
                  var NousDps = $('state[id=' + Nous_dp + '.*.*.Total]');  
                  // Datenpunkte der Nous Namen (!!! Bitte nicht ändern !!!)
                  var NousDpsName = $('state[id=' + Nous_dp + '.*.name]');
                  // Nous Verbrauch aktualisieren - nachts um 00:00 Uhr
                  function Nous_vebrauch_tag() {
                      // Nochmals das Tagesupdate durchlaufen, damit die restlichen Werte gelesen werden
                      Nous_verbrauch_update();
                      // Datumsvariable
                      var heute = new Date();
                      // Heute zu Gestern verschieben. Täglich um 00:00 Uhr
                      verschiebe_verbrauch_objekt("heute", "gestern");
                      log("Nous 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("Nous 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("Nous 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("Nous Verbrauch: Werte für dieses und letztes Jahr aktualisiert!");
                      }
                  }
                  // Tagesverbrauch alle 15 Min von der Original Variable des Nous in eigene Variable kopieren
                  function Nous_verbrauch_update() {
                      var anzahl_updates = 0;
                      var anzahl_reboots = 0;
                      var anzahl_gleich = 0;
                      NousDps.each(function (id, i) {
                          //var Nous_verbrauch = getState(id).val; 
                          var Nous_verbrauch = 1000 * getState(id).val; // Nous Steckdoesen geben die Leistungswerte in kWH an, Shellys in Wh
                          if (Nous_verbrauch != null) {
                              // Hole aktuellen Wert, um zu kontrollieren, ob ein Reboot stattgefunden hat
                              var aktueller_wert = getState(Nous_DP(id) + "aktueller_wert").val;
                              var alter_wert = 0;
                              // Prüfe alten und neuen Wert
                              if (Nous_verbrauch > aktueller_wert) {
                                  // Verbrauchswert ist größer als alter Wert -> es wurde kein Reboot durchgeführt
                                  setState(Nous_DP(id) + "alter_wert", aktueller_wert, true);
                                  alter_wert = aktueller_wert;
                                  anzahl_updates++;
                              }
                              
                  
                              if (aktueller_wert > Nous_verbrauch) {
                                  // Verbrauchswert ist kleiner als alter Wert -> es wurde ein Reboot durchgeführt
                                  // setState(Nous_DP(id) + "alter_wert", 0, true);
                                  // alter_wert = 0;
                                  alter_wert = aktueller_wert; // Um Rechenfegler durch fehlende Messwerte zu verhindern
                                  anzahl_reboots++;
                              }
                  
                              if (Nous_verbrauch == aktueller_wert) {
                                  // Verbrauchswert ist gleich altem Wert -> kein Update notwendig
                                  alter_wert = aktueller_wert;
                                  anzahl_gleich++;
                              }
                              setState(Nous_DP(id) + "aktueller_wert", Nous_verbrauch, true);
                              // Alter und neuer Wert -> aktuelle Differenz
                              var verbrauch = parseFloat(Nous_verbrauch) - alter_wert;
                              // Tagesverbrauch aktualisieren
                              aktualisiere_vebrauch_objekt(Nous_DP(id), "heute", verbrauch);
                              // Wochenverbrauch aktualisieren
                              aktualisiere_vebrauch_objekt(Nous_DP(id), "diese_woche", verbrauch);
                              // Monatsverbrauch aktualisieren
                              aktualisiere_vebrauch_objekt(Nous_DP(id), "dieser_monat", verbrauch);
                              // Jahresverbrauch aktualisieren
                              aktualisiere_vebrauch_objekt(Nous_DP(id), "dieses_jahr", verbrauch);
                              // Gesamten Vebrauch aktualisieren
                              aktualisiere_vebrauch_objekt(Nous_DP(id), "gesamt", verbrauch);
                          }
                      });
                      
                      aktualisiere_namen();
                      log("Nous 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 Nous abzuholen
                  function aktualisiere_namen() {
                      if (typeof extendObject === "function") {
                          NousDpsName.each(function (id, i) {
                              if (existsState(id)) {
                                  setState(Nous_DP_Name(id), String(getState(id).val), true);
                                  extendObject("javascript.0." + Nous_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 Nous
                      var anzahl = NousDps.length;
                  log("Nous Datenpukte erstellt: " + anzahl);	    
                      NousDps.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(Nous_DP(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("Nous Verbrauch: Datenpunkte erstellt! Erster Verbrauch steht nach 30 Sekunden zur Verfügung! Anzahl gefundener Nous Datenpunkte: " + anzahl );
                      setTimeout(Nous_verbrauch_update, 30000);
                      // Datenpunkte für die Namen der Nous erstellen
                      NousDpsName.each(function (id, j) {
                          createState(Nous_DP_Name(id), "", ueberschreiben, {
                              name: "Name des Nous",
                              desc: "Name des Nous",
                              type: "string",
                              role: "value",
                              unit: ""
                          });
                      });
                  }
                  /**
                   * Wenn 3EM DP, dann anderen Wert zurückgeben
                   * @param {any} dp
                   * @param {boolean} extended
                   */
                  function Nous_DP(dp, extended = false) {
                      dp = dp.split(".");
                      dp = datenpunkt + dp[2] + "." + dp[3];
                      if (extended) {
                          dp = dp + "_Returned.";
                      } else {
                          dp = dp + ".";
                      }
                      return dp;
                  }
                  function Nous_DP_Name(dp) {
                      dp = dp.split(".");
                      dp = datenpunkt + dp[2] + "." + dp[3];
                      return dp;
                  }
                  function Nous_DP_Name_Main(dp) {
                      dp = dp.split(".");
                      dp = datenpunkt + dp[2];
                      return dp;
                  }
                  function Nous_verbrauch_erster_start() {
                      log("Nous Verbrauch: Erster Start des Skriptes! Datenpunkte werden erstellt!");
                      // Datenpunkte werden erstellt
                      datenpunkte_erstellen();
                  }
                  /*
                   * Override Functions
                   * @autor 2022 SpacerX <spacerx@rbe-base.de>
                   * Überschreibt Funktionen um Datenpunkte unter 0_userdata.0 zu erstellen
                   *
                   *** START SpacerX ***/
                  // Userdatenpunkt
                  var userdir = "0_userdata.0."; // Abschließender Punkt !!! WICHTIG !!!
                  /**
                   * Letzten des Monats berechnen.
                   * @param {Date} oHeute
                   */
                  function letzterDesMonats(oHeute) {
                      return new Date(oHeute.getFullYear(), oHeute.getMonth() + 1, 0).getDate();
                  }
                  //Override at row 48
                  // Nous Verbrauch aktualisieren - nachts um 23:59 Uhr
                  function Nous_vebrauch_tag() {
                      // Nochmals das Tagesupdate durchlaufen, damit die restlichen Werte gelesen werden
                      Nous_verbrauch_update();
                      // Datumsvariable
                      var heute = new Date();
                      // Heute zu Gestern verschieben. Täglich um 23:59 Uhr
                      verschiebe_verbrauch_objekt("heute", "gestern");
                      log("Nous Verbrauch: Werte für gestern und heute aktualisiert!");
                      // aktuelle Woche in letzte Woche verschieben. Am Sonntag um 23:59 Uhr
                      if (heute.getDay() === 0) {   /*line changed by spacerx (Sonntag=0, Montag=1)*/
                          verschiebe_verbrauch_objekt("diese_woche", "letzte_woche");
                          log("Nous Verbrauch: Werte für diese und letzte Woche aktualisiert!");
                      }
                      // aktueller Monat in letzten Monat verschieben. Am letzten des Monats um 23:59 Uhr
                      if (heute.getDate() === letzterDesMonats(heute)) {   /*line changed by spacerx*/
                          verschiebe_verbrauch_objekt("dieser_monat", "letzter_monat");
                          log("Nous Verbrauch: Werte für diesen und letzten Monat aktualisiert!");
                      }
                      // aktuelles Jahr in letztes Jahr verschieben. Am letzten Tag des Jahres um 23:59 Uhr
                      if (heute.getDate() === letzterDesMonats(heute) && heute.getMonth() === 11) { /*line changed by spacerx (Jan=0, Dez=11)*/
                          verschiebe_verbrauch_objekt("dieses_jahr", "letztes_jahr");
                          log("Nous Verbrauch: Werte für dieses und letztes Jahr aktualisiert!");
                      }
                  }
                  //Override at row 254
                  //Verschiebt das jeweilige Verbrauchs-Objekt und nullt den Ursprung (Tag, Woche, Monat, Jahr)
                  function verschiebe_verbrauch_objekt(von, nach) {
                      $('state[id=' + userdir + datenpunkt + '*.*.' + von + ']').each(function (id, i) {   /*line changed by spacerx*/
                          // 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);
                      });
                  }
                  //Override at row 267
                  // Funktion um die aktuellen Namen des Nous abzuholen
                  function aktualisiere_namen() {
                      if (typeof extendObject === "function") {
                          NousDpsName.each(function (id, i) {
                              if (existsState(id)) {
                                  setState(Nous_DP_Name(id), String(getState(id).val), true);
                                  extendObject(Nous_DP_Name_Main(id), {   /*line changed by spacerx*/
                                      common: {
                                          name: String(getState(id).val),
                                          desc: String(getState(id).val)
                                      },
                                      type: "channel"
                                  });
                              }
                          });
                      }
                  }
                  //Override at row 377
                  function Nous_DP(dp, extended = false) {
                      dp = dp.split(".");
                      dp = userdir + datenpunkt + dp[2] + "." + dp[3];   /*line changed by spacerx*/
                      if (extended) {
                          dp = dp + "_Returned.";
                      } else {
                          dp = dp + ".";
                      }
                      return dp;
                  }
                  //Override at row 387
                  function Nous_DP_Name(dp) {
                      dp = dp.split(".");
                      dp = userdir + datenpunkt + dp[2] + "." + dp[3];   /*line changed by spacerx*/
                      return dp;
                  }
                  //Override at row 392
                  function Nous_DP_Name_Main(dp) {
                      dp = dp.split(".");
                      dp = userdir + datenpunkt + dp[2];   /*line changed by spacerx*/
                      return dp;
                  }
                  /*** END SpacerX ***/
                  // Erster Start und Initialisierung
                  Nous_verbrauch_erster_start();
                  // Alle 15 Minuten das Skript für den Tagesverbrauch ausführen
                  schedule('*/15 * * * *', Nous_verbrauch_update);
                  /*** START Edit SpacerX ***/
                  // Nachts um 24 Uhr werden die Werte in andere Variablen gespeichert, um den Verlauf zu erstellen
                  //schedule('0 0 * * *', Nous_vebrauch_tag);
                  // Nachts um 23:59 Uhr werden die Werte in andere Variablen gespeichert, um den Verlauf zu erstellen
                  schedule('59 23 * * *', Nous_vebrauch_tag);
                  /*** END Edit SpacerX ***/
                  

                  Nun möchte ich dieses Script so adaptieren, dass für von mir in einem Array vorgegebene (virtuelle) Zählerwerte* die Tages-, Wochen-, Monats- und Jahreswerte ermittelt und in die entsprechenden Datenpunkte geschrieben werden. Das klappt auch soweit bis auf das Verschieben der Werte „heute -> gestern“, „diese Woche -> letzte Woche“ etc. Die zuständige Routine verstehe ich leider nicht. Es sollte die Funktion ab Zeile 175 in diesem Script sein:
                  function verschiebe_verbrauch_objekt(von, nach) {

                  /*
                   * Dieses Script dient dazu, aus definierten Datenpunkten (zumeist Zählerständen) 
                   * den jeweils letzten Tages- Wochen- Monats- und Jahreswert auszulesen und in
                   * separate Datenpunkte zu schreiben. 
                   * Damit erhält man besser auswertbare Daten eines Zeitraums und umgeht die nicht 
                   * ausreichenden bzw. nicht vorhandenen Gruppierungsmöglichkeiten in Grafana.
                   * 
                   * In der Regel wird man diese Methode anwenden, wenn es keinen geräteseitigen Zählerstand gibt, 
                   * etwa bei errechneten Werten und der "Source Analytics" Adapter nicht zur Anwendung kommen soll."
                   * 
                   * Die Funktionsweise:
                   * Zuerst werden viertelstündlich die Zählerwerte (in Wm) aus den Quelldatenpunkten ausgelesen, in Wh umgerechnet und in die Datenpunkte 
                   * "gesamt", "dieses Jahr", "dieser Monat", "diese Woche" und "heute" für die weitere Verarbeitung geschrieben.
                   * Diese Werte werden alle 15 Minuten um die angefallene Different erhöht.
                   * Jeweils um 23:59 eines jeden Tages wird der letzte Tageswert aus dem "heute" Datenpunkt gelesen und in den Datenpunkt "gestern" kopiert.
                   * Jeweils um 23:59 jeden Sonntag wird der letzte Wert aus "diese_woche" in den Datenpunkt "letzte_woche" kopiert.
                   * Jeweils am Monatsletzten um 23:59 wird der letzte Wert aus "dieser_monat" in den Datenpunkt "letzter_monat" kopiert.
                   * Am 31.12. jedes Jahres um 23:59 wird der letzte Wert aus "dieses_jahr" in den Datenpunkt "letztes_jahr" kopiert.
                   * Damit sind die Tages-, Wochen-, Monats- und Jahreswerte in sepataten Datenpunkten verfügbar.
                   * 
                   * Skript Name:      Tag-Woche-Monat-Jahr
                   * Skript Version:   0.4
                   * Erstell-Datum:    11. September 2024 | Last Update: 7.01.2025
                   * 
                   */
                  
                  // Datenpunkte, aus denen Tages- Wochen- Monats- und Jahreswerte erstellt werden sollen:
                  var quelldatenpunkt = ["0_userdata.0.Einspeisung.PV-Erzeugung-Counter", "0_userdata.0.Einspeisung.PV-Eigenverbrauch-Counter", "0_userdata.0.Einspeisung.PV-Einspeisung-Counter"];
                  var zieldatenpunkt = ["0_userdata.0.Einspeisung.PV-Erzeugung", "0_userdata.0.Einspeisung.PV-Eigenverbrauch", "0_userdata.0.Einspeisung.PV-Einspeisung"];
                  var anz1;                   //Zähler für Quell- und Zieldatenpunkt Verzeichnisse
                  var anz2;                   //Innerer Zähler für die Objekte (Zieldatenpunkte)
                  var verbrauch_wm;           // Werte in Wm!!!
                  var verbrauch;              // Umgewandelt in Wh!!!
                  var ueberschreiben = false;
                  var anzahl_updates = 0;
                  var anzahl_reboots = 0;
                  var anzahl_gleich = 0;
                  
                  // Datenpunkte neu erstellen unterhalb 0.userdata.0
                  // Verbrauchs Objekte 
                  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 = ["Gesamt", "Aktuelles Jahr", "Letztes Jahr", "Letzter Monat", "Aktueller Monat", "Letzte Woche", "Aktuelle Woche", "Gestern", "Heute", "Messwert alt", "Messwert neu"];
                  
                  datenpunkte_erstellen()
                  
                  // Erstelle die benötigten Datenpunkte
                  function datenpunkte_erstellen() {
                      // Anzahl der Quelldatenpunkt Ordner
                      for (anz1 = 0; anz1 < quelldatenpunkt.length ; anz1++) {
                          var initial_wert = 0.0;
                          // Anzahl der neuen Datenpunkte
                          for (anz2 = 0; anz2 < objekt.length; anz2++) {
                              createState(zieldatenpunkt[anz1] + "." + objekt[anz2], initial_wert, ueberschreiben, {
                                  name: beschreibung[anz2],
                                  desc: beschreibung[anz2],
                                  type: "number",
                                  role: "value.power",
                                  unit: "Wh"
                              });
                          }
                      }
                  }
                  
                  // Verbrauch alle 15 Min ermitteln
                  function verbrauch_update() {
                      anzahl_updates = 0;
                      anzahl_reboots = 0;
                      anzahl_gleich = 0;
                      for (anz1 = 0; anz1 < quelldatenpunkt.length; anz1++) {
                  		// Zählerwerte liegen in Wm vor und müssen erst in Wh umgewandelt werden
                          verbrauch_wm  = getState(quelldatenpunkt[anz1]).val; 
                  		// Runden auf 2 Stellen	
                          verbrauch = Math.round(verbrauch_wm / 60*100) /100; 					
                          if (verbrauch != null) {
                              // Hole aktuellen Wert, um zu kontrollieren, ob ein Reboot stattgefunden hat
                  			// In den Zieldatenpunkten liegen die Werte in der Einheit Wh vor
                              var aktueller_wert = getState(zieldatenpunkt[anz1] + ".aktueller_wert").val;  
                              var alter_wert = 0;
                              // Prüfe alten und neuen Wert
                              if (verbrauch > aktueller_wert) {
                                  // Verbrauchswert ist größer als alter Wert -> es wurde kein Reboot durchgeführt
                                  setState(zieldatenpunkt[anz1] + ".alter_wert", aktueller_wert, true);   		// "Aktueller Wert" wird aktualisiert
                                  alter_wert = aktueller_wert;												// "Alter Wert" wird aktualisiert
                                  anzahl_updates++;
                              }
                  			// Kommt nicht vor, da die Werte errechnet werden. Kein Gerät, das resettet werden könnte
                              // 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 (verbrauch == aktueller_wert) {
                                  // Verbrauchswert ist gleich dem alten Wert -> kein Update notwendig
                                  alter_wert = aktueller_wert;
                                  anzahl_gleich++;
                              }
                               setState(zieldatenpunkt[anz1] + ".aktueller_wert", verbrauch, true);
                              // Neuer Wert - alter Wert = aktuelle Differenz
                              var differenz = parseFloat(verbrauch) - alter_wert;
                              //console.log("Alter Wert = " + alter_wert);
                              //console.log("Neuer Wert = " + verbrauch);
                              //console.log("Differenz = " + differenz);
                              
                              // Tagesverbrauch aktualisieren
                              aktualisiere_vebrauch_objekt(zieldatenpunkt[anz1], ".heute", differenz);
                              // Wochenverbrauch aktualisieren
                              aktualisiere_vebrauch_objekt(zieldatenpunkt[anz1], ".diese_woche", differenz);
                              // Monatsverbrauch aktualisieren
                              aktualisiere_vebrauch_objekt(zieldatenpunkt[anz1], ".dieser_monat", differenz);
                              // Jahresverbrauch aktualisieren
                              aktualisiere_vebrauch_objekt(zieldatenpunkt[anz1], ".dieses_jahr", differenz);
                              // Gesamten Vebrauch aktualisieren
                              aktualisiere_vebrauch_objekt(zieldatenpunkt[anz1], ".gesamt", differenz);
                          }
                      };
                  }
                  
                  // 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);
                  }
                  
                  function shelly_verbrauch_erster_start() {
                      log("Shelly Verbrauch: Erster Start des Skriptes! Datenpunkte werden erstellt!");
                      // Datenpunkte werden erstellt
                      datenpunkte_erstellen();
                  }
                  
                  // Userdatenpunkt
                  var userdir = "0_userdata.0."; // Abschließender Punkt !!! WICHTIG !!!
                  
                  // Letzten des Monats berechnen.
                  function letzterDesMonats(oHeute) {
                      return new Date(oHeute.getFullYear(), oHeute.getMonth() + 1, 0).getDate();
                  }
                  
                  // Shelly Verbrauch aktualisieren - nachts um 23:59 Uhr
                  function verbrauch_tag() {
                      // Nochmals das Tagesupdate durchlaufen, damit die restlichen Werte gelesen werden
                      verbrauch_update();
                      // Datumsvariable
                      var heute = new Date();
                      // Heute zu Gestern verschieben. Täglich um 23:59 Uhr
                      verschiebe_verbrauch_objekt("heute", "gestern");
                      log("Shelly Verbrauch: Werte für gestern und heute aktualisiert!");
                      // aktuelle Woche in letzte Woche verschieben. Am Sonntag um 23:59 Uhr
                      if (heute.getDay() === 0) {   // (Sonntag=0, Montag=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 letzten des Monats um 23:59 Uhr
                      if (heute.getDate() === letzterDesMonats(heute)) {   /*line changed by spacerx*/
                          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 letzten Tag des Jahres um 23:59 Uhr
                      if (heute.getDate() === letzterDesMonats(heute) && heute.getMonth() === 11) { /*line changed by spacerx (Jan=0, Dez=11)*/
                          verschiebe_verbrauch_objekt("dieses_jahr", "letztes_jahr");
                          log("Shelly Verbrauch: Werte für dieses und letztes Jahr aktualisiert!");
                      }
                  }
                  
                  // 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) {
                  	$('state[id=' + zieldatenpunkt(anz1)+ '*.*.' + von + ']').each(function (id, anz2) {	
                          // 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);
                      });
                  }
                  
                  //Verschiebt das jeweilige Verbrauchs-Objekt und nullt den Ursprung (Tag, Woche, Monat, Jahr)
                  function verschiebe_verbrauch_objekt(von, nach) {
                      //$('state[id=' + userdir + datenpunkt + '*.*.' + von + ']').each(function (id, anz2) {   
                  	$('state[id=' + zieldatenpunkt[anz1]+ '*.*.' + von + ']').each(function (id, anz2) {	
                          // 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);
                      });
                  }
                  
                  // Erster Start und Initialisierung
                  shelly_verbrauch_erster_start();
                  
                  // Alle 15 Minuten das Skript für den Tagesverbrauch ausführen
                  schedule('*/15 * * * *', verbrauch_update);
                  
                  // Nachts um 23:59 Uhr werden die Werte in andere Variablen gespeichert, um den Verlauf zu erstellen
                  schedule('59 23 * * *', verbrauch_tag);
                  
                  

                  *Die virtuellen Zählerwerte errechne ich aus den Ertrags- und Einspeiseleistungen meiner PV, die jede Minute ermittelt werden. Mein Zähler zeigt leider nur die eingespeiste Leistung, aber nicht den zugehörigen Zählerstand an.

                  Und da die Fragen sicher kommen werden:

                  • Ich habe keine Möglichkeit, einen Shelly 3EM etc. unterzubringen und der Source Analytics Adapter soll auch nicht zum Einsatz kommen.
                  • Und ja, ich könnte die „heute“ Werte auch manuell nach „gestern“ schreiben und anschließend nullen, dann hätte ich das Konstrukt aber immer noch nicht verstanden.

                  Ich hoffe, ich konnte mein Anliegen verständlich beschreiben und hoffe auf Eure Hilfestellung.

                  Gruß

                  OliverIOO Offline
                  OliverIOO Offline
                  OliverIO
                  schrieb am zuletzt editiert von
                  #8

                  @opöl
                  Du mal so als Anregung.
                  Für sowas sind Datenbanken prädestiniert.
                  Man schreibt regelmäßig nur die rohdaten in die Datenbank.
                  Zu einem späteren Zeitpunkt kann man die dann schön aggregieren nach verschiedenen Zeitscheiben, vergleichen, etc.
                  Alles dynamisch

                  Meine Adapter und Widgets
                  TVProgram, SqueezeboxRPC, OpenLiga, RSSFeed, MyTime,, pi-hole2, vis-json-template, skiinfo, vis-mapwidgets, vis-2-widgets-rssfeed
                  Links im Profil

                  1 Antwort Letzte Antwort
                  1
                  • CodierknechtC Online
                    CodierknechtC Online
                    Codierknecht
                    Developer Most Active
                    schrieb am zuletzt editiert von
                    #9

                    @opöl
                    Das was @OliverIO schreibt.
                    Und wenn es darum geht, dass diese "Datenbank" (Influx, MySQL, MariaDB etc.) bestimmte Werte (Tagesverbrauch) nur 1x am Tag protokollieren soll, kann man den Wert (z.B. ENERGY_Today) per Script um 23:59 in einen eigenen DP schreiben und diesen historisieren. So hat man dann pro Tag genau 1 Wert mit passendem Timestamp in der DB.

                    Der Vorteil von Datenbanken: Damit hat man dann echte Langzeitwerte, die man zu einem beliebigen Zeitpunkt über beliebige Zeiträume aggregieren kann.

                    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand." (Martin Fowler, "Refactoring")

                    Proxmox 9.1.1 LXC|8 GB|Core i7-6700
                    HmIP|ZigBee|Tasmota|Unifi
                    Zabbix Certified Specialist
                    Konnte ich Dir helfen? Dann benutze bitte das Voting unten rechts im Beitrag

                    O 1 Antwort Letzte Antwort
                    0
                    • CodierknechtC Codierknecht

                      @opöl
                      Das was @OliverIO schreibt.
                      Und wenn es darum geht, dass diese "Datenbank" (Influx, MySQL, MariaDB etc.) bestimmte Werte (Tagesverbrauch) nur 1x am Tag protokollieren soll, kann man den Wert (z.B. ENERGY_Today) per Script um 23:59 in einen eigenen DP schreiben und diesen historisieren. So hat man dann pro Tag genau 1 Wert mit passendem Timestamp in der DB.

                      Der Vorteil von Datenbanken: Damit hat man dann echte Langzeitwerte, die man zu einem beliebigen Zeitpunkt über beliebige Zeiträume aggregieren kann.

                      O Offline
                      O Offline
                      opöl
                      schrieb am zuletzt editiert von
                      #10

                      @codierknecht , @OliverIO ,

                      das ist doch genau das, was ich erreichen möchte. Die Rohdaten stehen bereits in der influx DB und sollen für die grafische Auswertung zu bestimmten Zeitpunkten in separate Datenpunkte (Woche, Monat...) geschrieben werden.

                      Mir hat das Wissen über die Funktionsweise der "for each" Methode gefehlt. Habe ich mir inzwischen angelesen und mit @paul53 's Anregung:

                      function verschiebe_verbrauch_objekt(von, nach) {
                         zieldatenpunkt.forEach(function(id) { 
                             const verbrauch = getState(id + '.' + von).val; // Hole Verbrauch "von" 
                             console.error("id= " + id);
                             console.error("Verbrauch= " + verbrauch);
                             if (verbrauch != null) {
                                 setState(id + '.' + nach, verbrauch, true); // Schreibe Verbrauch in "nach"
                             }
                             setState(id + '.' + von, 0, true);              // Setze "von" zurück
                         });
                      }
                      

                      sowie eines zeitgesteuerten Aufrufs dieser Funktion in meinem Script wurden die Datenpunkte "heute" nach "gestern" kopiert und im Anschluss auf "0" gesetzt, also genau das, was ich erreichen wollte.

                      Ich lasse das jetzt mal bis Sonntag laufen, bis dahin sollte ich dann die täglichen und die ersten wöchentlichen Aktualisierungen haben.

                      Wenn alles klappt, setze ich diesen Thread dann auf "gelöst", andernfalls melde ich mich nochmal. Vielen Dank an Euch alle.

                      Gruß

                      O 1 Antwort Letzte Antwort
                      0
                      • O opöl

                        @codierknecht , @OliverIO ,

                        das ist doch genau das, was ich erreichen möchte. Die Rohdaten stehen bereits in der influx DB und sollen für die grafische Auswertung zu bestimmten Zeitpunkten in separate Datenpunkte (Woche, Monat...) geschrieben werden.

                        Mir hat das Wissen über die Funktionsweise der "for each" Methode gefehlt. Habe ich mir inzwischen angelesen und mit @paul53 's Anregung:

                        function verschiebe_verbrauch_objekt(von, nach) {
                           zieldatenpunkt.forEach(function(id) { 
                               const verbrauch = getState(id + '.' + von).val; // Hole Verbrauch "von" 
                               console.error("id= " + id);
                               console.error("Verbrauch= " + verbrauch);
                               if (verbrauch != null) {
                                   setState(id + '.' + nach, verbrauch, true); // Schreibe Verbrauch in "nach"
                               }
                               setState(id + '.' + von, 0, true);              // Setze "von" zurück
                           });
                        }
                        

                        sowie eines zeitgesteuerten Aufrufs dieser Funktion in meinem Script wurden die Datenpunkte "heute" nach "gestern" kopiert und im Anschluss auf "0" gesetzt, also genau das, was ich erreichen wollte.

                        Ich lasse das jetzt mal bis Sonntag laufen, bis dahin sollte ich dann die täglichen und die ersten wöchentlichen Aktualisierungen haben.

                        Wenn alles klappt, setze ich diesen Thread dann auf "gelöst", andernfalls melde ich mich nochmal. Vielen Dank an Euch alle.

                        Gruß

                        O Offline
                        O Offline
                        opöl
                        schrieb am zuletzt editiert von
                        #11

                        @paul53 ,

                        die Tageswerte wurden seit dem 10.1. alle wie geplant aktualisiert bzw. zurückgesetzt und am Sonntag um 23:59 wurden ebenfalls die Datenpunkte "letzte_woche" aktualisiert und die DPs "diese_woche" genullt. Deine Funktion tut also, was ich möchte. Vielen Dank für Deine Hilfe.

                        Ich hätte da aber noch abschließend zwei Verständnis Fragen:

                        1. Beim Anlegen der DPs per Script habe ich bereits früher einen Flüchtigkeitsfehler eingebaut, den ich erst jetzt bemerkt habe. Statt der DP Namen habe ich beim Anlegen der DPs die Beschreibung in die Definition geschrieben. Kann ich das nachträglich im Script korrigieren oder werden dann die DPs noch einmal neu angelegt und die bisher gespeicherten Werte sind weg?
                          Siehe Zeile 2 -> Objekt Array (Namen der DPs) und Zeile 14 -> DP Name.
                        // Verbrauchs Objekte 
                        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 = ["Gesamt", "Aktuelles Jahr", "Letztes Jahr", "Letzter Monat", "Aktueller Monat", "Letzte Woche", "Aktuelle Woche", "Gestern", "Heute", "Messwert alt", "Messwert neu"];
                        
                        // Erstelle die benötigten Datenpunkte
                        function datenpunkte_erstellen() {
                            // Anzahl der Quelldatenpunkt Ordner
                            for (anz1 = 0; anz1 < quelldatenpunkt.length ; anz1++) {
                                var initial_wert = 0.0;
                                // Anzahl der neuen Datenpunkte
                                for (anz2 = 0; anz2 < objekt.length; anz2++) {
                                    createState(zieldatenpunkt[anz1] + "." + objekt[anz2], initial_wert, ueberschreiben, {
                                        name: beschreibung[anz2], <-- Hier sollte "objekt[anz2]" stehen, also die Objekt Namen aus dem Array
                                        desc: beschreibung[anz2],
                                        type: "number",
                                        role: "value.power",
                                        unit: "Wh"
                                    });
                                }
                            }
                        }
                        
                        

                        So sieht z.B. der DP 0_userdata.0.Einspeisung.PV-Erzeugung.letzte_woche aus:

                        {
                          "common": {
                            "name": "Letzte Woche",
                            "desc": "Letzte Woche",
                            "type": "number",
                            "role": "value.power",
                            "unit": "Wh",
                        
                        1. Warum steht in Deiner Funktion
                        function verschiebe_verbrauch_objekt(von, nach) {
                            zieldatenpunkt.forEach(function(id) { 
                                const verbrauch = getState(id + '.' + von).val;
                                if (verbrauch != null) {
                                    setState(id + '.' + nach), verbrauch, true); // Schreibe Verbrauch in "nach"
                                }
                                setState(id + '.' + von, 0, true); // Setze "von" zurück
                            });
                        }
                        

                        die Zeile 7 nicht innerhalb der "If" Anweisung, also vor der geschlossenen Klammer in Zeile 6?
                        In meinem Fall (Quelldatenpunkte sind vorhanden) kann der Verbrauch doch nicht "null" zurück liefern. Verbrauch = null kann doch nur vorkommen, wenn es zu einem Array Wert keinen "von" Wert gibt, dann muss dieser aber auch nicht zurückgesetzt werden. Oder andersrum: Nur wenn "von" existiert und einen Wert hat, muss "nach" aktualisiert und "von" resettet werden.
                        Ich würde mich freuen, wenn Du mich da noch kurz abholen könntest.

                        Nochmals Danke und Gruß

                        paul53P 1 Antwort Letzte Antwort
                        0
                        • O opöl

                          @paul53 ,

                          die Tageswerte wurden seit dem 10.1. alle wie geplant aktualisiert bzw. zurückgesetzt und am Sonntag um 23:59 wurden ebenfalls die Datenpunkte "letzte_woche" aktualisiert und die DPs "diese_woche" genullt. Deine Funktion tut also, was ich möchte. Vielen Dank für Deine Hilfe.

                          Ich hätte da aber noch abschließend zwei Verständnis Fragen:

                          1. Beim Anlegen der DPs per Script habe ich bereits früher einen Flüchtigkeitsfehler eingebaut, den ich erst jetzt bemerkt habe. Statt der DP Namen habe ich beim Anlegen der DPs die Beschreibung in die Definition geschrieben. Kann ich das nachträglich im Script korrigieren oder werden dann die DPs noch einmal neu angelegt und die bisher gespeicherten Werte sind weg?
                            Siehe Zeile 2 -> Objekt Array (Namen der DPs) und Zeile 14 -> DP Name.
                          // Verbrauchs Objekte 
                          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 = ["Gesamt", "Aktuelles Jahr", "Letztes Jahr", "Letzter Monat", "Aktueller Monat", "Letzte Woche", "Aktuelle Woche", "Gestern", "Heute", "Messwert alt", "Messwert neu"];
                          
                          // Erstelle die benötigten Datenpunkte
                          function datenpunkte_erstellen() {
                              // Anzahl der Quelldatenpunkt Ordner
                              for (anz1 = 0; anz1 < quelldatenpunkt.length ; anz1++) {
                                  var initial_wert = 0.0;
                                  // Anzahl der neuen Datenpunkte
                                  for (anz2 = 0; anz2 < objekt.length; anz2++) {
                                      createState(zieldatenpunkt[anz1] + "." + objekt[anz2], initial_wert, ueberschreiben, {
                                          name: beschreibung[anz2], <-- Hier sollte "objekt[anz2]" stehen, also die Objekt Namen aus dem Array
                                          desc: beschreibung[anz2],
                                          type: "number",
                                          role: "value.power",
                                          unit: "Wh"
                                      });
                                  }
                              }
                          }
                          
                          

                          So sieht z.B. der DP 0_userdata.0.Einspeisung.PV-Erzeugung.letzte_woche aus:

                          {
                            "common": {
                              "name": "Letzte Woche",
                              "desc": "Letzte Woche",
                              "type": "number",
                              "role": "value.power",
                              "unit": "Wh",
                          
                          1. Warum steht in Deiner Funktion
                          function verschiebe_verbrauch_objekt(von, nach) {
                              zieldatenpunkt.forEach(function(id) { 
                                  const verbrauch = getState(id + '.' + von).val;
                                  if (verbrauch != null) {
                                      setState(id + '.' + nach), verbrauch, true); // Schreibe Verbrauch in "nach"
                                  }
                                  setState(id + '.' + von, 0, true); // Setze "von" zurück
                              });
                          }
                          

                          die Zeile 7 nicht innerhalb der "If" Anweisung, also vor der geschlossenen Klammer in Zeile 6?
                          In meinem Fall (Quelldatenpunkte sind vorhanden) kann der Verbrauch doch nicht "null" zurück liefern. Verbrauch = null kann doch nur vorkommen, wenn es zu einem Array Wert keinen "von" Wert gibt, dann muss dieser aber auch nicht zurückgesetzt werden. Oder andersrum: Nur wenn "von" existiert und einen Wert hat, muss "nach" aktualisiert und "von" resettet werden.
                          Ich würde mich freuen, wenn Du mich da noch kurz abholen könntest.

                          Nochmals Danke und Gruß

                          paul53P Offline
                          paul53P Offline
                          paul53
                          schrieb am zuletzt editiert von paul53
                          #12

                          @opöl sagte: Kann ich das nachträglich im Script korrigieren

                          Korrigiere es besser im Tab "Objekte" (Bleistift rechts).

                          @opöl sagte in Anpassung eines Scripts / Hilfe benötigt:

                          Zeile 7 nicht innerhalb der "If" Anweisung

                          ... weil ich es so aus dem Original-Skript übernommen habe.

                          EDIT: Verbrauchswerte sind Zahlen, weshalb ich den Vergleich verbrauch != null ohnehin nicht verstanden habe. Er dürfte immer erfüllt sein.

                          Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
                          Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

                          O 1 Antwort Letzte Antwort
                          0
                          • paul53P paul53

                            @opöl sagte: Kann ich das nachträglich im Script korrigieren

                            Korrigiere es besser im Tab "Objekte" (Bleistift rechts).

                            @opöl sagte in Anpassung eines Scripts / Hilfe benötigt:

                            Zeile 7 nicht innerhalb der "If" Anweisung

                            ... weil ich es so aus dem Original-Skript übernommen habe.

                            EDIT: Verbrauchswerte sind Zahlen, weshalb ich den Vergleich verbrauch != null ohnehin nicht verstanden habe. Er dürfte immer erfüllt sein.

                            O Offline
                            O Offline
                            opöl
                            schrieb am zuletzt editiert von
                            #13

                            @paul53 ,
                            ich denke, das wurde eingefügt, weil ja die Schleife für alle Werte des Arrays durchlaufen wird, unabhängig davon, ob es einen „von“ und „nach“ Datenpunkt gibt. Z.B. für den DP „gesamt“ gibt es keine Notwendigkeit, Werte zu verschieben. Ergo gibt es „von“ nicht und daher wird von einem nicht existierenden DP ein „null“ zurückgegeben. Da entfällt aber auch die Notwendigkeit, etwas nicht existentes zu nullen.
                            Die If Anweisung wirkt quasi als Filter, damit nur da verschoben und genullt wird, wo das benötigt wird.

                            So zumindest mein Verständnis…

                            Ich probiere es mal aus.

                            Gruß

                            paul53P 1 Antwort Letzte Antwort
                            0
                            • O opöl

                              @paul53 ,
                              ich denke, das wurde eingefügt, weil ja die Schleife für alle Werte des Arrays durchlaufen wird, unabhängig davon, ob es einen „von“ und „nach“ Datenpunkt gibt. Z.B. für den DP „gesamt“ gibt es keine Notwendigkeit, Werte zu verschieben. Ergo gibt es „von“ nicht und daher wird von einem nicht existierenden DP ein „null“ zurückgegeben. Da entfällt aber auch die Notwendigkeit, etwas nicht existentes zu nullen.
                              Die If Anweisung wirkt quasi als Filter, damit nur da verschoben und genullt wird, wo das benötigt wird.

                              So zumindest mein Verständnis…

                              Ich probiere es mal aus.

                              Gruß

                              paul53P Offline
                              paul53P Offline
                              paul53
                              schrieb am zuletzt editiert von
                              #14

                              @opöl sagte: unabhängig davon, ob es einen „von“ und „nach“ Datenpunkt gibt.

                              Ich habe mir nicht das komplette Skript angesehen.

                              Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
                              Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

                              1 Antwort Letzte Antwort
                              0
                              Antworten
                              • In einem neuen Thema antworten
                              Anmelden zum Antworten
                              • Älteste zuerst
                              • Neuste zuerst
                              • Meiste Stimmen


                              Support us

                              ioBroker
                              Community Adapters
                              Donate

                              586

                              Online

                              32.4k

                              Benutzer

                              81.5k

                              Themen

                              1.3m

                              Beiträge
                              Community
                              Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
                              ioBroker Community 2014-2025
                              logo
                              • Anmelden

                              • Du hast noch kein Konto? Registrieren

                              • Anmelden oder registrieren, um zu suchen
                              • Erster Beitrag
                                Letzter Beitrag
                              0
                              • Home
                              • Aktuell
                              • Tags
                              • Ungelesen 0
                              • Kategorien
                              • Unreplied
                              • Beliebt
                              • GitHub
                              • Docu
                              • Hilfe