Skip to content
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Skripten / Logik
  4. Richtig rechnen in JS

NEWS

  • UPDATE 31.10.: Amazon Alexa - ioBroker Skill läuft aus ?
    apollon77A
    apollon77
    48
    3
    8.9k

  • Monatsrückblick – September 2025
    BluefoxB
    Bluefox
    13
    1
    2.3k

  • Neues Video "KI im Smart Home" - ioBroker plus n8n
    BluefoxB
    Bluefox
    16
    1
    3.5k

Richtig rechnen in JS

Geplant Angeheftet Gesperrt Verschoben Skripten / Logik
9 Beiträge 3 Kommentatoren 764 Aufrufe 2 Watching
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • H Offline
    H Offline
    h1ob
    schrieb am zuletzt editiert von h1ob
    #1

    Hallo zusammen,

    ich nutze ein Skript um meinen aktuellen Gasverbrauch / Gaszählerstand zu errechnen. Kurz zur Erklärung:
    Der Gaszähler ist mit einem Impulsgeber ausgestattet. Die Anzahl Impulse (Drehungen der letzten Nachkommastelle am Zähler = 0,01 m3) wird an einen ESP8266 geschickt und dann per MQTT an ioBroker.

    Ich setze inital den aktuellen Gaszählerstand mit zwei Nachkommastellen in den Datenpunkt, aktuell bspw. 51824.05 m³.
    Jeder Impuls vom Gaszähler erhöht den aktuellen Zählerstand um 0.01 m³. Da die Übertragung alle 15 Minuten stattfindet, kommen zwischen 1 und n Impulse rein.

    Das ist der relevante Teil aus dem Skript:

    const iImpuls = 0.01;        
    ...
    iZwSumme = liDelta * iImpuls; //m3
    var lfAktuellm3 = (getState(iAktuell).val) + iZwSumme; 
    

    Ich lasse mir aktuell noch die Zwischenschritte im Log ausgeben um zu sehen ob alles so funktioniert wie gewollt.
    Vorhin wurde ein Impuls gemeldet (=0.01 m³ verbraucht in den letzten 15 Minuten) . Der Datenpunkt stand bei 51824.05. Als neuen Wert hätte ich also 51824.06 erwartet. JS macht daraus aber 51824.060000000005. Ich habe es mit .toFixed und Math.round probiert, aber komme nicht wirklich weiter. Der Impuls ist ja eine Konstante, da gibt es nichts zu interpretieren oder zu runden.

    Wie kriege ich es hin, dass pro Impuls auch wirklich nur 0.01 addiert wird und das auf genau 2 Nachkommastellen?

    paul53P arteckA 3 Antworten Letzte Antwort
    0
    • H h1ob

      Hallo zusammen,

      ich nutze ein Skript um meinen aktuellen Gasverbrauch / Gaszählerstand zu errechnen. Kurz zur Erklärung:
      Der Gaszähler ist mit einem Impulsgeber ausgestattet. Die Anzahl Impulse (Drehungen der letzten Nachkommastelle am Zähler = 0,01 m3) wird an einen ESP8266 geschickt und dann per MQTT an ioBroker.

      Ich setze inital den aktuellen Gaszählerstand mit zwei Nachkommastellen in den Datenpunkt, aktuell bspw. 51824.05 m³.
      Jeder Impuls vom Gaszähler erhöht den aktuellen Zählerstand um 0.01 m³. Da die Übertragung alle 15 Minuten stattfindet, kommen zwischen 1 und n Impulse rein.

      Das ist der relevante Teil aus dem Skript:

      const iImpuls = 0.01;        
      ...
      iZwSumme = liDelta * iImpuls; //m3
      var lfAktuellm3 = (getState(iAktuell).val) + iZwSumme; 
      

      Ich lasse mir aktuell noch die Zwischenschritte im Log ausgeben um zu sehen ob alles so funktioniert wie gewollt.
      Vorhin wurde ein Impuls gemeldet (=0.01 m³ verbraucht in den letzten 15 Minuten) . Der Datenpunkt stand bei 51824.05. Als neuen Wert hätte ich also 51824.06 erwartet. JS macht daraus aber 51824.060000000005. Ich habe es mit .toFixed und Math.round probiert, aber komme nicht wirklich weiter. Der Impuls ist ja eine Konstante, da gibt es nichts zu interpretieren oder zu runden.

      Wie kriege ich es hin, dass pro Impuls auch wirklich nur 0.01 addiert wird und das auf genau 2 Nachkommastellen?

      paul53P Offline
      paul53P Offline
      paul53
      schrieb am zuletzt editiert von
      #2

      @h1ob sagte: JS macht daraus aber 51824.060000000005.

      0.01 muss binär gerundet werden. Vorschlag:

      iZwSumme = liDelta; // Integer
      var lfAktuellm3 = (getState(iAktuell).val) + iZwSumme / 100; 
      

      Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
      Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

      H 1 Antwort Letzte Antwort
      0
      • H h1ob

        Hallo zusammen,

        ich nutze ein Skript um meinen aktuellen Gasverbrauch / Gaszählerstand zu errechnen. Kurz zur Erklärung:
        Der Gaszähler ist mit einem Impulsgeber ausgestattet. Die Anzahl Impulse (Drehungen der letzten Nachkommastelle am Zähler = 0,01 m3) wird an einen ESP8266 geschickt und dann per MQTT an ioBroker.

        Ich setze inital den aktuellen Gaszählerstand mit zwei Nachkommastellen in den Datenpunkt, aktuell bspw. 51824.05 m³.
        Jeder Impuls vom Gaszähler erhöht den aktuellen Zählerstand um 0.01 m³. Da die Übertragung alle 15 Minuten stattfindet, kommen zwischen 1 und n Impulse rein.

        Das ist der relevante Teil aus dem Skript:

        const iImpuls = 0.01;        
        ...
        iZwSumme = liDelta * iImpuls; //m3
        var lfAktuellm3 = (getState(iAktuell).val) + iZwSumme; 
        

        Ich lasse mir aktuell noch die Zwischenschritte im Log ausgeben um zu sehen ob alles so funktioniert wie gewollt.
        Vorhin wurde ein Impuls gemeldet (=0.01 m³ verbraucht in den letzten 15 Minuten) . Der Datenpunkt stand bei 51824.05. Als neuen Wert hätte ich also 51824.06 erwartet. JS macht daraus aber 51824.060000000005. Ich habe es mit .toFixed und Math.round probiert, aber komme nicht wirklich weiter. Der Impuls ist ja eine Konstante, da gibt es nichts zu interpretieren oder zu runden.

        Wie kriege ich es hin, dass pro Impuls auch wirklich nur 0.01 addiert wird und das auf genau 2 Nachkommastellen?

        arteckA Offline
        arteckA Offline
        arteck
        Developer Most Active
        schrieb am zuletzt editiert von
        #3

        @h1ob sagte in Richtig rechnen in JS:

        Wie kriege ich es hin, dass pro Impuls auch wirklich nur 0.01 addiert wird und das auf genau 2 Nachkommastellen?

        guck

        https://www.w3schools.com/jsref/jsref_obj_math.asp

        zigbee hab ich, zwave auch, nuc's genauso und HA auch

        1 Antwort Letzte Antwort
        0
        • paul53P paul53

          @h1ob sagte: JS macht daraus aber 51824.060000000005.

          0.01 muss binär gerundet werden. Vorschlag:

          iZwSumme = liDelta; // Integer
          var lfAktuellm3 = (getState(iAktuell).val) + iZwSumme / 100; 
          
          H Offline
          H Offline
          h1ob
          schrieb am zuletzt editiert von
          #4

          @paul53 Das hat leider nicht funktioniert. Es sieht jetzt so aus:

          iZwSumme wird nicht gebraucht, weil liDelta denselben Wert hat.

          var lfAktuellm3 = (getState(iAktuell).val) + liDelta / 100;
          

          lfAktuellm3 hat trotzdem den Wert 51825.73000000005

          paul53P 1 Antwort Letzte Antwort
          0
          • H h1ob

            @paul53 Das hat leider nicht funktioniert. Es sieht jetzt so aus:

            iZwSumme wird nicht gebraucht, weil liDelta denselben Wert hat.

            var lfAktuellm3 = (getState(iAktuell).val) + liDelta / 100;
            

            lfAktuellm3 hat trotzdem den Wert 51825.73000000005

            paul53P Offline
            paul53P Offline
            paul53
            schrieb am zuletzt editiert von
            #5

            @h1ob sagte: lfAktuellm3 hat trotzdem den Wert 51825.73000000005

            Wenn einmal ein Wert mit vielen Nachkommastellen im Datenpunkt steht, bleibt es ohne Rundung auch so.

            var lfAktuellm3 = Math.round(getState(iAktuell).val * 100 + liDelta) / 100;
            

            Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
            Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

            H 1 Antwort Letzte Antwort
            0
            • paul53P paul53

              @h1ob sagte: lfAktuellm3 hat trotzdem den Wert 51825.73000000005

              Wenn einmal ein Wert mit vielen Nachkommastellen im Datenpunkt steht, bleibt es ohne Rundung auch so.

              var lfAktuellm3 = Math.round(getState(iAktuell).val * 100 + liDelta) / 100;
              
              H Offline
              H Offline
              h1ob
              schrieb am zuletzt editiert von h1ob
              #6

              @paul53

              Nein, ich habe den Wert vorher auf zwei Nachkommastellen manuell in den Datenpunk geschrieben. Das hat auch ein paar Stunden funktioniert. Irgendwann hatte die Zahl dann wieder 10 Nachkommastellen.

              67839b95-3226-41ef-82b8-b7b02922d16e-grafik.png

              Da runden keine Option ist, habe ich eine kleine Funktion geschrieben, die einfach alles ab der zweiten Nachkommastelle abschneidet.

              function CutFloat(str,val) {
                  str = str.toString();
                  str = str.slice(0, (str.indexOf(".")) + val + 1); 
                  return Number(str);   
              };
              
              paul53P 1 Antwort Letzte Antwort
              0
              • H h1ob

                @paul53

                Nein, ich habe den Wert vorher auf zwei Nachkommastellen manuell in den Datenpunk geschrieben. Das hat auch ein paar Stunden funktioniert. Irgendwann hatte die Zahl dann wieder 10 Nachkommastellen.

                67839b95-3226-41ef-82b8-b7b02922d16e-grafik.png

                Da runden keine Option ist, habe ich eine kleine Funktion geschrieben, die einfach alles ab der zweiten Nachkommastelle abschneidet.

                function CutFloat(str,val) {
                    str = str.toString();
                    str = str.slice(0, (str.indexOf(".")) + val + 1); 
                    return Number(str);   
                };
                
                paul53P Offline
                paul53P Offline
                paul53
                schrieb am zuletzt editiert von paul53
                #7

                @h1ob sagte: Da runden keine Option ist

                Weshalb nicht?

                @h1ob sagte in Richtig rechnen in JS:

                alles ab der zweiten Nachkommastelle abschneidet.

                Das entspricht "abrunden".

                Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
                Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

                H 1 Antwort Letzte Antwort
                0
                • paul53P paul53

                  @h1ob sagte: Da runden keine Option ist

                  Weshalb nicht?

                  @h1ob sagte in Richtig rechnen in JS:

                  alles ab der zweiten Nachkommastelle abschneidet.

                  Das entspricht "abrunden".

                  H Offline
                  H Offline
                  h1ob
                  schrieb am zuletzt editiert von h1ob
                  #8

                  @paul53 Weil beim Runden die Gefahr besteht, dass trotz nur einem Impuls dann 0.02 m³ und nicht 0.01³ addiert werden.
                  Ich sehe Werte in der Tabelle, bei denen die dritte Stellen nach dem Komma 5 oder größer ist. Da hätte Math.round() aufgerundet, was schlicht zu einem falschen Ergebnis führen würde.

                  1 Antwort Letzte Antwort
                  0
                  • H h1ob

                    Hallo zusammen,

                    ich nutze ein Skript um meinen aktuellen Gasverbrauch / Gaszählerstand zu errechnen. Kurz zur Erklärung:
                    Der Gaszähler ist mit einem Impulsgeber ausgestattet. Die Anzahl Impulse (Drehungen der letzten Nachkommastelle am Zähler = 0,01 m3) wird an einen ESP8266 geschickt und dann per MQTT an ioBroker.

                    Ich setze inital den aktuellen Gaszählerstand mit zwei Nachkommastellen in den Datenpunkt, aktuell bspw. 51824.05 m³.
                    Jeder Impuls vom Gaszähler erhöht den aktuellen Zählerstand um 0.01 m³. Da die Übertragung alle 15 Minuten stattfindet, kommen zwischen 1 und n Impulse rein.

                    Das ist der relevante Teil aus dem Skript:

                    const iImpuls = 0.01;        
                    ...
                    iZwSumme = liDelta * iImpuls; //m3
                    var lfAktuellm3 = (getState(iAktuell).val) + iZwSumme; 
                    

                    Ich lasse mir aktuell noch die Zwischenschritte im Log ausgeben um zu sehen ob alles so funktioniert wie gewollt.
                    Vorhin wurde ein Impuls gemeldet (=0.01 m³ verbraucht in den letzten 15 Minuten) . Der Datenpunkt stand bei 51824.05. Als neuen Wert hätte ich also 51824.06 erwartet. JS macht daraus aber 51824.060000000005. Ich habe es mit .toFixed und Math.round probiert, aber komme nicht wirklich weiter. Der Impuls ist ja eine Konstante, da gibt es nichts zu interpretieren oder zu runden.

                    Wie kriege ich es hin, dass pro Impuls auch wirklich nur 0.01 addiert wird und das auf genau 2 Nachkommastellen?

                    paul53P Offline
                    paul53P Offline
                    paul53
                    schrieb am zuletzt editiert von paul53
                    #9

                    @h1ob sagte: Jeder Impuls vom Gaszähler erhöht den aktuellen Zählerstand um 0.01 m³. Da die Übertragung alle 15 Minuten stattfindet, kommen zwischen 1 und n Impulse rein.

                    Meine Lösung wäre:

                    var impulse = Math.round(100 * getState(idAktuell).val);
                    
                    on({id: idImpulse}, function(dp) {
                        impulse += dp.state.val;
                        setState(idAktuell, impulse / 100, true);
                    });
                    

                    Die Variable impulse enthält stets einen Integer-Wert.

                    Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
                    Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

                    1 Antwort Letzte Antwort
                    0
                    Antworten
                    • In einem neuen Thema antworten
                    Anmelden zum Antworten
                    • Älteste zuerst
                    • Neuste zuerst
                    • Meiste Stimmen


                    Support us

                    ioBroker
                    Community Adapters
                    Donate

                    616

                    Online

                    32.5k

                    Benutzer

                    81.6k

                    Themen

                    1.3m

                    Beiträge
                    Community
                    Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
                    ioBroker Community 2014-2025
                    logo
                    • Anmelden

                    • Du hast noch kein Konto? Registrieren

                    • Anmelden oder registrieren, um zu suchen
                    • Erster Beitrag
                      Letzter Beitrag
                    0
                    • Home
                    • Aktuell
                    • Tags
                    • Ungelesen 0
                    • Kategorien
                    • Unreplied
                    • Beliebt
                    • GitHub
                    • Docu
                    • Hilfe