NEWS
Timeout in JS einbinden
-
Hallo
für den Fachmann wohl eine Kleinigkeit, ich weiss nicht wie man das schreiben soll
Mein Script:// Heizung ein bei Energieanforderung const ids = 'javascript.0.Array_IDs_Heizung_level'/*Array IDs Heizung level*/ const ID_Liste_Level = getState(ids).val; const level_value = 20.1; // Trigger auf Array ID Heizung level on({ id: [].concat(ID_Liste_Level), change: 'ne' }, async (obj) => { let value = obj.state.val; let oldValue = obj.oldState.val; // FOR Schleife um Daten zu holen var x_end = ID_Liste_Level.length -1; var x_inc = 1; var gesamt_value = 0.0; var timeout; if (0 > x_end) { x_inc = -x_inc;} for (var x = 0; x_inc >= 0 ? x <= x_end : x >= x_end; x += x_inc) { // Level geändert gesamt_value = gesamt_value + (getState(ID_Liste_Level[x]).val ) } // Test auf level_value if (gesamt_value >= level_value) { // Heizung ein setState('javascript.0.Heizung_Kessel_aktiv'/*Heizung Kessel aktiv*/,true,true) // clear timeout muss hier hinzu } // Heizung aus soll aber erst nach 5 Std else //Timeout setzten 300min muss hier rein {setState('javascript.0.Heizung_Kessel_aktiv'/*Heizung Kessel aktiv*/,false,true)} console.log(gesamt_value) }); Kann mit einer den code eintragen. danke
-
evtl solltest du genauer beschreiben was du willst.
mir sind das zuwenig informationen -
@oliverio said in Timeout in JS einbinden:
evtl solltest du genauer beschreiben was du willst.
mir sind das zuwenig informationensorry dachte das wäre so schon klar.
ich möchte an den Stellen in dem Script
// clear timeout muss hier hinzu
einen Clear Timeout habenund hier:
//Timeout setzten 300min muss hier rein
soll ein Timeout starten -
gut, auf basis der informationen die du mir gegeben hast
// Heizung ein bei Energieanforderung const ids = 'javascript.0.Array_IDs_Heizung_level'/*Array IDs Heizung level*/ const ID_Liste_Level = getState(ids).val; const level_value = 20.1; // Trigger auf Array ID Heizung level on({ id: [].concat(ID_Liste_Level), change: 'ne' }, async (obj) => { let value = obj.state.val; let oldValue = obj.oldState.val; // FOR Schleife um Daten zu holen var x_end = ID_Liste_Level.length -1; var x_inc = 1; var gesamt_value = 0.0; var timeout; if (0 > x_end) { x_inc = -x_inc;} for (var x = 0; x_inc >= 0 ? x <= x_end : x >= x_end; x += x_inc) { // Level geändert gesamt_value = gesamt_value + (getState(ID_Liste_Level[x]).val ) } // Test auf level_value if (gesamt_value >= level_value) { // Heizung ein setState('javascript.0.Heizung_Kessel_aktiv'/*Heizung Kessel aktiv*/,true,true) // clear timeout muss hier hinzu clearTimeout(timeout); } // Heizung aus soll aber erst nach 5 Std else //Timeout setzten 300min muss hier rein timeout=setTimeout(() => { setState('javascript.0.Heizung_Kessel_aktiv'/*Heizung Kessel aktiv*/,false,true); }, 300*60*60*1000); console.log(gesamt_value) }); Kann mit einer den code eintragen. danke
-
@oliverio
danke, so einfach?
Hatte das in blockly gemacht und als JS augegeben. Da sah das sehr komplex aus. -
keine ahnung.
du hattest ja nur geschrieben, hier die entsprechenden befehle eintragen und das habe ich getan.
warum und wieso weiß ich ja nicht.hier die Hilfeseiten dazu
https://developer.mozilla.org/en-US/docs/Web/API/Window/clearTimeout
https://developer.mozilla.org/en-US/docs/Web/API/Window/setTimeout -
300*60*60*1000 sind mehr als 5Stunden? 300*60*1000 -> 5Std
-
@ubecker sagte in Timeout in JS einbinden:
@oliverio
danke, so einfach?
Hatte das in blockly gemacht und als JS augegeben. Da sah das sehr komplex aus.Dafür kannste auch KI verwenden, in vielen Fällen übersetzt sie die Blockly gut in JS. Ob es dann auch ressourcenschonend ist, steht auf einem anderen Blatt (dafür bracht es Profis).
-
@oliverio
alles ok, mir ging es nur um die syntax zu den Befehlen. Hab das nirgendwo gefunden.
und danke für die links
Zur weiteren Info:
ich teste mittels Array Werte von (ca 20) Heizkörperventilen
Wenn die Raumtemperatur abfällt öffnen die Ventile = Energieanforderung.
Dann schalte ich die Heizung ein
Der Timeout macht nur eine Verzögerung des ausschalten der Heizung -
ah ja, einmal 60* zuviel
-
zunächst mal durch ki formatiert und erklärt
Gerne! Hier ist dein Skript strukturiert, korrekt eingerückt und mit Kommentaren erklärt. Es handelt sich um ein JavaScript-Skript für ioBroker (Blockly/JavaScript Adapter), das prüft, ob die Heizungsanforderung durch verschiedene Quellen hoch genug ist, um den Heizkessel einzuschalten – oder nach 5 Stunden auszuschalten.
Formatierter und erklärter Code
// 🔥 Heizung ein-/ausschalten bei Energieanforderung const ids = 'javascript.0.Array_IDs_Heizung_level'; // Array mit allen Level-IDs const ID_Liste_Level = getState(ids).val; // Liest die Array-IDs aus dem Datenpunkt const level_value = 20.1; // Schwellenwert für Aktivierung der Heizung // ⏱ Trigger auf Änderungen in einem der Level-Werte on({ id: [].concat(ID_Liste_Level), change: 'ne' }, async (obj) => { let value = obj.state.val; let oldValue = obj.oldState.val; // 🔁 Schleife über alle Heiz-Level IDs let x_end = ID_Liste_Level.length - 1; let x_inc = 1; let gesamt_value = 0.0; let timeout; if (x_end < 0) { x_inc = -x_inc; } for (let x = 0; x_inc >= 0 ? x <= x_end : x >= x_end; x += x_inc) { gesamt_value += getState(ID_Liste_Level[x]).val; } // ✅ Wenn die Gesamtleistung über dem Schwellwert liegt if (gesamt_value >= level_value) { // Heizung aktivieren setState('javascript.0.Heizung_Kessel_aktiv', true, true); // Eventuell vorhandenen Ausschalt-Timer löschen clearTimeout(timeout); } else { // ❄️ Heizung erst nach 5 Stunden deaktivieren timeout = setTimeout(() => { setState('javascript.0.Heizung_Kessel_aktiv', false, true); }, 300 * 60 * 1000); // 300 Minuten = 5 Stunden } // 🧾 Debug-Ausgabe console.log(gesamt_value); });
🧠 Was macht das Skript genau?
Abschnitt Funktion getState(ids).val
Holt die Liste der IDs, deren Werte überwacht werden sollen on({...})
Reagiert auf jede Änderung eines Werts in dieser Liste for
-SchleifeSummiert alle aktuellen Werte der IDs (z. B. Heizkreise) if gesamt_value >= ...
Wenn genug Anforderung vorhanden ist → Heizung an else
mitsetTimeout
Sonst: nach 5 Stunden (300 Minuten) → Heizung aus clearTimeout(timeout)
Wenn vorher ein Ausschalten geplant war, aber jetzt wieder Anforderung kommt, wird der Timer gelöscht
Hinweise
timeout
ist aktuell lokal in der Funktion definiert – wird aber bei jedem Trigger neu gesetzt. Damit der Ausschalt-Timer persistiert, musstimeout
außerhalb des Event-Handlers deklariert werden (sonst funktioniertclearTimeout()
nicht wie gewünscht).
Mögliche Verbesserung:
let timeout; // globale Variable außerhalb des Event-Handlers on({...}) { ... }
Wenn du willst, kann ich das für dich gleich verbessern.
-
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 mehreresetTimeout()
-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.
-
@ubecker
das geht auch schon in der kostenlosen version mit chatgpt -
@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 }
-
@paul53 das was copy/paste aus chatgpt
-
@oliverio said in Timeout in JS einbinden:
nächster schritt
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. -
@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:' weglassensonst alles ok, meine if Bedingung zum setzen hab ich auch eingebaut.
nochmals Danke.
-
@ubecker sagte in Timeout in JS einbinden:
console.log('Gesamtanforderung:', gesamt_value);
console.log('Gesamtanforderung: '+ gesamt_value);
-
@ubecker sagte: funktioniert so nicht da erst ein String und dann eine Zahl.
Funktioniert, wenn das Komma durch ein Plus ersetzt wird.
-
@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 ausgegebenmit + 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
und aus der node repl (einfach node starten)
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