Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. JavaScript
    5. [gelöst]js-skript zeitspanne Objekt-State "true" erfassen

    NEWS

    • 15. 05. Wartungsarbeiten am ioBroker Forum

    • Monatsrückblick - April 2025

    • Minor js-controller 7.0.7 Update in latest repo

    [gelöst]js-skript zeitspanne Objekt-State "true" erfassen

    This topic has been deleted. Only users with topic management privileges can see it.
    • S
      sveni_lee last edited by

      ich habe ein mini JS-Skript um den Zeitpunkt des Einschaltens eines Objekts zu erfassen…

      on({id: 'hm-rpc.0.OEQ0207710.5.STATE', change: "ne"}, function (obj) {
        if (getState("hm-rpc.0.OEQ0207710.5.STATE").val == true) {
          setState("javascript.0.Bewässerung.Ventil1.Timestamp_ON"/*Timestamp_ON*/, formatDate(new Date(), "TT.MM.JJJJ SS:mm"), true);
        }
      });
      

      nun möchte mir zusätzlich auch noch die Dauer des einschaltens erfassen… aber irgendwie steh ich da grad auf dem Schlauch...

      1 Reply Last reply Reply Quote 0
      • P
        pix last edited by

        hallo sveni_lee,

        es gibt ein Skript von looxer (Betriebstundenzähler), das genau für sowas da ist.

        Wenn du aber gern selbst probieren möchtest, dann brauchst natürlich den Timestamp vom Einschalten und vom Ausschalten.

        /* Test Dauer An Aus
        Skript zeigt Einschaltdauer und Ausschaltdauer bei Änderung an
        https://forum.iobroker.net/posting.php?mode=reply&f=21&t=13432#pr141557
        für sveni_lee
        11.04.2018 erstellt von pix
        */
        
        const idGERAET = "hm-rpc.0.OEQ0207710.5.STATE";
        
        // Variablen werden beim Start(Neustart des Skriptes (oder Javascript Adapters) auf 0 gesetzt. Für dauerhafte Speicherung mit createState() Objekte erstellen
        var ts_ein = 0,
            ts_aus = 0,
            dauer_ein = 0,
            dauer_aus = 0;
        
        on({id: idGERAET, change: "ne"}, function (obj) {
            if (obj.state.val) { // wenn Gerät EIN
                ts_ein = obj.state.ts;
                dauer_ein = ts_ein - ts_aus;
                log("Gerät wurde eingeschaltet und war zuvor " + dauer_ein + "ms ausgeschaltet");
            } else if (!obj.state.val) { // wenn nicht EIN oder wenn AUS
                ts_aus = obj.state.ts;
                dauer_aus = ts_aus - ts_ein;
                log("Gerät wurde ausgeschaltet und war zuvor " + dauer_aus + "ms eingeschaltet");
            }
        });
        
        

        Habs mal bei mir laufen lassen und sieht dann so aus:

        10:58:54.879	[info]	javascript.1 Stop script script.js.Test.Test_DauerAnAus
        10:59:00.998	[info]	javascript.2 Start javascript script.js.Test.Test_DauerAnAus
        10:59:00.998	[info]	javascript.2 script.js.Test.Test_DauerAnAus: registered 1 subscription and 0 schedules
        10:59:04.964	[info]	javascript.2 script.js.Test.Test_DauerAnAus: Gerät wurde eingeschaltet und war zuvor 1523437144961ms ausgeschaltet
        10:59:14.226	[info]	javascript.2 script.js.Test.Test_DauerAnAus: Gerät wurde ausgeschaltet und war zuvor 9263ms eingeschaltet
        10:59:17.463	[info]	javascript.2 script.js.Test.Test_DauerAnAus: Gerät wurde eingeschaltet und war zuvor 3237ms ausgeschaltet
        10:59:20.468	[info]	javascript.2 script.js.Test.Test_DauerAnAus: Gerät wurde ausgeschaltet und war zuvor 3006ms eingeschaltet
        10:59:23.969	[info]	javascript.2 script.js.Test.Test_DauerAnAus: Gerät wurde eingeschaltet und war zuvor 3500ms ausgeschaltet
        

        Das erste Schalten erzeugt natürlich einen falschen Wert, aber danach stimmt es. Natürlich kann mann nun noch die ms in Sekunden oder Minuten so umrechnen.

        Achtung: Wenn es um die Dauer des Einschaltens geht, während das Gerät eingeschaltet ist, braucht man eine ständige Abfrage. Falls dir da nur eine Darstellung in VIS wichtig ist, solltest du auf ein Timestamp/Lastchange-Widget zurückgreifen.

        Gruß

        Pix

        1 Reply Last reply Reply Quote 0
        • S
          sveni_lee last edited by

          Hallo pix,

          den Betriebsstundenzähler habe ich sogar installiert 🙂

          aber so richtig bin ich noch nicht dahinter gestiegen.

          was benötige ich…

          • Zeitpunkt des letzen einschaltens: erledigt
          • Dauer des letzten einschltens: ???
          • kommulierte "Tageszeiten": Betribsstundenzähler
          • kommulierte "Zeiten" pro Woche: Betriebsstundenzähler
          • kommulierte "Zeiten" pro Monat: Betriebsstundenzähler
          • kommulierte "Zeiten" pro Jahr: Betriebsstundenzähler

          Einzi mit der Dauer des letzten einschaltens komm ich noch nicht klar….

          1 Reply Last reply Reply Quote 0
          • S
            sveni_lee last edited by

            ich habe mein Skript mal mit deinem kombiniert, das ganze sieht jetzt so aus…

            var ts_ein = 0,
                ts_aus = 0,
                dauer_ein = 0,
                dauer_aus = 0;
            
            on({id: 'hm-rpc.0.OEQ0207710.5.STATE', change: "ne"}, function (obj) {
              if (obj.state.val) { //wenn Gerät EIN 
                setState("javascript.0.Bewässerung.Ventil1.Timestamp_ON"/*Timestamp_ON*/, formatDate(new Date(), "TT.MM.JJJJ SS:mm"), true);
                ts_ein = obj.state.ts;
              }
              else if (!obj.state.val) { // wenn Gerät AUS
                ts_aus = obj.state.ts;
                dauer_ein = ts_aus - ts_ein;
                log(dauer_ein)
                setState("javascript.0.Bewässerung.Ventil1.Laufzeit_last_ON"/*Laufzeit_last_ON*/, Math.round(dauer_ein/60000) + " Minuten", true);
                }
            });
            

            das ganze funktioniert sogar 😄

            Also besten Dank schon mal

            1 Reply Last reply Reply Quote 0
            • paul53
              paul53 last edited by

              Das geht noch einfacher

              const idDauer = "javascript.0.Bewässerung.Ventil1.Laufzeit_last_ON";
              on('hm-rpc.0.OEQ0207710.5.STATE', function(dp) {
                 if(!dp.state.val) setState(idDauer, Math.round((dp.state.lc - dp.oldState.lc) / 60000), true); // Minuten
              });
              
              1 Reply Last reply Reply Quote 0
              • S
                sveni_lee last edited by

                cool, damit spart man sich tatsächlich auch noch die Variablen…

                dann hätte ich noch eine Frage:

                könnte man im ersten Abschnitt

                on({id: 'hm-rpc.0.OEQ0207710.5.STATE', change: "ne"}, function (obj) {
                  if (obj.state.val) { //wenn Gerät EIN 
                    setState("javascript.0.Bewässerung.Ventil1.Timestamp_ON"/*Timestamp_ON*/, formatDate(new Date(), "TT.MM.JJJJ SS:mm"), true);
                  }
                

                eine art Stopp-uhr mitlaufen lassen, die alle 30 oder 60 sekunden einen wert in ms ausgibt, so dass man einen Wert hätte wie lange das Objekt schon auf true steht?

                1 Reply Last reply Reply Quote 0
                • paul53
                  paul53 last edited by

                  @sveni_lee:

                  eine art Stopp-uhr mitlaufen lassen, die alle 30 oder 60 sekunden einen wert in ms ausgibt, `
                  Dafür gibt es https://wiki.selfhtml.org/wiki/JavaScript/Window/setInterval zusammen mit einer globalen Zählvariablen. Das Stoppen mit https://wiki.selfhtml.org/wiki/JavaScript/Window/clearInterval beim Ausschalten nicht vergessen !

                  1 Reply Last reply Reply Quote 0
                  • S
                    sveni_lee last edited by

                    okay… das starten des Intervals funktioniert:

                    on({id: 'hm-rpc.0.OEQ0207710.5.STATE', change: "ne"}, function (obj) {
                      if (obj.state.val) { //wenn Gerät EIN 
                        setState("javascript.0.Bewässerung.Ventil1.Timestamp_ON"/*Timestamp_ON*/, formatDate(new Date(), "TT.MM.JJJJ SS:mm"), true);
                        setInterval(function(){ 
                            setState("javascript.0.Bewässerung.Ventil1.Laufzeit_last_ON"/*Laufzeit_last_ON*/, Math.round((Date.now() - obj.state.lc)/60000) + " Minuten", true);
                        }, 10000);
                      }
                      else if (!obj.state.val) { // wenn Gerät AUS
                        clearInterval(timer);
                        setState("javascript.0.Bewässerung.Ventil1.Laufzeit_last_ON"/*Laufzeit_last_ON*/, Math.round((obj.state.lc - obj.oldState.lc)/60000) + " Minuten", true);
                        setState("javascript.0.Bewässerung.Ventil1.Menge_last_ON"/*Laufzeit_last_ON*/, Math.round((obj.state.lc - obj.oldState.lc)/60000/60*4000) + " Liter", true);
                        }
                    });
                    

                    aber das mit cearInterval(timer) habe ich noch nicht ganz verstanden

                    EDIT:

                    ich denke ich habs herausgefunden:

                    var intervalId = null;
                    
                    on({id: 'hm-rpc.0.OEQ0207710.5.STATE', change: "ne"}, function (obj) {
                      if (obj.state.val) { //wenn Gerät EIN 
                        setState("javascript.0.Bewässerung.Ventil1.Timestamp_ON"/*Timestamp_ON*/, formatDate(new Date(), "TT.MM.JJJJ SS:mm"), true);
                        intervalId = setInterval(function(){ 
                            setState("javascript.0.Bewässerung.Ventil1.Laufzeit_last_ON"/*Laufzeit_last_ON*/, Math.round((Date.now() - obj.state.lc)/60000) + " Minuten", true);
                        }, 10000);
                      }
                      else if (!obj.state.val) { // wenn Gerät AUS
                        clearInterval(intervalId);
                        setState("javascript.0.Bewässerung.Ventil1.Laufzeit_last_ON"/*Laufzeit_last_ON*/, Math.round((obj.state.lc - obj.oldState.lc)/60000) + " Minuten", true);
                        setState("javascript.0.Bewässerung.Ventil1.Menge_last_ON"/*Laufzeit_last_ON*/, Math.round((obj.state.lc - obj.oldState.lc)/60000/60*4000) + " Liter", true);
                        }
                    });
                    
                    
                    J 1 Reply Last reply Reply Quote 0
                    • paul53
                      paul53 last edited by

                      Weshalb verwendest Du ein Intervall von 10 s, wenn Du den angezeigten Wert auf ganze Minuten rundest ?

                      1 Reply Last reply Reply Quote 0
                      • paul53
                        paul53 last edited by

                          }
                          else if (!obj.state.val) { // wenn Gerät AUS
                        
                        

                        kann vereinfacht werden

                          } else { // wenn Gerät AUS
                        
                        
                        1 Reply Last reply Reply Quote 0
                        • P
                          pix last edited by

                          @sveni_lee:

                          cool, damit spart man sich tatsächlich auch noch die Variablen… `
                          Das Skript sollte nicht möglichst kurz sein, sondern eine Variante von deinem Ursprungsskript. Da du in deinem Skript das gleiche Objekt, welches du mit der on()-Funktion überwachst im Callback mit getState() abfragst, habe ich deine JS-Kenntnisse falsch eingeschätzt.

                          KLappt es jetzt?

                          Pix

                          EDIT:

                          @Paul: auf die Vereinfachungen sollte er selbst kommen 😉

                          1 Reply Last reply Reply Quote 0
                          • S
                            sveni_lee last edited by

                            @pix:

                            Das Skript sollte nicht möglichst kurz sein, sondern eine Variante von deinem Ursprungsskript. Da du in deinem Skript das gleiche Objekt, welches du mit der on()-Funktion überwachst im Callback mit getState() abfragst, habe ich deine JS-Kenntnisse falsch eingeschätzt. `

                            naja, sagen wir mal ich bin blutiger anfänger

                            > KLappt es jetzt?

                            ja, funktioniert nun so… alle 10sec wird der state aktulisiert...

                            1 Reply Last reply Reply Quote 0
                            • J
                              Jukabroker @sveni_lee last edited by

                              @sveni_lee sagte in [gelöst]js-skript zeitspanne Objekt-State "true" erfassen:

                              okay… das starten des Intervals funktioniert:

                              on({id: 'hm-rpc.0.OEQ0207710.5.STATE', change: "ne"}, function (obj) {
                                if (obj.state.val) { //wenn Gerät EIN 
                                  setState("javascript.0.Bewässerung.Ventil1.Timestamp_ON"/*Timestamp_ON*/, formatDate(new Date(), "TT.MM.JJJJ SS:mm"), true);
                                  setInterval(function(){ 
                                      setState("javascript.0.Bewässerung.Ventil1.Laufzeit_last_ON"/*Laufzeit_last_ON*/, Math.round((Date.now() - obj.state.lc)/60000) + " Minuten", true);
                                  }, 10000);
                                }
                                else if (!obj.state.val) { // wenn Gerät AUS
                                  clearInterval(timer);
                                  setState("javascript.0.Bewässerung.Ventil1.Laufzeit_last_ON"/*Laufzeit_last_ON*/, Math.round((obj.state.lc - obj.oldState.lc)/60000) + " Minuten", true);
                                  setState("javascript.0.Bewässerung.Ventil1.Menge_last_ON"/*Laufzeit_last_ON*/, Math.round((obj.state.lc - obj.oldState.lc)/60000/60*4000) + " Liter", true);
                                  }
                              });
                              

                              aber das mit cearInterval(timer) habe ich noch nicht ganz verstanden

                              EDIT:

                              ich denke ich habs herausgefunden:

                              var intervalId = null;
                              
                              on({id: 'hm-rpc.0.OEQ0207710.5.STATE', change: "ne"}, function (obj) {
                                if (obj.state.val) { //wenn Gerät EIN 
                                  setState("javascript.0.Bewässerung.Ventil1.Timestamp_ON"/*Timestamp_ON*/, formatDate(new Date(), "TT.MM.JJJJ SS:mm"), true);
                                  intervalId = setInterval(function(){ 
                                      setState("javascript.0.Bewässerung.Ventil1.Laufzeit_last_ON"/*Laufzeit_last_ON*/, Math.round((Date.now() - obj.state.lc)/60000) + " Minuten", true);
                                  }, 10000);
                                }
                                else if (!obj.state.val) { // wenn Gerät AUS
                                  clearInterval(intervalId);
                                  setState("javascript.0.Bewässerung.Ventil1.Laufzeit_last_ON"/*Laufzeit_last_ON*/, Math.round((obj.state.lc - obj.oldState.lc)/60000) + " Minuten", true);
                                  setState("javascript.0.Bewässerung.Ventil1.Menge_last_ON"/*Laufzeit_last_ON*/, Math.round((obj.state.lc - obj.oldState.lc)/60000/60*4000) + " Liter", true);
                                  }
                              });
                              
                              

                              Hallo sveni_lee
                              ich habe das Script zufällig gefunden und mal nachgebaut, es funktioniert auch, aber nach einiger Zeit ändert sich ohne zutun der Timestamp_ON ??? dann fängt der Timer auch wieder neu an zu zählen.
                              Kannst du da ev. helfen?
                              Jukabroker

                              1 Reply Last reply Reply Quote 0
                              • First post
                                Last post

                              Support us

                              ioBroker
                              Community Adapters
                              Donate

                              546
                              Online

                              31.6k
                              Users

                              79.4k
                              Topics

                              1.3m
                              Posts

                              4
                              13
                              1711
                              Loading More Posts
                              • Oldest to Newest
                              • Newest to Oldest
                              • Most Votes
                              Reply
                              • Reply as topic
                              Log in to reply
                              Community
                              Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                              The ioBroker Community 2014-2023
                              logo