Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. JavaScript
    5. Timeout in JS einbinden

    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

    Timeout in JS einbinden

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

      nächster schritt

      Perfekt! Hier ist dein Skript mit korrekt implementiertem Timeout-Handling, sodass clearTimeout(timeout) wie gewünscht funktioniert und nicht bei jedem Trigger-Ereignis verloren geht:


      ✅ Finale Version mit persistentem Timeout

      // 🔥 Heizung ein-/ausschalten bei Energieanforderung
      
      const ids = 'javascript.0.Array_IDs_Heizung_level';       // Datenpunkt mit Array von Level-IDs
      const level_value = 20.1;                                  // Schwellenwert zur Aktivierung der Heizung
      const ID_Liste_Level = getState(ids).val;                  // Array der zu überwachenden IDs
      
      let timeout = null; // ⏱ Timeout-Variable global definieren
      
      // 📡 Trigger bei jeder Änderung eines Wertes in der Liste
      on({ id: [].concat(ID_Liste_Level), change: 'ne' }, async (obj) => {
          let gesamt_value = 0.0;
      
          // 🔁 Summiere alle aktuellen Werte
          for (let i = 0; i < ID_Liste_Level.length; i++) {
              let val = getState(ID_Liste_Level[i]).val;
              gesamt_value += val;
          }
      
          // ✅ Wenn Schwelle erreicht oder überschritten → Heizung AN
          if (gesamt_value >= level_value) {
              setState('javascript.0.Heizung_Kessel_aktiv', true, true);
      
              // ⛔ Bereits laufenden Ausschalt-Timer abbrechen
              if (timeout !== null) {
                  clearTimeout(timeout);
                  timeout = null;
              }
          }
          // ❄️ Wenn unter Schwelle → Heizung AUS (nach 5 Stunden)
          else {
              if (timeout === null) {
                  timeout = setTimeout(() => {
                      setState('javascript.0.Heizung_Kessel_aktiv', false, true);
                      timeout = null; // Timer zurücksetzen
                  }, 300 * 60 * 1000); // 300 Minuten = 5 Stunden
              }
          }
      
          // 📋 Protokolliere aktuellen Summenwert
          console.log('Gesamtanforderung:', gesamt_value);
      });
      

      🧠 Vorteil der Änderung

      Durch die globale timeout-Variable wird verhindert, dass mehrere setTimeout()-Aufrufe gleichzeitig laufen. Stattdessen gibt es genau einen Ausschalt-Timer, der bei Bedarf neu gesetzt oder gelöscht wird.

      Wenn du möchtest, kann ich auch eine erweiterte Version mit Logging, Telegram-Benachrichtigung oder Visualisierung vorbereiten.

      paul53 ubecker 2 Replies Last reply Reply Quote 0
      • OliverIO
        OliverIO @ubecker last edited by

        @ubecker
        das geht auch schon in der kostenlosen version mit chatgpt

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

          @oliverio sagte: Durch die globale timeout-Variable wird verhindert, dass mehrere setTimeout()-Aufrufe gleichzeitig laufen.

          Das ist bei analogen Vergleichswerten auch erforderlich, da andernfalls clearTimeout(timeout) nicht funktioniert.
          Prinzip:

              if (Vergleich von Analogwerten) {
                  setState('javascript.0.Heizung_Kessel_aktiv', true, true);
                  // ⛔ Bereits laufenden Ausschalt-Timer abbrechen
                  if (timeout) {
                      clearTimeout(timeout);
                      timeout = null;
                  }
              } else if (!timeout) {
                  timeout = setTimeout(() => {
                      setState('javascript.0.Heizung_Kessel_aktiv', false, true);
                  }, 300 * 60 * 1000); // 300 Minuten = 5 Stunden
              }
          
          OliverIO 1 Reply Last reply Reply Quote 0
          • OliverIO
            OliverIO @paul53 last edited by

            @paul53 das was copy/paste aus chatgpt

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

              @oliverio said in Timeout in JS einbinden:

              nächster schritt

              Perfekt! Hier ist dein Skript mit korrekt implementiertem Timeout-Handling, sodass clearTimeout(timeout) wie gewünscht funktioniert und nicht bei jedem Trigger-Ereignis verloren geht:


              ✅ Finale Version mit persistentem Timeout

              // 🔥 Heizung ein-/ausschalten bei Energieanforderung
              
              const ids = 'javascript.0.Array_IDs_Heizung_level';       // Datenpunkt mit Array von Level-IDs
              const level_value = 20.1;                                  // Schwellenwert zur Aktivierung der Heizung
              const ID_Liste_Level = getState(ids).val;                  // Array der zu überwachenden IDs
              
              let timeout = null; // ⏱ Timeout-Variable global definieren
              
              // 📡 Trigger bei jeder Änderung eines Wertes in der Liste
              on({ id: [].concat(ID_Liste_Level), change: 'ne' }, async (obj) => {
                  let gesamt_value = 0.0;
              
                  // 🔁 Summiere alle aktuellen Werte
                  for (let i = 0; i < ID_Liste_Level.length; i++) {
                      let val = getState(ID_Liste_Level[i]).val;
                      gesamt_value += val;
                  }
              
                  // ✅ Wenn Schwelle erreicht oder überschritten → Heizung AN
                  if (gesamt_value >= level_value) {
                      setState('javascript.0.Heizung_Kessel_aktiv', true, true);
              
                      // ⛔ Bereits laufenden Ausschalt-Timer abbrechen
                      if (timeout !== null) {
                          clearTimeout(timeout);
                          timeout = null;
                      }
                  }
                  // ❄️ Wenn unter Schwelle → Heizung AUS (nach 5 Stunden)
                  else {
                      if (timeout === null) {
                          timeout = setTimeout(() => {
                              setState('javascript.0.Heizung_Kessel_aktiv', false, true);
                              timeout = null; // Timer zurücksetzen
                          }, 300 * 60 * 1000); // 300 Minuten = 5 Stunden
                      }
                  }
              
                  // 📋 Protokolliere aktuellen Summenwert
                  console.log('Gesamtanforderung:', gesamt_value);
              });
              

              🧠 Vorteil der Änderung

              Durch die globale timeout-Variable wird verhindert, dass mehrere setTimeout()-Aufrufe gleichzeitig laufen. Stattdessen gibt es genau einen Ausschalt-Timer, der bei Bedarf neu gesetzt oder gelöscht wird.

              Wenn du möchtest, kann ich auch eine erweiterte Version mit Logging, Telegram-Benachrichtigung oder Visualisierung vorbereiten.


              super; einzig was noch fehlt sind die Bedingungen wenn Heizug schon auf true steht braucht nicht wieder gesetzt zu werden, auch beim ausschalten. sind aber nur 2 if Bedingungen.

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

                @oliverio
                kleiner Fehler in dem Script:
                console.log('Gesamtanforderung:', gesamt_value);
                funktioniert so nicht da erst ein String und dann eine Zahl.
                Zahl nach String konvertieren oder einfach den String 'Gesamtanforderung:' weglassen

                sonst alles ok, meine if Bedingung zum setzen hab ich auch eingebaut.

                nochmals Danke.

                M paul53 OliverIO 3 Replies Last reply Reply Quote 0
                • M
                  MCU @ubecker last edited by

                  @ubecker sagte in Timeout in JS einbinden:

                  console.log('Gesamtanforderung:', gesamt_value);

                  console.log('Gesamtanforderung: '+ gesamt_value);
                  
                  1 Reply Last reply Reply Quote 0
                  • paul53
                    paul53 @ubecker last edited by

                    @ubecker sagte: funktioniert so nicht da erst ein String und dann eine Zahl.

                    Funktioniert, wenn das Komma durch ein Plus ersetzt wird.

                    1 Reply Last reply Reply Quote 1
                    • OliverIO
                      OliverIO @ubecker last edited by OliverIO

                      @ubecker sagte in Timeout in JS einbinden:

                      console.log('Gesamtanforderung:', gesamt_value);

                      wie gesagt, das skript ist nicht von mir überarbeitet worden, sondern von chatGPT
                      nach Definition ist das richtig
                      https://developer.mozilla.org/en-US/docs/Web/API/console/log_static
                      https://nodejs.org/api/console.html#consolelogdata-args
                      console.log nimmt 1 bis N parameter. jeder parameter wird gemäß typ so ausgegeben

                      mit + wird automatisch von javascript der typ aus gesamt_value nach string gewandelt und dann das ergebnis angehängt.

                      da scheint es im javascript adapter noch was geben
                      hier die ausgabe aus der browser console
                      4e69704f-ced3-4f57-b243-1db1d37289bd-image.png

                      und aus der node repl (einfach node starten)
                      d774bb97-a55f-42fd-a7be-ae1477382e26-image.png

                      habe mal geschaut.
                      da ist die typdefinition im javascript adapter nicht ganz korrekt.
                      die console befehle kennen alle nur einen parameter.
                      allerdings ist das auch nicht die priorität, ist ja eh nur für debugging
                      https://github.com/ioBroker/ioBroker.javascript/blob/64c375ea0e0840f21a7cc12582c970022f061fa2/src/types.d.ts#L570

                      P ubecker 2 Replies Last reply Reply Quote 0
                      • P
                        peterfido @OliverIO last edited by

                        @oliverio Für solche Zeitspannen setze ich auf einen Datenpunkt, welcher minutiös heruntergezählt wird. Arbeitet man am ioBroker innerhalb der fünf Stunden, kann es sonst passieren, dass das Timeout verlorengeht.

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

                          @peterfido
                          Besser:
                          Den Ende timestamp in einem datenpunkt merken und dann regelmäßig prüfen, ob er erreicht wird. Bzw. der datenpunkt existiert nur falls der Adapter neu gestartet wird, damit man wieder neu aufsetzen kann.
                          Dann schreibt man nicht so oft in der Datenbank herum.

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

                            @oliverio Der Schreibzyklen wegen vielleicht schon. Darüber habe ich mir zu Raspi-Zeiten tatsächlich Gedanken gemacht.Also, wie so oft, ein "kommt darauf an".

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

                              @oliverio said in Timeout in JS einbinden:

                              allerdings ist das auch nicht die priorität, ist ja eh nur für debugging

                              genau.

                              @oliverio said in Timeout in JS einbinden:

                              Den Ende timestamp in einem datenpunkt merken und dann regelmäßig prüfen, ob er erreicht wird. Bzw. der datenpunkt existiert nur falls der Adapter neu gestartet wird, damit man wieder neu aufsetzen kann.
                              Dann schreibt man nicht so oft in der Datenbank herum

                              hier eigentlich unkritisch. Dann bleibt die Heizung weitere 5 Std. an.
                              ich lass es erst mal beim normalen Teimout und werde das beobachten.

                              danke an alle

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

                              Support us

                              ioBroker
                              Community Adapters
                              Donate

                              742
                              Online

                              31.8k
                              Users

                              80.0k
                              Topics

                              1.3m
                              Posts

                              6
                              24
                              373
                              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