Hat man im Smarthome Verbrauchswerte, wie z.B. Stromzählerstand, Gasverbrauch, integriert, ist es sinnvoll die Daten regelmäßig aufzubereiten bzw. zu protokollieren. Interessant sind beispielsweise Stunden- und Tagesverbräuche, um einfach und schnell eine optische Auswertung über Diagramme erstellen zu können. Die Berechnung basiert auf dem Momentanzählerstand, der in ioBroker in einem Objekt aktualisiert und gespeichert wird.
Update Oktober 2021: Auf Grund des Admin v5-Updates und der Regelung von eigenen Datenpunkten im Objektbaum 0_userdata haben wir das Script angepasst.
Das Script ermittelt dann zu jeder vollen Stunde, nach jedem Tag, nach jedem Monat und nach jedem Jahr die Differenz zum Vorwert und speichert dieses als Verbrauch für diesen Zeitraum in einer Variablen bzw. einem Objekt in ioBroker ab. Um die Historie zu speichern, müssen wir lediglich für dieses Objekt die Historisierung einschalten.
Hier das entsprechende Script für ioBroker:
var cronH = "0 * * * *"; var cronD = "59 23 * * *"; var cronW = "0 0 * * 1"; var cronM = "0 0 1 * *"; var idHAGTotH = "0_userdata.0.Stromzähler.tmp.Total-h"; var idHAGTotD = "0_userdata.0.Stromzähler.tmp.Total-d"; var idHAGTotW = "0_userdata.0.Stromzähler.tmp.Total-w"; var idHAGTotM = "0_userdata.0.Stromzähler.tmp.Total-m"; var idHAGTotal = "smartmeter.0.1-0:1_8_0__255.value"; /*Stromverbrauch insgesammt*/ var idHAGZielH = "0_userdata.0.Stromzähler.Hour"; var idHAGZielD = "0_userdata.0.Stromzähler.Day"; var idHAGZielW = "0_userdata.0.Stromzähler.Week"; var idHAGZielM = "0_userdata.0.Stromzähler.Month"; var debug = false; var DPArray = [idHAGTotH, idHAGTotD , idHAGTotW, idHAGTotM, idHAGZielH, idHAGZielD, idHAGZielW, idHAGZielM]; var DPUnit = "kWh"; DPArray.forEach(function(wert, index, array) { var DPType = wert.split("."); var DPDescr = "Power consumption of " + (DPType[DPType.length - 1]); if(index > 3) DPUnit = "Wh"; createState(wert, 0, { name: DPDescr, desc: DPDescr, type: 'number', unit: DPUnit, role: 'value' }); }); function haupt (VorId, ZielId) { var nVorwert = getState(VorId).val; var nAktuell = getState(idHAGTotal).val; var nDiff = ((nAktuell * 10) - (nVorwert * 10)) * 100; setState(ZielId, nDiff, true); if(debug) log("Aus: " + nAktuell +" - "+ nVorwert + " = " + nDiff); var shandler = on ({id: ZielId, change: 'any'}, function(data) { setState(VorId, (nAktuell*10)/10, true); unsubscribe(shandler); }); } // regelmässige Wiederholungen // ----------------------------------------------------------------------------- schedule(cronH, function () { haupt(idHAGTotH, idHAGZielH); }); schedule(cronD, function () { haupt(idHAGTotD, idHAGZielD); }); schedule(cronW, function () { haupt(idHAGTotW, idHAGZielW); }); schedule(cronM, function () { haupt(idHAGTotM, idHAGZielM); });
Hallo, was muss ich denn für Werte anpassen im Script ? Ich habe einen Wert über einen Lesekopf mit absoluten Zählerstand unter smartmeter.0.1-0:1_8_0.value , diesen anpassen und müssen noch Variablen angelegt werden ?
In Zeile 9 muss dann der Wert durch smartmeter.0.1-0:1_8_0.value ersetzt werden.
Hallo Florian, leider ohne Erfolg, habe auch noch Objekte tmp.Total-D etc. angelegt. Jedoch kein Erfolg.
Welche Fehlermeldung erscheint denn?
Hallo Florian,
folgende Fehlermeldungen
javascript.0 2020-07-11 22:06:24.335 error (2462) at processTicksAndRejections (internal/process/task_queues.js:97:5)
javascript.0 2020-07-11 22:06:24.335 error (2462) at runMicrotasks ()
javascript.0 2020-07-11 22:06:24.335 error (2462) at /opt/iobroker/node_modules/standard-as-callback/built/index.js:19:49
javascript.0 2020-07-11 22:06:24.334 error (2462) at tryCatcher (/opt/iobroker/node_modules/standard-as-callback/built/utils.js:11:23)
javascript.0 2020-07-11 22:06:24.334 error (2462) at /opt/iobroker/node_modules/iobroker.js-controller/lib/states/statesInRedis.js:616:17
javascript.0 2020-07-11 22:06:24.334 error (2462) at /opt/iobroker/node_modules/iobroker.javascript/main.js:1112:17
javascript.0 2020-07-11 22:06:24.333 error (2462) at /opt/iobroker/node_modules/iobroker.javascript/main.js:1521:17
javascript.0 2020-07-11 22:06:24.333 error (2462) at prepareScript (/opt/iobroker/node_modules/iobroker.javascript/main.js:1468:37)
javascript.0 2020-07-11 22:06:24.333 error (2462) at compile (/opt/iobroker/node_modules/iobroker.javascript/main.js:1245:28)
javascript.0 2020-07-11 22:06:24.332 error (2462) at Object.createScript (vm.js:263:10)
javascript.0 2020-07-11 22:06:24.332 error (2462) at new Script (vm.js:88:7)
javascript.0 2020-07-11 22:06:24.332 error (2462) SyntaxError: missing ) after argument list
javascript.0 2020-07-11 22:06:24.331 error (2462) ^^^^^
javascript.0 2020-07-11 22:06:24.331 error (2462) var DPType = wert.split(„.'{„time“:{„start“:“00:00″,“end“:“23:59″,“mode“:“minutes“,“interval“:2},“period“:{„days“:1}}'“);
javascript.0 2020-07-11 22:06:24.330 error at script.js.Stromzähler:39
javascript.0 2020-07-11 22:06:24.330 error (2462) script.js.Stromzähler compile failed:
javascript.0 2020-07-11 22:06:24.327 info (2462) Start javascript script.js.Stromzähler
javascript.0 2020-07-11 22:06:19.902 info (2462) Stop script script.js.Stromzähler
Der Fehler „SyntaxError: missing )“ sieht evt. nach unvollständigem Code aus, ich habe den Code in einem neuen Script problemlos aktivieren können.
Hey,
erstmal danke für das Script.
Hatte jedoch auch permanent Fehlermeldungen. Nachdem ich testweise den unteren teil (regelmässige Wiederholungen) rausgenommen habe konnte ich das Script problemlos starten und die Datenpunkte wurden angelegt.
Weiter habe ich mich bisher noch nicht drum gekümmert, nur mal als Rückmeldung
in dem Script oben fehlt im letzten Abschnitt (Zeile 53 /54 ) die „});“
Somit ist das Script nicht beendet und wirft Fehler raus.
Läuft nun, aber hatte einen Fehler bei Smartmeter Variable, daher noch keine gespeicherten Werte. Muss bei der SQL Protokollierung etwas beachtet werden? Also als was der Wert gespeichert werden soll?
Perfekt, danke für den Hinweis. Script ist jetzt korrigiert.
Bei der Speicherung ist eigentlich nichts Besonderes zu beachten. Interessant ist lediglich die Einstellung „Minimale Differenz zum letzten Wert“, das verindert z.B. dass zu viele Werte durch Änderungen im Dezimalbereich des Wertes aufgezeichnet werden.
Werte werden nun gespeichert, jedoch hat er nun natürlich als Tageswert den Gesamtzählerstand von „23177.xxx“ KW Stunden Demnach wird keiner der Werte stimmen. Gibts dafür eine Lösung? Also quasi einen Startwert eingeben? :)
Die „Vorwerte“ oder Startwerte können in den Objekten javascript.0.Stromzähler.tmp.Total-* eingetragen werden, dann stimmt auch der aktuelle Wert. Bei dem Wert Total-h sollte spätestens nach einer Stunde Laufzeit des Scripts der richtige Wert gespeichert werden.
Hallo, genau sowas habe ich gesucht, danke erst mal
Skript läuft ohne Fehler allerdings mit 0 Werten
Frage mich jetzt ob ich die Eingangsadresse falsch eingetragen habe oder halt die Start werte fehlen..
Wo werden die hier genau eingetragen?
„common“: {
„name“: „Power consumption of Total-d“,
„desc“: „Power consumption of Total-d“,
„type“: „number“,
„unit“: „kWh“,
„role“: „value“
},
„native“: {
„name“: „Power consumption of Total-d“,
„desc“: „Power consumption of Total-d“,
„type“: „number“,
„unit“: „kWh“,
„role“: „value“
},
„type“: „state“,
„from“: „system.adapter.javascript.0“,
„user“: „system.user.admin“,
„ts“: 1631344785398,
„_id“: „javascript.0.Stromzähler.tmp.Total-d“,
„acl“: {
„object“: 1636,
„state“: 1636,
„owner“: „system.user.admin“,
„ownerGroup“: „system.group.administrator“
}
}
Das Script arbeitet mit dem Wert eines Datenpunkts, der sich mit dem Verbrauch, z.B. Stromzähler, verändert. Das entsprechende Objekt ist über diese Zeile definiert:
var idHAGTotal = „smartmeter.0.1-0:1_8_0__255.value“;
Dort muss das korrekte Objekt eingepflegt werden.
Hallo
Erstmal danke für das script. Sowas suche ich schon lange. anscheinend habe ich ein Brett vorm Kopf.
Ich bekomme im Log folgende Fehler!
javascript.0 2020-12-28 08:00:00.017 error (26221) at processTimers (internal/timers.js:497:7)
javascript.0 2020-12-28 08:00:00.016 error (26221) at listOnTimeout (internal/timers.js:554:17)
javascript.0 2020-12-28 08:00:00.016 error (26221) at Timeout._onTimeout (/opt/iobroker/node_modules/node-schedule/lib/schedule.js:510:7)
javascript.0 2020-12-28 08:00:00.016 error (26221) at /opt/iobroker/node_modules/node-schedule/lib/schedule.js:552:11
javascript.0 2020-12-28 08:00:00.015 error (26221) at Job.invoke (/opt/iobroker/node_modules/node-schedule/lib/schedule.js:173:10)
javascript.0 2020-12-28 08:00:00.015 error (26221) at Job.job (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1273:34)
javascript.0 2020-12-28 08:00:00.015 error (26221) at Object. (script.js.Strom_berechnen:44:5)
javascript.0 2020-12-28 08:00:00.014 error (26221) at haupt (script.js.Strom_berechnen:31:35)
javascript.0 2020-12-28 08:00:00.013 error (26221) Error in callback: TypeError: Cannot read property ‚val‘ of undefined
javascript.0 2020-12-28 08:00:00.008 error (26221) script.js.Strom_berechnen: Please disable that setting or use „getState“ with a callback, e.g.: getState(„javascript.0.Stromzähler.tmp.Total-h“, (err, state) => { … });
javascript.0 2020-12-28 08:00:00.007 error (26221) script.js.Strom_berechnen: The „getState“ method cannot be used synchronously, because the adapter setting „Do not subscribe to all states on start“ is enabled.
Ich lese den aktuellen Verbrauch mit einem Script über Volkszähler ein. Habe dazu in Zeile 9 deines Scriptes folgendes eingesetzt.
var idHAGTotal = „javascript.0.Volkszaehler.AKTUELLER_VERBRAUCH.value“;
Diesen Wert schreibe ich mit der Instanz History. die wird auch gefüllt jedoch steht bei bestätigt „false“
könntest du mir evtl. mit den einstellungen helfen?
Hallo Florian,
vielen Dank für dein super Script. Habe mir die Werte umständlich über Blockly gebaut, da ich kein Javascript kann. Dank deiner Vorlage konnte ich auch den fehlenden Jahreswert in deinem Script ergänzen.
Kurze Verständnisfrage: Warum nimmst du 23:59 Uhr statt 00:00 Uhr?
In Vergangenheit hatten wir mit 00:00 Uhr das Problem, dass die Werte dann dem Folgetage zugeordnet werden. Deswegen der pragmatische Weg mit 23:59 Uhr.
Hallo
Danke für das super Script. Ich nutze es schon länger für meinen Stromverbrauch.
Jetzt wollte ich es für meine Mini-PV Anlage, die bringt maximal 550 Watt/Stunde.
In dem Script wird alles in kWh gezählt, hab mal den Wert auf Wh geändert, aber irgendwie passt das nicht so recht.
Es hat z.B. die letzte Stunde 43200 Wh gezählt.
Was mache ich falsch, hast dir evtl. Einen Tip für mich?
Gruß
Stephan
Mir geht es leider seit kurzem auch so, vorher klappte alles normal.
Jemad eine Lösung?
Hi,
ich habe das gleiche Problem. DIe Werte sind offensichtlich um Faktor 1000 zu hoch.
Habe mir nun Datenpunkte angelegt und ein blockly erstellt, dass mir bei Änderung der Werte „Stromzähler – hour – day – month -week“ die korregierten Werte in meine Datenpunkte schreibt.
Also eher ein workarround
Gruß Tobbes
Hallo Florian,
Vielen Dank funktioniert einwandfrei.
Vielen Dank dafür
:-)
Hallo Florian,
danke für dein Script.
Ich habe eine Verständnisfrage. Mein Energiezähler erfasst in kWh, dein Script rechnet mit Wh (DPUnit=“Wh“)?
So wie ich das sehe, muss Zeile 33 entsprechend angepaßt werden?
Wenn ich noch den Jahreswert benötige, wie schaut der korrekte CRON-Zähler aus?
var cronY = „?????“;
Danke für deine Antwort…
var cronY= „0 0 1 1 *“;
In diesem Fall um 00:00 am 1.1. eines Jahres wird das Script ausgeführt.
kWh vs. Wh schauen wir uns noch an und geben eine Antwort.
Hallo Florian, hast du noch eine Antwort bzgl. kWh / Wh???
Hallo,
ich habe das Script(e) eingefügt und bekomme auch keine Fehlermeldung. Leider wird das Tmp Verzeichnis unter Java nicht angelegt und somit auch nicht die Werte. Ich habe das Script zwei mal angelegt, einmal für 180 und 280.
Hat jemand eine Idee woran es liegt?
Danke schon mal
Sind diese Zeilen korrekt übernommen?
var idHAGTotH = „javascript.0.Stromzähler.tmp.Total-h“;
var idHAGTotD = „javascript.0.Stromzähler.tmp.Total-d“;
var idHAGTotW = „javascript.0.Stromzähler.tmp.Total-w“;
var idHAGTotM = „javascript.0.Stromzähler.tmp.Total-m“;
var idHAGZielH = „javascript.0.Stromzähler.Hour“;
var idHAGZielD = „javascript.0.Stromzähler.Day“;
var idHAGZielW = „javascript.0.Stromzähler.Week“;
var idHAGZielM = „javascript.0.Stromzähler.Month“;
var DPArray = [idHAGTotH, idHAGTotD , idHAGTotW, idHAGTotM, idHAGZielH, idHAGZielD, idHAGZielW, idHAGZielM];
Hallo Florian,
wenn du das Script meinst, ja. Ich habe es kopiert.
Was ich aber metkwürdig finde, ich kann das Script nach dem Speichern nicht mehr einsehen. Es kommt dann nur in Zeile 2.
//JTNDeG1sJTIweG1sbnMlM0QlMjJodHRwcyUzQSUyRiUyRmRldmVsb3BlcnMuZ29vZ2xlLmNvbSUyRmJsb2NrbHklMkZ4bWwlMjIlM0UlM0MlMkZ4bWwlM0U=
Gruß
Thorsten
Bitte das Script erstmal in einen Texteditor einfügen, nochmal kopieren und dann erst als Script in ioBroker einfügen.
Hallo Florian,
danke für die AW, das mit dem Einfügen hat jetzt funktioniert, war mein Fehler.
Ich habe das Skript auf den Gaszähler geändert und es funktioniert prima.
Leider bei den Stromzählern nicht. Ich habe zwei Stromzähler angeschlossen und das Skript in Zeile 9 „smartmeter.0.1-0:1_8_0__255.value“ in „smartmeter.0.1-0:2_8_0__255.value“, „smartmeter.1.1-0:1_8_0__255.value“, „smartmeter.1.1-0:2_8_0__255.value“ geändert.
Zusätzlich habe ich die Zeilen 5-8 und 10-13 in javascript.0-180, javascript.0-280, javascript.1-180, javascript.1-280 angepasst.
Die Verzeichnisstrukturen werden in IOBroker angelegt, aber es bleiben die Messdaten für die TMP Verzeichnisse bei „0“ und in den Daten für Hour, Day und Week steht nur der Zählerstand.
Ich würde mich freuen wenn es hier eine Lösung gibt.
Dann würde ich gerne noch die Zählerstände zu einem bestimmten Zeitpunkt abrufen z.B. 31.12.20xx um 23:59 Uhr, bzw. eine Tabelle in Grafana auflisten mit bestimmten Zeitabständen. Gibt es hierfür auch eine Lösung von dir?
LG
Hallo,
Ich habe das gleiche Problem.
History funktioniert grundsätzlich, aber bei diesem Script wird der Wert nur etwa 7 Minuten gespeichert, dann steht dort „keine Daten“.
Gruß Tobbes
Hallo Florian,
vielen Dank für dein super Script!! Habe es seit Monaten für meine Stromzähler in gebrauch und seit heute auch für meinen Wasserzähler.
I love statistics
LG
Hi, danke für das Script.
Leider speichert History nur einen Datenwert und nur ein paar Minuten. Generell funktioniert History bei mir. Bei anderen Objekten wird eine schöne Tabelle mit Werten angezeigt. Bei dem Objekt aus dem Script leider nicht. Habe das Objekt bereits gelöscht und das Script neu gestartet aber der Fehler ist der gleiche.
Was kann ich machen?
Hallo,
leider habe ich genau das gleiche Problem dass History die Daten nur ca. 7 Minuten speichert. an was kann das liegen.?
Danke
Hallo, genau sowas habe ich gesucht, danke erst mal
Skript läuft ohne Fehler allerdings mit 0 Werten
Frage mich jetzt ob ich die Eingangsadresse falsch eingetragen habe oder halt die Start werte fehlen..
Wo werden die hier genau eingetragen?
„common“: {
„name“: „Power consumption of Total-d“,
„desc“: „Power consumption of Total-d“,
„type“: „number“,
„unit“: „kWh“,
„role“: „value“
},
„native“: {
„name“: „Power consumption of Total-d“,
„desc“: „Power consumption of Total-d“,
„type“: „number“,
„unit“: „kWh“,
„role“: „value“
},
„type“: „state“,
„from“: „system.adapter.javascript.0“,
„user“: „system.user.admin“,
„ts“: 1631344785398,
„_id“: „javascript.0.Stromzähler.tmp.Total-d“,
„acl“: {
„object“: 1636,
„state“: 1636,
„owner“: „system.user.admin“,
„ownerGroup“: „system.group.administrator“
}
}
Hallo,
macht es nicht Sinn, beim ersten Stundenintervall ALLE tmp Werte auf den aktuellen Zählerstand zu setzen, wenn sie 0 sind? Ansonsten hat man bei jedem ersten Interwall (d/w/y) den vollen Zählerstand und nicht den ab Script start. Mein SMA-EM ist schon seit 3 Jahren verbaut. Das heißt beim ersten Jahresintervall 2021->2022 krieg ich den Verbrauch von 3 Jahren. Erst Ende nächsten Jahres 2022->2023 wird der korrekte Stand angegeben.
Ich habe mir jetzt so beholfen, dass ich nach dem ersten Stundenintervall die 3 anderen tmp Werte manuell auf den h tmp gesetzt habe.
Hallo! Ja, guter Hinweis. Das korrekte Setzen der Werte zum Zeitpunkt der Scriptaktivierung erzeugt mit dem ersten Intervall korrekte Daten, so ist das im Source-Analytix-Plugin auch umgesetzt.
Danke für das tolle Script! Ich habe es jetzt für meinen Wasserzähler abgeändert und nur wenig ändern müssen. Leider habe ich jetzt das Resultat, das bei altem Zählerstand 512.923 neuem Zählerstand 512.948 als Ergebnis 25 m3 steht. Das sind aber eher 0,25m3 kann ich das irgendwie ändern?
Danke schon mal
Vielen Lieben dank für diese Anleitung bzw. das Script.
Könnte eventuell jemand das script als blockly bereitstellen, oder einen Screenshot vom blockly reingeben?
Bin noch ein totale Noob und verstehe das java script noch nicht ganz und mit blockly kann ich es verstehen und mit dem code vergleichen um es, erstens zu lernen und zweitens auch für was anderes eventuell umzubauen.
Das wäre sehr sehr nett,
Vielen Lieben Dank
LG
Hallo zusammen, habe das Script nun ebenfalls übernommen (erstmal danke dafür). Da ich allerdings keine Werte in den Objekten aktualisiert bekomme, hier meine Verständnisfrage. Muss ich in den vier Total variablen jeweils den aktuellen Stand eintragen (Zeile 5-8)? Unter Zeile 9 habe ich bei „fritzdect.energy“ hinterlegt. Besten Dank schonmal
Moin Zusammen.
Würde das Skript auch gerne probieren, allerdings gabs seit 2021 keine Antwort mehr auf Fragen – wird das Skript noch supported? Funktioniert es fehlerfrei?
Gruß
Danke für dieses super Skript!!
Eine Frage habe ich nur: Wie können die Nachkommastellen der Werte abgeschaltet werden?
Lieben Dank und bitter weiter so.
Einfach in der Zeile mit Math.round testen:
setState(ZielId, Math.round(nDiff), true);
Das Skript ist von der Idee her genau das was ich suche. Ich will bei mir die Verbräuche für Strom und Wasser und Gas entsprechend dokumentieren.
Bevor ich mich aber ans werkeln setze, wüsste ich halt gern, ob das Eingangs abgebildete Script noch aktuell ist? In wie weit wurden die in den Kommentaren dieksutieren Fehler einegarbeitet? Oder muss man das jetzt noch zusammenschnpseln?
Idealerweise stellt mal jemand seine funktionierenden Varianten hier ins Forum – DANKE!!
Der JS-Code sollte fehlerfrei wie beschrieben funktionieren. Wichtig ist, dass das Quell-Objekt des Zählerwerts korrekt definiert wird.
Was jetzt noch cool wäre: Die Zähler zählen z.B. minütlich hoch und nullen erst wieder beim Stunden- Tages- Wochen- Monatsdurchgang. So wie ich das sehe, bleiben die Zähler auf 0 und nur bei Ablauf der Zeit wird einmal der Neuwert reingeschrieben – ist das richtig?
Ich habe einen selbstgebauten auslesekopf mit Tasmota.
Der Datenpunkt sollte eigentlich so aussehen:
sonoff.0.StromZaehler.SML_Total_in
aber ich bekomme keine Werte.
habs auch schon mit .value dahinter versucht, Keine Chance.
Hallo,
erstmal danke für dieses Script, das ist genau das was ich suche.
Jedoch habe ich das gleiche Problem, ich bekomme keine Werte in die Datenpunkte geschrieben.
Ich verwende den History-Adapter, kann es vielleicht daran liegen das ich keine Werte bekomme?
Danke im Voraus.
Hallo!
gibt es mit dem sonoff.0.StromZaehler.SML_Total_in eine positie Nachricht? ichh änge auch da…
Guten Morgen,
ich habe Dein Script erfolgreich im Einsatz, nur habe ich ein kosmetisches Problem.
Wenn ich einen Stundenverbrauch gleich NULL , also idHAGZielH = 0 habe, dann taucht dieser Stundenwert nicht in der Auswertung aus.
Wo muss ich noch etwas einfügen, damit auch NULL Werte ausgegeben werden ?
Danke für Deine Rückmeldung
Hallo Florian
ich weiß nicht ob du dein Problem schon gelöst hast, ich würde in der Anlage der States dies vorbelegen mit 0 (der zahl null) Lg
Hallo,
ich habe leider das Problem, daß der Zähler nicht ausgelesen wird. Habe schon verschiedene Sachen ausprobiert, aber es kommt immer wieder dieser Fehler:
getState „StromZaehler SML Total_in.value“ not found (3)
Kann mir jemand helfen? Den Datenpunkt habe ich aus den Objects kopiert und dann .value dran gesetzt.