Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. JavaScript
    5. setTimeout Verständnisproblem

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    setTimeout Verständnisproblem

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

      Hi,

      ich überwache meinen Trockner mit einem Shelly und habe dafür ein kleines Skript geschrieben, dass die Leistungsuafnahme des Shelly überwacht.

      Ich unterscheide zwischen off/ready/drying und cooldown

      Cooldown sit der Knitterschutz, der Trockner macht am alle paar Sekunden ein paar Umdrehungen.
      Dafür nutze ich ein settimeout von 10 min. Dieses wird gecleared wenn der Trockner wieder eine Umdrehung amcht und von daher wieder n paar W mehr braucht.
      Theoretisch sollte er also erst sagen, dass der Trockner 10 min lang keinen mucks macht und ihn dann in ready schalten und mir eine Nachricht schicken.

      Wenn ich an der stelle Logbucheinträge mache, dann sind die timer auch gelöscht aber sie schicken mir trotzdem 10min später nachrichten.

      Liegt das evtl an dem trigger mit on, das jedesmal eine neue Instanz gebildet wird?
      [edit] laut recherche ist jeder aufruf mit "on" ein neuer Handle und somit setzt er halt keinen timer zurück, weil es in dem Handle keinen gibt. Und der Andere läuft fröhlich weiter.

      createState("javascript.0.Helper.DryerState", "off", {type: 'string',name: 'Zustand Trockner'});//cooldown/idle/drying/off
      //Function zum Ende
      function coolDown () {        
          setState("javascript.0.Helper.DryerState", 'ready');
          setState("javascript.0.Logbuch.array_LogMsg", ['info','Trockner fertig']);
          sendTo("telegram", "send", {
              text: 'ℹ️ - Trockner fertig.' 
          }); 
                
      }
      
      on({id: 'shelly.0.SHPLG-S#DCEB70#1.Relay0.Power', change: "any"}, async function (obj) {
          var power = getState("shelly.0.SHPLG-S#DCEB70#1.Relay0.Power").val;
          var dryerState = getState("javascript.0.Helper.DryerState").val;
      
          if (power > 0 && dryerState == 'off'){//Wird eingeschaltet
              dryerState = 'ready';
              setState("javascript.0.Logbuch.array_LogMsg", ['info','Trockner eingeschaltet']);
              sendTo("telegram", "send", {
                  text: 'ℹ️ - Trockner eingeschaltet.'
              });
          }else if(power == 0 && dryerState != 'off'){       //wird Ausgeschaltet
              dryerState = 'off';
              clearTimeout (cooldowntimer); //Coutndown unterbrechen  
              setState("javascript.0.Logbuch.array_LogMsg", ['info','Trockner ausgeschaltet']);
              sendTo("telegram", "send", {
                  text: 'ℹ️ - Trockner ausgeschaltet.'
              });
          } 
          else if (power > 20 && (dryerState == 'off' || dryerState == 'ready') ) {   //beginnt mit Trocknen 
              starttime = new Date().getTime();
              dryerState = 'drying';
              setState("javascript.0.Logbuch.array_LogMsg", ['info','Trockner gestartet.'+ power]);
              sendTo("telegram", "send", {
                  text: 'ℹ️ - Trockner gestartet!'
              });
          }else if(power < 20 && dryerState == 'drying' ) {  //start Knitterschutz 10 min warten und dann als fertig erkennen
              dryerState = 'cooldown';
              var cooldowntimer = setTimeout (coolDown, 600000);
          }else if(power > 20 && dryerState == 'cooldown'){ //trommel bewegt sich im Knitterschutz
              dryerState = 'drying';
              clearTimeout (cooldowntimer); //Coutndown unterbrechen  
          }   
          setState("javascript.0.Helper.DryerState", dryerState);  // Am Ende die lokale Variable auf den state übertragen  
      });
      

      Da ich das gleiche Prinzip auch eisnetzen möchte um zu sehen ob meine Entwässerungspumpen zu lange laufen, hätte ich das gerne verstanden.

      Gruß
      Nils

      OliverIO 1 Reply Last reply Reply Quote 0
      • OliverIO
        OliverIO @jmeister79 last edited by

        @jmeister79

        2 Probleme sehe ich.
        1)
        der folgende befehl legt jedes mal ein neues timeout an

        var cooldowntimer = setTimeout (coolDown, 600000);
        

        damit du wieder darauf zugreifen kanns gibt er die ein handle/referenz zurück, anhand dessen javascript erkennt welchen du meinst.

        durch das das du da var davor stehen hast, wird die bei jedem funktionsaufruf immer wieder neu initialisiert. der wert der drin steht ist bei verlassen der funktion verloren. d.h. auf genau diesen timeout kannst du nie wieder zugreifen.
        also musst du die variable nach ausserhalb der funktion legen, damit der wert erhalten wird und sie auch nur einmal bei start des skripts initialisiert wird

        wenn du das var entfernt hast, würdest du mit dem obigen befehl ja dennoch immer noch einen neuen timeout generieren und den anderen vergessen.
        daher musst du zuvor prüfen, ob du schonmal einen timeout gestartet hast also bspw so

        if (cooldowntimer!=0) {
          clearTimeout(cooldowntimer);
          cooldowntimer=0;
        }
        

        Nicht vergessen cooldowntimer beim initialisieren und auch nach jedem clearTimeout wieder auf 0 setzen.

        https://developer.mozilla.org/de/docs/Web/API/setTimeout

        jmeister79 2 Replies Last reply Reply Quote 1
        • jmeister79
          jmeister79 @OliverIO last edited by jmeister79

          @oliverio Danke Dir.

          Ich habe gerade nochmal ganz lange nachgedacht ob ich das mit einem Zeitpunkt regeln kann aber stehe grad auf dem Schlauch.

          Ich habe jetzt folgende Idee: Wie von dir gesagt den handle des Timers in ein objekt von ioBroker schreiben, und beim nächsten Aufruf, genau diesen Timer resetten, Jetzt läuft die Waschmaschine und nachher der Trockner, bin gespannt 😉

          [Edit: deine idee ist besser, ich setze mal beide Parallel um und schau mal welche geht.]
          Nils

          1 Reply Last reply Reply Quote 0
          • jmeister79
            jmeister79 @OliverIO last edited by

            @oliverio Hey kleine Rückmeldung.
            Deine Lösung war die richtige.
            Ist ja auch total sinnvoll, jedes on startet n neues handle. Alle darin deklarierten Variablen sind futsch.

            Danke für den Tipp.

            Nils

            OliverIO 1 Reply Last reply Reply Quote 0
            • OliverIO
              OliverIO @jmeister79 last edited by OliverIO

              @jmeister79
              freut mich.
              vor allem. das ist ein besipiel für ein speicherleck.
              der reservierte bereich für den timeout geht ja solange nicht weg, bis der prozess (also skript oder gar javascript-adapter) neu gestartet wird.
              wenn das jetzt sehr oft aufgerufen wird oder das skript längers läuft, dann wird der freie speicher immer weniger

              jmeister79 1 Reply Last reply Reply Quote 0
              • jmeister79
                jmeister79 @OliverIO last edited by

                @oliverio ich hab hier zu nochmal neuigkeiten.

                Trotz dieser Umbauten hat das nicht wirklich funktioniert. Der Timer hat manchmal ziemlichen Mist gebaut udn er hat mit der Zeit eine riesige SWAP Datei erzeugt.

                Ich habe es ejtzt so umgebaut, dass ich auf den Änderugnszeitpunkt der Zustände schaue. das funktioniert zuverlässiger.

                LG
                Nils

                Sokomoto 1 Reply Last reply Reply Quote 0
                • Sokomoto
                  Sokomoto @jmeister79 last edited by

                  @jmeister79 sagte in setTimeout Verständnisproblem:

                  Ich habe es ejtzt so umgebaut,

                  Ich bin als Anfänger mit dem SetTimeout() und Cron auch schon schwer gegen die Wand gelaufen. Deshalb habe ich mir für mein Waschhaus eine Routine gebaut ohne diese zwei Timer. Ist allerdings nicht die schönste Technik. 🙂

                  // Pause Timer in Sekunden
                  function Pause(ms=1) { 
                      ms=ms*1000; // Millisekunden
                      return new Promise(resolve => setTimeout(resolve, ms));
                  }
                  
                  async function Waschhaus(){
                      While (true){ // Endlosschleife
                          code.....
                          await Pause(600); // hier wird dann der Code angehalten für 10 Minuten
                          code....
                          await Pause(10); // stop 10 Sekunden usw...
                      }
                  }
                  
                  // Start
                  Waschhaus();
                  

                  tschuess

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

                  Support us

                  ioBroker
                  Community Adapters
                  Donate

                  796
                  Online

                  31.8k
                  Users

                  80.0k
                  Topics

                  1.3m
                  Posts

                  3
                  7
                  326
                  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