NEWS
Datenpunkt hat im Skript immer den Wert vom vorherigen Lauf
-
Hallo zusammen,
ich möchte meinen Gaszähler smart machen und habe dafür einen Reed Kontakt an einer NodeMCU angeschlossen. Die Werte (Anzahl Umdrehungen etc.) kommen per MQTT. Das funktioniert soweit einwandfrei. Nun möchte ich ein Skript bauen, welches mir den Gasverbrauch pro Tag/Woche etc. berechnet. Dabei habe ich aber ein Problem. Ich befürchte ich sehe vor lauter Bäumen den Wald nicht.
Hier ein Auszug aus dem Skript:
var bLogging = true; // Log (de)aktivieren var iZaehler = 'mqtt.0.Gaszaehler.Gasverbrauch.Count' ; //Anzahl Impulse vom NodeMCU var iZaehlerTotal = 'mqtt.0.Gaszaehler.Gasverbrauch.Total'; //Anzahl Impulse vom NodeMCU (Total) Wenn über zwei Perioden der Count identisch ist, wird nur Total aktualisiert var iArbeitsvariable = 'gaszaehler.0.arbeitsvariable'; //Anzahl Impulse var iAktuell = 'gaszaehler.0.aktuellerstand'; // Aktueller Stand des Gaszählers var iOffset = 'gaszaehler.0.zaeheleroffset';// Offset, falls Anzeige und tatsächlicher Verbrauch abweichen sollten var iImpuls = 0.01; //1 Impuls des Gaszählers entspricht 0,01m³ = 10 Liter const cBrennwert = 11.5; //Brennwert des Gases: 11.5 (Für Umrechung m³ in kWh) // Prüfe ob per MQTT neue Daten angekommen sind on({id: new RegExp('mqtt\\.0\\.Gaszaehler\\.Gasverbrauch\\.Total' + "|" + 'mqtt\\.0\\.Gaszaehler\\.Gasverbrauch\\.Count'), change: "any"}, function (obj) { log(parseInt(getState(iZaehler).val,10)); setState(iArbeitsvariable, getState(iZaehler).val); if (bLogging) log('Zähler hinzugefügt: ' + getState(iZaehler).val + ' / ' + getState(iArbeitsvariable).val); // Zwischenrechnung für die anschließende Aufsummierung iZwSumme = iImpuls * parseFloat(getState(iArbeitsvariable).val) * cBrennwert; log('Zwischensumme: ' + iZwSumme); // Delta-Verbrauch festhalten // TODO: Offset einbauen setState(iAktuell, getState(iAktuell).val + (iImpuls * parseInt(getState(iArbeitsvariable).val,10))); //fSummenbildung(); });
An einigen Stellen lasse ich mir aktuell noch Werte ins Log ausgeben. Dabei ist mir aufgefallen, dass iZaehler immer den aktuellen Count hat, was ich auch so erwarten würde. Allerdings hat iArbeitsvariable bei jeder Ausführung trotz setState() immer den Wert vom vorherigen Lauf.
Hier das Log dazu:
12:24:56.370 info javascript.0 script.js.Gaszaehler.GaszaehlerVerbrauch: 15 12:24:56.370 info javascript.0 script.js.Gaszaehler.GaszaehlerVerbrauch: Zähler hinzugefügt: 15 / 10 12:24:56.370 info javascript.0 script.js.Gaszaehler.GaszaehlerVerbrauch: Zwischensumme: 1.1500000000000001 12:25:10.067 info javascript.0 script.js.Gaszaehler.GaszaehlerVerbrauch: 31 12:25:10.068 info javascript.0 script.js.Gaszaehler.GaszaehlerVerbrauch: Zähler hinzugefügt: 31 / 15 12:25:10.068 info javascript.0 script.js.Gaszaehler.GaszaehlerVerbrauch: Zwischensumme: 1.7249999999999999 12:25:44.818 info javascript.0 script.js.Gaszaehler.GaszaehlerVerbrauch: 17 12:25:44.818 info javascript.0 script.js.Gaszaehler.GaszaehlerVerbrauch: Zähler hinzugefügt: 17 / 31 12:25:44.819 info javascript.0 script.js.Gaszaehler.GaszaehlerVerbrauch: Zwischensumme: 3.565
Woran liegt das?
-
Hallo, ich habe es bei mir im Blockly gelöst. Es ist ohne Kommentare, aber ich hoffe du kannst es trotzdem nachvollziehen.
Ich habe eine einen Hilfsdatenpunkt erstellt mit dem alten Stand des mqtt Zählers. Falls dieser sich verändert wird die Differenz davon zum Gesamt hinzugefügt.
Den Umweg bin ich deswegen gegangen, weil mein Server mit Ubuntu ab und zu mal neu gestartet werden muss, aber somit geht kein Verbrauch verloren.
Zusätzlich das if wenn der MCU mal neu startet und der counter auf 0 ist.
Mein Zählerstand ist damit bisher immer perfekt synchron.
mqtt hab ich derzeit auf 60 sek.
-
Ihr habt einen denkfehler!!
In einem trigger auf einen Datenpunkt gibt es immer den neuen Wert direkt mit. Entweder in JavaScript zb in obj.state.val bzw in blockly gibt es die Variable „value“ im trigger. Die enthält den aktuellen Wert!
Der Wert den ihr per getState im trigger bekommt kann durchaus noch der alte sein.
Gesendet vom Handy …
-
Danke euch beiden.
Ich kenne obj.state.val, aber das wird bei mir nicht funktionieren, da ich ja den Trigger auf Count oder Total gesetzt habe. Das sind unterscheidliche Werte und ich kann mit einem davon weiterrechnen. Deshalb brauche ich einen umständlicheren, aber allgemeinen Ansatz.
-
@e-s:Hallo, ich habe es bei mir im Blockly gelöst. Es ist ohne Kommentare, aber ich hoffe du kannst es trotzdem nachvollziehen.
gasblockly.png
Ich habe eine einen Hilfsdatenpunkt erstellt mit dem alten Stand des mqtt Zählers. Falls dieser sich verändert wird die Differenz davon zum Gesamt hinzugefügt.
Den Umweg bin ich deswegen gegangen, weil mein Server mit Ubuntu ab und zu mal neu gestartet werden muss, aber somit geht kein Verbrauch verloren.
Zusätzlich das if wenn der MCU mal neu startet und der counter auf 0 ist.
Mein Zählerstand ist damit bisher immer perfekt synchron.
mqtt hab ich derzeit auf 60 sek. `
Hi nochmal,
ich habe dein Blockly Skript durchgearbeitet und es auch so bei mir umgesetzt. Vielen Dank für den Hinweis mit dem Total Count. Das ist in der Tat viel besser als der normale Count.
Ich arbeite jetzt mit Variablen statt getState(), da ich heute gelernt habe, dass setState() asynchron arbeitet und man unter Umständen noch den alten Wert per getState() zurückbekommt. Jetzt funktioniert alles wie es soll.