NEWS
Verbrauchsberechnung für Sonoff Geräte (Nous, Tasmota)
-
Hallo zusammen,
ich wünsche Euch, frohe Weihnachten gehabt zu haben und immer noch zu haben.
Die letzten ruhigen Feiertage habe ich genutzt, um ein Nous-Verbrauch Script, das ich schon länger im Einsatz habe, in eine Form zu bringen, die man auch veröffentlichen kann.
Das Script berechnet aus den Verbrauchwerten von Sonoff Geräten (Nous A1T Steckdosen und auf Tasmota geflashte Shelly Plus 1 PM uns Shelly Steckdosen) die Tages- Wochen- Monats- Jahres- und Gesamtwerte und erlauben damit eine einfache grafische Aufbereitung und Auswertung der jeweiligen Werte.Es ist in der Funktionsweise an das Shelly-Verbrauch Script des Users @skb mit den Ergänzungen vom @spacerx angelehnt, verarbeitet allerdings nur Verbrauch oder Erzeugung. Der "Returned" Wert wie im Shelly Script wird nicht berücksichtigt, da die von mir benutzten Sonoff Geräte nur in einer Richtung messen, bzw. nur eine Richtung für mich relevant ist.
Ein weiterer Unterschied ist, dass die von mir benutzten Sonoff Geräte (Nous A1T Steckdosen, Shelly Plus 1PM und Shelly Steckdosen mit Tasmota) ein gegenüber Shellys verändertes Reset Verhalten zeigen. Der Zähler des Geräts wird im Reset Fall nicht auf "0" sondern auf den Stand des Vortags zurückgesetzt und der Tageszähler wird genullt. Daher wurde das Verhalten des Scripts im Reset Fall entsprechend angepasst.Ich stelle das Script hier zur freien Verwendung zur Verfügung. Vielleicht findet es ja jemand hilfreich.
Der Name des Scripts hat übrigens den Grund, dass ich zuerst nur Nous Steckdosen erfassen wollte. Erst nach Einsatz des Scripts habe ich dann festgestellt, das es auch die auf Tasmota geflashten Shellys verarbeitet hat und habe den Namen dann so gelassen.
Ob auch andere mit Tasmota geflashte Shellys damit funktionieren kann ich nicht sagen, da ich bislang nur die genannten Geräte im Einsatz habe. Über entsprechende Rückmeldung würde ich mich aber freuen.
Gruß
/* * * Dieses Skript dient zur Verbrauchserfassung von Tasmota Geräten * z.B. Nous Steckdosen oder auf Tasmota geflashte Shelly Geräte. * * Es basiert auf dem Shelly-Verbrauch Script des Autors * SKB (Stephan Kreyenborg) sowie den Anpassungen von SpacerX. * * Das Script ermittelt aus dem Zählerstand der Geräte die Tages- Wochen- Monats- * und Jahresverbräuche und legt diese in neuen Datenpunkten 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. * * Autor: Horst Apel <horst.apel@netcologne.de> * Skript Name: Nous-Verbrauch * Skript Version: 1.90 | 28. November 2025 * Erstell-Datum: 08. Oktober 2023 * * Letzte Änderung: Verbessertes Reset Handling. * */ // 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 verbrauch 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 werden unter "0_userdata.0." angelegt. var userdir = "0_userdata.0."; // Abschließender Punkt !!! WICHTIG !!! // Datenpunkte der Nous (!!! Bitte nicht ändern !!!) var NousDps = $('state[id=' + Nous_dp + '.*.*.ENERGY.Total]'); // Datenpunkte der Nous Namen (!!! Bitte nicht ändern !!!) var NousDpsName = $('state[id=' + Nous_dp + '.*.name]'); // Nous Verbrauch aktualisieren - nachts um 23:59 Uhr function Nous_verbrauch_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 Montag um 23:59 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 23:59 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 23:59 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) { // Aktuellen Zählerwert (Nous_verbrauch) holen. // Nous Geräte geben die Leistungswerte in kWH an, Shellys in Wh. var Nous_verbrauch = 1000 * getState(id).val; // Wh // Werte nur aktualisieren, wenn ein Messwert vorliegt if (Nous_verbrauch != null) { // (Nous_verbrauch = Neuer Zählerstand des Nous // Hole gespeicherten aktuellen Zählerstand, um zu kontrollieren, ob ein Reboot stattgefunden hat var aktueller_wert = getState(Nous_DP(id) + "aktueller_wert").val; // Verbrauchswert (neuer Zählerstand) ist größer als der letzte Wert -> es wurde kein Reboot durchgeführt // Prüfe alten und neuen Wert (Zählerstand) if (Nous_verbrauch > aktueller_wert) { setState(Nous_DP(id) + "alter_wert", aktueller_wert, true); // In den DP "alter_Wert" wird der neue Zählerstand (aktueller_wert) geschrieben alter_wert = aktueller_wert; anzahl_updates++; } if (aktueller_wert > Nous_verbrauch) { // Bei einem Reset eines Nous Geräts wird der Tageszähler auf "0" zurückgesetzt und der Gesamtzählerstand vom Vortag ausgegeben!!!!! // Daher müssen im Falle eines Resets die gespeicherten Werte "alter_wert" und "aktueller_wert" auf "Nous_verbrauch gesetzt" werden. // Die Tages-, Wochen-, Monats-, Jahres-, und Gesamtwerte werden so ohne Sprünge lückenlos weiter fortgeführt. aktueller_wert = Nous_verbrauch; alter_wert = Nous_verbrauch; setState(Nous_DP(id) + "alter_wert", alter_wert, true); anzahl_reboots++; } if (Nous_verbrauch == aktueller_wert) { // Verbrauchswert ist gleich altem Wert -> kein Update notwendig alter_wert = aktueller_wert; anzahl_gleich++; } // Aktuellen Wert merken setState(Nous_DP(id) + "aktueller_wert", Nous_verbrauch, true); // Neuer Zählerstand - alter Wert = aktuelle Differenz let verbrauch = parseFloat(Nous_verbrauch) - alter_wert; // Tagesverbrauch aktualisieren aktualisiere_verbrauch_objekt(Nous_DP(id), "heute", verbrauch); // Wochenverbrauch aktualisieren aktualisiere_verbrauch_objekt(Nous_DP(id), "diese_woche", verbrauch); // Monatsverbrauch aktualisieren aktualisiere_verbrauch_objekt(Nous_DP(id), "dieser_monat", verbrauch); // Jahresverbrauch aktualisieren aktualisiere_verbrauch_objekt(Nous_DP(id), "dieses_jahr", verbrauch); // Gesamten verbrauch aktualisieren aktualisiere_verbrauch_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_verbrauch_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: objekt[i], desc: beschreibung[i], type: "number", role: "value.power", unit: "Wh" }); //log("Datenpunkt: " + Nous_DP(id)+ objekt[i]); } log("Datenpunkte: " + Nous_DP(id)); }); // 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: "" }); }); } function Nous_DP(dp) { dp = dp.split("."); dp = datenpunkt + dp[2] + "." + dp[3] + "."; 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(); } function letzterDesMonats(oHeute) { return new Date(oHeute.getFullYear(), oHeute.getMonth() + 1, 0).getDate(); } // Nous Verbrauch aktualisieren - nachts um 23:59 Uhr function Nous_verbrauch_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) { 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)) { 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) { verschiebe_verbrauch_objekt("dieses_jahr", "letztes_jahr"); log("Nous 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=' + userdir + 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(Nous_DP_Name_Main(id), { common: { name: String(getState(id).val), desc: String(getState(id).val) }, type: "channel" }); } }); } } function Nous_DP(dp) { dp = dp.split("."); dp = userdir + datenpunkt + dp[2] + "." + dp[3] + "."; return dp; } function Nous_DP_Name(dp) { dp = dp.split("."); dp = userdir + datenpunkt + dp[2] + "." + dp[3]; return dp; } function Nous_DP_Name_Main(dp) { dp = dp.split("."); dp = userdir + datenpunkt + dp[2]; return dp; } // Erster Start und Initialisierung Nous_verbrauch_erster_start(); // Alle 15 Minuten das Skript für den Tagesverbrauch ausführen schedule('*/15 * * * *', Nous_verbrauch_update); // Nachts um 23:59 Uhr werden die Werte in andere Variablen gespeichert, um den Verlauf zu erstellen schedule('59 23 * * *', Nous_verbrauch_tag); -
Hallo zusammen,
ich wünsche Euch, frohe Weihnachten gehabt zu haben und immer noch zu haben.
Die letzten ruhigen Feiertage habe ich genutzt, um ein Nous-Verbrauch Script, das ich schon länger im Einsatz habe, in eine Form zu bringen, die man auch veröffentlichen kann.
Das Script berechnet aus den Verbrauchwerten von Sonoff Geräten (Nous A1T Steckdosen und auf Tasmota geflashte Shelly Plus 1 PM uns Shelly Steckdosen) die Tages- Wochen- Monats- Jahres- und Gesamtwerte und erlauben damit eine einfache grafische Aufbereitung und Auswertung der jeweiligen Werte.Es ist in der Funktionsweise an das Shelly-Verbrauch Script des Users @skb mit den Ergänzungen vom @spacerx angelehnt, verarbeitet allerdings nur Verbrauch oder Erzeugung. Der "Returned" Wert wie im Shelly Script wird nicht berücksichtigt, da die von mir benutzten Sonoff Geräte nur in einer Richtung messen, bzw. nur eine Richtung für mich relevant ist.
Ein weiterer Unterschied ist, dass die von mir benutzten Sonoff Geräte (Nous A1T Steckdosen, Shelly Plus 1PM und Shelly Steckdosen mit Tasmota) ein gegenüber Shellys verändertes Reset Verhalten zeigen. Der Zähler des Geräts wird im Reset Fall nicht auf "0" sondern auf den Stand des Vortags zurückgesetzt und der Tageszähler wird genullt. Daher wurde das Verhalten des Scripts im Reset Fall entsprechend angepasst.Ich stelle das Script hier zur freien Verwendung zur Verfügung. Vielleicht findet es ja jemand hilfreich.
Der Name des Scripts hat übrigens den Grund, dass ich zuerst nur Nous Steckdosen erfassen wollte. Erst nach Einsatz des Scripts habe ich dann festgestellt, das es auch die auf Tasmota geflashten Shellys verarbeitet hat und habe den Namen dann so gelassen.
Ob auch andere mit Tasmota geflashte Shellys damit funktionieren kann ich nicht sagen, da ich bislang nur die genannten Geräte im Einsatz habe. Über entsprechende Rückmeldung würde ich mich aber freuen.
Gruß
/* * * Dieses Skript dient zur Verbrauchserfassung von Tasmota Geräten * z.B. Nous Steckdosen oder auf Tasmota geflashte Shelly Geräte. * * Es basiert auf dem Shelly-Verbrauch Script des Autors * SKB (Stephan Kreyenborg) sowie den Anpassungen von SpacerX. * * Das Script ermittelt aus dem Zählerstand der Geräte die Tages- Wochen- Monats- * und Jahresverbräuche und legt diese in neuen Datenpunkten 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. * * Autor: Horst Apel <horst.apel@netcologne.de> * Skript Name: Nous-Verbrauch * Skript Version: 1.90 | 28. November 2025 * Erstell-Datum: 08. Oktober 2023 * * Letzte Änderung: Verbessertes Reset Handling. * */ // 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 verbrauch 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 werden unter "0_userdata.0." angelegt. var userdir = "0_userdata.0."; // Abschließender Punkt !!! WICHTIG !!! // Datenpunkte der Nous (!!! Bitte nicht ändern !!!) var NousDps = $('state[id=' + Nous_dp + '.*.*.ENERGY.Total]'); // Datenpunkte der Nous Namen (!!! Bitte nicht ändern !!!) var NousDpsName = $('state[id=' + Nous_dp + '.*.name]'); // Nous Verbrauch aktualisieren - nachts um 23:59 Uhr function Nous_verbrauch_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 Montag um 23:59 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 23:59 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 23:59 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) { // Aktuellen Zählerwert (Nous_verbrauch) holen. // Nous Geräte geben die Leistungswerte in kWH an, Shellys in Wh. var Nous_verbrauch = 1000 * getState(id).val; // Wh // Werte nur aktualisieren, wenn ein Messwert vorliegt if (Nous_verbrauch != null) { // (Nous_verbrauch = Neuer Zählerstand des Nous // Hole gespeicherten aktuellen Zählerstand, um zu kontrollieren, ob ein Reboot stattgefunden hat var aktueller_wert = getState(Nous_DP(id) + "aktueller_wert").val; // Verbrauchswert (neuer Zählerstand) ist größer als der letzte Wert -> es wurde kein Reboot durchgeführt // Prüfe alten und neuen Wert (Zählerstand) if (Nous_verbrauch > aktueller_wert) { setState(Nous_DP(id) + "alter_wert", aktueller_wert, true); // In den DP "alter_Wert" wird der neue Zählerstand (aktueller_wert) geschrieben alter_wert = aktueller_wert; anzahl_updates++; } if (aktueller_wert > Nous_verbrauch) { // Bei einem Reset eines Nous Geräts wird der Tageszähler auf "0" zurückgesetzt und der Gesamtzählerstand vom Vortag ausgegeben!!!!! // Daher müssen im Falle eines Resets die gespeicherten Werte "alter_wert" und "aktueller_wert" auf "Nous_verbrauch gesetzt" werden. // Die Tages-, Wochen-, Monats-, Jahres-, und Gesamtwerte werden so ohne Sprünge lückenlos weiter fortgeführt. aktueller_wert = Nous_verbrauch; alter_wert = Nous_verbrauch; setState(Nous_DP(id) + "alter_wert", alter_wert, true); anzahl_reboots++; } if (Nous_verbrauch == aktueller_wert) { // Verbrauchswert ist gleich altem Wert -> kein Update notwendig alter_wert = aktueller_wert; anzahl_gleich++; } // Aktuellen Wert merken setState(Nous_DP(id) + "aktueller_wert", Nous_verbrauch, true); // Neuer Zählerstand - alter Wert = aktuelle Differenz let verbrauch = parseFloat(Nous_verbrauch) - alter_wert; // Tagesverbrauch aktualisieren aktualisiere_verbrauch_objekt(Nous_DP(id), "heute", verbrauch); // Wochenverbrauch aktualisieren aktualisiere_verbrauch_objekt(Nous_DP(id), "diese_woche", verbrauch); // Monatsverbrauch aktualisieren aktualisiere_verbrauch_objekt(Nous_DP(id), "dieser_monat", verbrauch); // Jahresverbrauch aktualisieren aktualisiere_verbrauch_objekt(Nous_DP(id), "dieses_jahr", verbrauch); // Gesamten verbrauch aktualisieren aktualisiere_verbrauch_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_verbrauch_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: objekt[i], desc: beschreibung[i], type: "number", role: "value.power", unit: "Wh" }); //log("Datenpunkt: " + Nous_DP(id)+ objekt[i]); } log("Datenpunkte: " + Nous_DP(id)); }); // 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: "" }); }); } function Nous_DP(dp) { dp = dp.split("."); dp = datenpunkt + dp[2] + "." + dp[3] + "."; 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(); } function letzterDesMonats(oHeute) { return new Date(oHeute.getFullYear(), oHeute.getMonth() + 1, 0).getDate(); } // Nous Verbrauch aktualisieren - nachts um 23:59 Uhr function Nous_verbrauch_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) { 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)) { 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) { verschiebe_verbrauch_objekt("dieses_jahr", "letztes_jahr"); log("Nous 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=' + userdir + 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(Nous_DP_Name_Main(id), { common: { name: String(getState(id).val), desc: String(getState(id).val) }, type: "channel" }); } }); } } function Nous_DP(dp) { dp = dp.split("."); dp = userdir + datenpunkt + dp[2] + "." + dp[3] + "."; return dp; } function Nous_DP_Name(dp) { dp = dp.split("."); dp = userdir + datenpunkt + dp[2] + "." + dp[3]; return dp; } function Nous_DP_Name_Main(dp) { dp = dp.split("."); dp = userdir + datenpunkt + dp[2]; return dp; } // Erster Start und Initialisierung Nous_verbrauch_erster_start(); // Alle 15 Minuten das Skript für den Tagesverbrauch ausführen schedule('*/15 * * * *', Nous_verbrauch_update); // Nachts um 23:59 Uhr werden die Werte in andere Variablen gespeichert, um den Verlauf zu erstellen schedule('59 23 * * *', Nous_verbrauch_tag);@opöl sagte in Verbrauchsberechnung für Sonoff Geräte (Nous, Tasmota):
Ein weiterer Unterschied ist, dass die von mir benutzten Sonoff Geräte (Nous A1T Steckdosen, Shelly Plus 1PM und Shelly Steckdosen mit Tasmota) ein gegenüber Shellys verändertes Reset Verhalten zeigen. Der Zähler des Geräts wird im Reset Fall nicht auf "0" sondern auf den Stand des Vortags zurückgesetzt und der Tageszähler wird genullt.
das ist aber kein normales Verhalten der Geräte
-
Gerade nochmal an einem Shelly Plus Plug S mit Tasmota geschaut.
Vor Power Reset:

Nach Power Reset:

Meine Shelly Plus 1PM mit Tasmota verhalten sich genauso.
Gruß
@opöl ist doch schnuppe, welche Geräte es sind, das ist abhängig von der tasmota Version
und eine Zählerzurücksetzung bei Stromausfall sollte generell nicht passieren, falls doch, kann man mit bestimmten setoption`s entgegen wirken
-
Das ist generell richtig, wird aber z.B. bei meinen Nous Steckdosen standardmäßig nicht so gemacht. Grund ist, das der "Total" Wert nur einmal um Mitternacht vom RAM in den Flash geschrieben wird, weil dieser nicht beliebig oft beschrieben werden kann.
Es spielt aber in diesem Kontext keine Rolle, auf welchen Wert der "Total" Wert zurückgesetzt wird, egal ob auf den Vortagswert oder auf "0".Ein Reset wird erkannt, wenn der gemessene Zählerwert geringer ist als der zuletzt gespeicherte Wert. In diesem Fall wird ausgehend vom neuen Zählerstand weiter die Differenz zum nächsten Zählerstand gemessen.
Nur so sind ja negative Messwerte vermeidbar.Gruß
-
Das ist generell richtig, wird aber z.B. bei meinen Nous Steckdosen standardmäßig nicht so gemacht. Grund ist, das der "Total" Wert nur einmal um Mitternacht vom RAM in den Flash geschrieben wird, weil dieser nicht beliebig oft beschrieben werden kann.
Es spielt aber in diesem Kontext keine Rolle, auf welchen Wert der "Total" Wert zurückgesetzt wird, egal ob auf den Vortagswert oder auf "0".Ein Reset wird erkannt, wenn der gemessene Zählerwert geringer ist als der zuletzt gespeicherte Wert. In diesem Fall wird ausgehend vom neuen Zählerstand weiter die Differenz zum nächsten Zählerstand gemessen.
Nur so sind ja negative Messwerte vermeidbar.Gruß
-
@crunchip ,
vielen Dank für Deine Anmerkungen.
Es stand aber nie in Frage, dass es auch andere (und sicher auch bessere) Lösungen gibt.
Mein Anliegen war es, eine Lösung für Tasmota Geräte, die bei mir sehr gut funktioniert auch anderen, die sowas noch suchen, zur Verfügung zu stellen.
Niemand ist ja gezwungen, meinen Vorschlag anzunehmen. Wie Du aufgezeigt hast, gibt es ja Alternativen.In diesem Sinne:
Allen einen guten Rutsch und ein erfolgreiches und glückliches neues Jahr 2026.Gruß