NEWS
Timeout bei Event wieder stoppen, dynamische Instanz
-
Hallo zusammen,
ich habe sehr viele Fenster und wenn es draußen kalt ist, lasse ich mich gerne erinnern, falls noch ein Fenster beim Lüften vergessen wurde zu schließen. Das klappt auch soweit super. Mein Skripkt hat aber noch eine kleine Schwäche. Wenn das Fenster/ die Tür zwischenzeitlich geschlossen wurde, wird der Timer nicht zurückgesetzt. Wenn man es dann wieder öffnet, z.B. Haustüre, kommt die Meldung, dass selbiges noch offen ist sehr, schnell aufgrund des alten vorherigen Timers.
Da ich den Trigger über die Schleife für jedes Fenster aktiviere, habe ich nicht wirklich eine Instanz wo ich mir den aktiven Timer wiederholen kann. In Java hätte ich jetzt mit einer Hashmap gearbeitet. Ich bin mir aber nicht sicher, was hier in JavaScript der elegante Weg ist, um das zu programmieren. Hat hier jemand einen Tipp, bzw. etwas Codesnipsle?
Vielen Dank
Floconsole.log('started...'); const windowDetect = $('zigbee.0.*.opened'); var temperaturLinit = 14; var count = 0; var timeout = 600000; //timeout = 10000; windowDetect.each(function (id, i) { let room = getObject(id, 'rooms').enumNames[0]; if (typeof room == 'object') room = room.de; let funtions = getObject(id, 'functions').enumNames[0]; if (typeof funtions == 'object') funtions = funtions.de; let message = room + ' ' + funtions + ' steht offen!'; registerTrigger(id, message); count++; }); console.log(count + ' sensors registered...'); function registerTrigger(id, message) { on({ id: id, change: "ne" }, async function (obj) { //Lüftungscheck //console.log('Lüftungscheck'); //console.log('getState("zigbee.0.00124b002918d071.temperature").val ' + getState("zigbee.0.00124b002918d071.temperature").val); //console.log('temperaturLinit ' + temperaturLinit); //console.log('new Date().getMonth() ' + new Date().getMonth()); if (getState("zigbee.0.00124b002918d071.temperature").val < temperaturLinit && ((new Date().getMonth() < 4) || (new Date().getMonth() > 9))) { // console.log('Lüftungscheck true'); if (obj.state.val) { //console.log('Lüftungscheck obj true'); setTimeout(async function () { let count = 1; //console.log('Lüftungscheck count ' + count); while (count < 10 && getState(obj.id).val && getState("zigbee.0.00124b002918d071.temperature").val < temperaturLinit) { count++; await alexaAnnounce(message); await telegram(message); await wait(timeout); } }, timeout); } } }); } -
@arteck sagte: timer merken.. pro fenster..
... und count pro Fenster.
Array of timers und Array of counts, korrespondierend zu einem Array of ids, um den Index zu ermitteln.
const ids = $('zigbee.0.*.opened').toArray(); const timers = new Array(ids.length).fill(null); const counts = new Array(ids.length).fill(0);EDIT: Verwende Intervalle.
-
Hallo zusammen,
ich habe sehr viele Fenster und wenn es draußen kalt ist, lasse ich mich gerne erinnern, falls noch ein Fenster beim Lüften vergessen wurde zu schließen. Das klappt auch soweit super. Mein Skripkt hat aber noch eine kleine Schwäche. Wenn das Fenster/ die Tür zwischenzeitlich geschlossen wurde, wird der Timer nicht zurückgesetzt. Wenn man es dann wieder öffnet, z.B. Haustüre, kommt die Meldung, dass selbiges noch offen ist sehr, schnell aufgrund des alten vorherigen Timers.
Da ich den Trigger über die Schleife für jedes Fenster aktiviere, habe ich nicht wirklich eine Instanz wo ich mir den aktiven Timer wiederholen kann. In Java hätte ich jetzt mit einer Hashmap gearbeitet. Ich bin mir aber nicht sicher, was hier in JavaScript der elegante Weg ist, um das zu programmieren. Hat hier jemand einen Tipp, bzw. etwas Codesnipsle?
Vielen Dank
Floconsole.log('started...'); const windowDetect = $('zigbee.0.*.opened'); var temperaturLinit = 14; var count = 0; var timeout = 600000; //timeout = 10000; windowDetect.each(function (id, i) { let room = getObject(id, 'rooms').enumNames[0]; if (typeof room == 'object') room = room.de; let funtions = getObject(id, 'functions').enumNames[0]; if (typeof funtions == 'object') funtions = funtions.de; let message = room + ' ' + funtions + ' steht offen!'; registerTrigger(id, message); count++; }); console.log(count + ' sensors registered...'); function registerTrigger(id, message) { on({ id: id, change: "ne" }, async function (obj) { //Lüftungscheck //console.log('Lüftungscheck'); //console.log('getState("zigbee.0.00124b002918d071.temperature").val ' + getState("zigbee.0.00124b002918d071.temperature").val); //console.log('temperaturLinit ' + temperaturLinit); //console.log('new Date().getMonth() ' + new Date().getMonth()); if (getState("zigbee.0.00124b002918d071.temperature").val < temperaturLinit && ((new Date().getMonth() < 4) || (new Date().getMonth() > 9))) { // console.log('Lüftungscheck true'); if (obj.state.val) { //console.log('Lüftungscheck obj true'); setTimeout(async function () { let count = 1; //console.log('Lüftungscheck count ' + count); while (count < 10 && getState(obj.id).val && getState("zigbee.0.00124b002918d071.temperature").val < temperaturLinit) { count++; await alexaAnnounce(message); await telegram(message); await wait(timeout); } }, timeout); } } }); }@Sesamstrasse sagte: etwas Codesnipsle?
Versuche es mal so:
const ids = $('zigbee.0.*.opened').toArray(); const timers = new Array(ids.length).fill(null); const counts = new Array(ids.length); const mesgs = []; const timeout = 600000; const temperaturLimit = 14; for(let i = 0; i < ids.length; i++) { const id = ids[i]; let room = getObject(id, 'rooms').enumNames[0]; if (typeof room == 'object') room = room.de; let funktion = getObject(id, 'functions').enumNames[0]; if (typeof funktion == 'object') funktion = funktion.de; mesgs[i] = room + ' ' + funktion + ' steht offen!'; }; on(ids, function(dp) { const idx = ids.indexOf(dp.id); if(dp.state.val && getState("zigbee.0.00124b002918d071.temperature").val < temperaturLimit && ((new Date().getMonth() < 4) || (new Date().getMonth() > 9))) { let counts[idx] = 10; timers[idx] = setInterval(function() { if(counts[idx] > 0) { alexaAnnounce(mesgs[idx]); telegram(mesgs[idx]); counts[idx]--; } else { clearInterval(timers[idx]); timers[idx] = null; } }, timeout); } else if(timers[idx]) { clearInterval(timers[idx]); timers[idx] = null; } }); -
Vielen Dank euch für die schnelle Hilfe! Funzt perfekt.
-
Und den Bug mit den counts habe ich noch gar nicht realisiert. In Java wäre das gegangenen :) ein zweites mal vielen Dank!