NEWS

JavaScript mit Zeitspannen rechnen (TimeSpan)

  • Starter

    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.

  • Starter

    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 mir

    Number(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 so

          newValue = Math.round(100 * newValue + 1) / 100; // 1 Impuls = 0,01 m³
    
  • Starter

    Super, vielen Dank für die Erklärung. Das bringt mich schon einen Schritt weiter 👍

Suggested Topics

1.0k
Online

35.1k
Users

41.1k
Topics

564.9k
Posts