NEWS
JavaScript mit Zeitspannen rechnen (TimeSpan)
-
Hallo Leute,
gibt es eine einfache Möglichkeit die Zeitspanne der letzen Änderung eines Objektes zu errechnen?
Ich lese aktuell meinen Gaszähler mit einem Reedkontakt aus. In ca. 17 Sekunden werden 0.01m³ Gas verbraucht. Nun ist es so, dass gelegentlich zuviel gezählt wird.
Ich möchte jetzt einbauen dass nur gezählt wird wenn seit dem letzten Durchlauf mindestens 17s vergangen sind.
Mein aktuelles Skript sieht derzeit so aus:
//on ({id: 'zigbee.0.00158d0003469504.opened', change: 'ne'}, IncreaseValue); on ({id: 'sonoff.0.Gaszaehler.POWER2', change: 'ne'}, IncreaseValue); if(!getState('javascript.0.00_CustomVariables.Gasverbrauch').val) { createState('javascript.0.00_CustomVariables.Gasverbrauch',0, true, {name: "Gasverbrauch total",type: "number",desc:"aktueller Zählerstand", unit: "m³", def: 0.00, role: "value"}); } function IncreaseValue() { //var LastChange = formatDate((getState('zigbee.0.00158d0003469504.opened')).lc, 'hh:mm:ss'); var LastChange = formatDate((getState('sonoff.0.Gaszaehler.POWER2')).lc, 'hh:mm:ss'); //if(getState('zigbee.0.00158d0003469504.opened').val) if(getState('sonoff.0.Gaszaehler.POWER2').val) { var NewValue = Number(parseFloat((getState('javascript.0.00_CustomVariables.Gasverbrauch').val + 0.01).toFixed(2))) var Message = "Der Zählerstand beträgt " + NewValue + "m³ - " + LastChange; setState('javascript.0.00_CustomVariables.Gasverbrauch',NewValue,true); //sendTo("telegram.0", "send", {text: Message, disable_notification: true,chatId: xxxxxxxxxx}); log(Message); } }
Ich muss also die Bedingung in Zeile 5 erweitern. Den "LastChange" ermittle ich ja bereits. Was jetzt noch fehlt ist die Zeitspanne mit dem/der aktuellen Datum/Zeit. Ich kenne mich mit JavaScript noch nicht gut aus. Wenn es am aktuellen Script noch Verbesserungen geben kann dann gerne her damit
Mit Powershell wäre es einfach New-Timespan
Aber PS wird ja leider nicht unterstützt
Vielleicht kann mich ja einer in die richtige Richtung schubsen
Vielen Dank und einen schönen 3. Advent
-
@BoBeRzE sagte in JavaScript mit Zeitspannen rechnen (TimeSpan):
Zeitspanne mit dem/der aktuellen Datum/Zeit.
Mit Zeitdifferenz in s:
var lastTime = Date.now(); // aktuelle Uhrzeit in ms seit 1.1.1970 var newValue = parseFloat(getState('javascript.0.00_CustomVariables.Gasverbrauch').val); function IncreaseValue(dp) { var diff = (dp.state.lc - lastTime) / 1000; if(diff >= 17) { lastTime = dp.state.lc; newValue = newValue + 0.01; // 1 Impuls = 0,01 m³ setState('javascript.0.00_CustomVariables.Gasverbrauch', newValue, true); var lastChange = formatDate(lastTime, 'hh:mm:ss'); var Message = "Der Zählerstand beträgt " + newValue + " m³ - um " + lastChange; log(Message); } } on ({id: 'sonoff.0.Gaszaehler.POWER2', change: 'ne', val: true}, IncreaseValue); // triggert bei Änderung false --> true
EDIT: Variable lastTime initialisiert. newValue wird mit parseFloat() initialisiert, für den Fall, dass ein String in den Datenpunkt geraten ist.
-
Hallo paul53,
vielen Dank für die schnelle Hilfe.
Dazu habe ich ein- zwei Fragen.
1: Die Funktion hast du um einen Übergabeparameter "dp" erweitert. Wird der der automatisch von dem Trigger übergeben und ist dadurch innerhalb der Funktion als "dp" verfügbar?
2: Die Variablen lastTime und newValue werden einmalig bei Skriptstart erzeugt und newValue wird befüllt.
- lastTime ist am Anfang "undefiniert" und dadurch wird mit dem ersten Aufruf die Bedingung $true weil diff >= 17
- innerhalb der IF-Abfrage wird lastTime dann auf letzten tatsächlichen Änderungswert gesetzt
3: Funktioniert bei dir "newValue = newValue + 0.01" wie erwartet?
- Ich habe mirNumber(parseFloat((getState('javascript.0.00_CustomVariables.Gasverbrauch').val + 0.01).toFixed(2)))
gebastelt weil ich sonst immer enorm viele Nachkomastellen hatte.
Ich werde versuchen das Ganze später zu integrieren und schauen ob das Script noch läuft
Vielen Dank
-
@BoBeRzE sagte:
Übergabeparameter "dp" erweitert. Wird der der automatisch von dem Trigger übergeben und ist dadurch innerhalb der Funktion als "dp" verfügbar?
Zu 1. Ja.
Zu 2. Habe ich geändert, so dass lastTime mit der aktuellen Uhrzeit initialisiert wird (s. Skript oben).
Zu 3. Du hast den Datenpunkt mit Typ "number" erstellt. Mit Zahlen funktioniert die Berechnung. toFixed(2) wandelt in einen String und ist deshalb kontraproduktiv. Wenn Rundung erforderlich ist, dann sonewValue = Math.round(100 * newValue + 1) / 100; // 1 Impuls = 0,01 m³
-
Super, vielen Dank für die Erklärung. Das bringt mich schon einen Schritt weiter