NEWS
[gelöst]sleep/delay innerhalb einer Loop
-
Hallo,
ich stehe vor einem Problem und komme seit ein paar Tagen nicht weiter. Leider ist mir Javascript an der Stelle nicht "logisch" genug um es zu verstehen.Ich habe folgendes Script:
on({id: 'EigeneDatenpunkte.0.TasmotaUpdateAll', val: true}, function (obj) { setState("EigeneDatenpunkte.0.TasmotaUpdateAllEnable", false); setState("EigeneDatenpunkte.0.TasmotaUpdateAll", false); var value = obj.state.val; var oldValue = obj.oldState.val; var Intervall; log('Tasmota Updates gestartet') $('state(id=mqtt.0.tele.*.INFO2)').each(function(id) { var val = getObject(id).common.name; var varJSONName=JSON.parse(getState(id).val); var varIP=varJSONName.IPAddress; log('Update ' + varJSONName.Hostname + ' gestartet') //hier soll ein sleep eingebaut werden setState("EigeneDatenpunkte.0.History.Events", 'Update ' + varJSONName.Hostname + ' gestartet', true); const url = require('request'); //url.head('http://' + varIP + '/u1?o=http%3A%2F%2Fthehackbox.org%2Ftasmota%2Frelease%2Fsonoff.bin', function(error, response, body) {if (error) log(error, 'error');}); //hier endet der sleep }); //erst wenn der Loop durchgelaufen ist soll das nachfolgende ausgeführt werden log('Tasmota Update beendet'); });
Habe in dem Code an den entsprechenden Stellen beschrieben was ich möchte. Ich bekomme es einfach nicht hin, dass innerhalb der for each Loop ein sleep existiert damit der Befehl nicht für alles fast gleichzeitig ausgeführt wird. Natürlich sollte auch das ausgeben des beenden erst nach dem Lop geloggt werden und nicht direkt.
Kann mir hier jemand Helfen oder auch nur einen guten Tipp geben wie ich das Problem lösen könnte?
-
@tazdevil20 sagte:
der Befehl nicht für alles fast gleichzeitig ausgeführt wird.
Dann sollte man ein Intervall verwenden. Der $Selector liefert die Anzahl der IDs in .length.
Beispiel:const Sonoff = $('state[id=*.POWER](functions="Beleuchtung")'); // Sonoff Lampen var i = 0; log(getObject(Sonoff[i]).common.name); // unverzögerte Aktion var timer = setInterval(function() { i++; if(i < Sonoff.length) { log(getObject(Sonoff[i]).common.name); // verzögerte Aktionen } else { clearInterval(timer); log('beendet'); } }, 1000);
-
@paul53
Ich fürchte ich verstehe das noch nicht und setzte es wohl entsprechend falsch um.
Habe jetzt folgenden Code:on({id: 'EigeneDatenpunkte.0.TasmotaUpdateAll', val: true}, function (obj) { setState("EigeneDatenpunkte.0.TasmotaUpdateAllEnable", false); setState("EigeneDatenpunkte.0.TasmotaUpdateAll", false); var value = obj.state.val; var oldValue = obj.oldState.val; var i = 0; log('Tasmota Updates gestartet') const Devices = $('state(id=mqtt.0.tele.*.INFO2)').each(function(id) { var timer = setInterval(function() { if(i <= Devices.length) { i++ var val = getObject(id).common.name; var varJSONName=JSON.parse(getState(id).val); var varIP=varJSONName.IPAddress; log('Update ' + varJSONName.Hostname + ' gestartet'); setState("EigeneDatenpunkte.0.History.Events", 'Update ' + varJSONName.Hostname + ' gestartet', true); const url = require('request'); //url.head('http://' + varIP + '/u1?o=http%3A%2F%2Fthehackbox.org%2Ftasmota%2Frelease%2Fsonoff.bin', function(error, response, body) {if (error) log(error, 'error');}); } else { clearInterval(timer); log('Tasmota Update beendet'); } }, 3000); }); });
Als Log-Output erhalte ich folgendes:
13.11.2019, 21:58:38.159 [info ]: javascript.0 (11897) script.js.Sonstiges.TasmotaUpdate: Tasmota Updates gestartet 13.11.2019, 21:58:41.180 [info ]: javascript.0 (11897) script.js.Sonstiges.TasmotaUpdate: Update AvatarStromWaschmaschine gestartet 13.11.2019, 21:58:41.181 [info ]: javascript.0 (11897) script.js.Sonstiges.TasmotaUpdate: Update LSCStromGartenhaus gestartet 13.11.2019, 21:58:41.183 [info ]: javascript.0 (11897) script.js.Sonstiges.TasmotaUpdate: Update SonoffBueroKerstin gestartet 13.11.2019, 21:58:41.184 [info ]: javascript.0 (11897) script.js.Sonstiges.TasmotaUpdate: Update SonoffBueroMichael gestartet 13.11.2019, 21:58:41.188 [info ]: javascript.0 (11897) script.js.Sonstiges.TasmotaUpdate: Update SonoffDualGartenBewaesserung gestartet 13.11.2019, 21:58:41.190 [info ]: javascript.0 (11897) script.js.Sonstiges.TasmotaUpdate: Update SonoffKellerFlur gestartet 13.11.2019, 21:58:41.192 [info ]: javascript.0 (11897) script.js.Sonstiges.TasmotaUpdate: Update SonoffStromBewaesserung gestartet 13.11.2019, 21:58:41.194 [info ]: javascript.0 (11897) script.js.Sonstiges.TasmotaUpdate: Update SonoffSchlafzimmer gestartet 13.11.2019, 21:58:44.181 [info ]: javascript.0 (11897) script.js.Sonstiges.TasmotaUpdate: Update AvatarStromWaschmaschine gestartet 13.11.2019, 21:58:44.184 [info ]: javascript.0 (11897) script.js.Sonstiges.TasmotaUpdate: Tasmota Update beendet 13.11.2019, 21:58:44.186 [info ]: javascript.0 (11897) script.js.Sonstiges.TasmotaUpdate: Tasmota Update beendet 13.11.2019, 21:58:44.187 [info ]: javascript.0 (11897) script.js.Sonstiges.TasmotaUpdate: Tasmota Update beendet 13.11.2019, 21:58:44.191 [info ]: javascript.0 (11897) script.js.Sonstiges.TasmotaUpdate: Tasmota Update beendet 13.11.2019, 21:58:44.192 [info ]: javascript.0 (11897) script.js.Sonstiges.TasmotaUpdate: Tasmota Update beendet 13.11.2019, 21:58:44.193 [info ]: javascript.0 (11897) script.js.Sonstiges.TasmotaUpdate: Tasmota Update beendet 13.11.2019, 21:58:44.201 [info ]: javascript.0 (11897) script.js.Sonstiges.TasmotaUpdate: Tasmota Update beendet 13.11.2019, 21:58:47.182 [info ]: javascript.0 (11897) script.js.Sonstiges.TasmotaUpdate: Tasmota Update beendet
Wie man sieht wird zuerst 3 Sekunden gewartet aber dann trotzdem alles gleichzeitig ausgeführt.
Wo ist mein Fehler? -
@tazdevil20 sagte:
Wo ist mein Fehler?
Die each-Schleife muss durch das Intervall ersetzt werden. Etwa so:
const Devices = $('state(id=mqtt.0.tele.*.INFO2)'); var timer = null; on({id: 'EigeneDatenpunkte.0.TasmotaUpdateAll', val: true}, function (obj) { setState("EigeneDatenpunkte.0.TasmotaUpdateAllEnable", false); setState("EigeneDatenpunkte.0.TasmotaUpdateAll", false); var i = 0; log('Tasmota Updates gestartet') timer = setInterval(function() { if(i < Devices.length) { var id = Devices[i]; var val = getObject(id).common.name; var varJSONName=JSON.parse(getState(id).val); var varIP=varJSONName.IPAddress; log('Update ' + varJSONName.Hostname + ' gestartet'); setState("EigeneDatenpunkte.0.History.Events", 'Update ' + varJSONName.Hostname + ' gestartet', true); //request.head('http://' + varIP + '/u1?o=http%3A%2F%2Fthehackbox.org%2Ftasmota%2Frelease%2Fsonoff.bin', function(error, response, body) {if (error) log(error, 'error');}); i++; } else { clearInterval(timer); log('Tasmota Update beendet'); } }, 3000); });
request ist eine im JS-Adapter vordefinierte Variable, also require("request") wird nicht benötigt.
-
@paul53
Vielen Dank. Funktioniert.
Noch eine Verständnisfrage: Die Variable Devices ist jetzt außerhalb der Aktion welche durch das Ändern des Objekts EigeneDatenpunkte.0.TasmotaUpdateAll auf true. Wann würde der $Selector aktualisiert werden? -
@tazdevil20 sagte:
Wann würde der $Selector aktualisiert werden?
Bei Skriptstart. Sind die IDs nicht konstant ?
-
Nicht zwingend. Kann ja mal sein, dass sich die IP oder auch die Anzahl ändert (offline oder auch welche dazu gekommen).
Dann wäre doch ein Workaround, dass das Skript alle x Stunden/Tage neu startet, oder? -
@tazdevil20 sagte:
das Skript alle x Stunden/Tage neu startet, oder?
Dann besser den $Selector innerhalb des Triggers verwenden.
on({id: 'EigeneDatenpunkte.0.TasmotaUpdateAll', val: true}, function (obj) { const Devices = $('state(id=mqtt.0.tele.*.INFO2)');