NEWS
BWM: Lampe an, solange Bewegung stattfindet.
-
Frohe Weihnachten,
ich habe jetzt eine Weile versucht eine Lösung zu finden, bin aber noch nicht so recht weitergekommen.
Mein Anliegen ist vermutlich recht trivial. Ich möchte, dass eine Lampe auf einen Bewegungsmelder angeschaltet und nach einer bestimmten Zeit wieder ausgeschaltet wird. Problem: Die Zeit (bspw. 2 Minuten) soll jedes Mal von vorn starten, solange noch Bewegung erkannt wird.
Ich hatte dieses versucht wie folgt zu lösen (RF-Bewegungsmelder von Sonoff):on({id: 'sonoff.0.DVES_CCC9EE.RfReceived_Data', change: 'any'}, function(obj){ var dev = obj.state.val //ID des meldenden Geräts var dauer = 60000 if (dev == "EE780E") { var melder = "Terrasse"; setTimeout(function (){ setState('hs100.0.192_168_22_52.state', false); log("Licht aus. Melder war: " + melder); }, dauer); setState('hs100.0.192_168_22_52.state', true/); } } });
Dieses hat für den Einzelfall auch gut funktioniert. Wenn ich die Terrasse betreten habe und der BWM dieses erkannt, war die Garagenlampe für eine Minute an. Mittlerweile habe ich erkannt, dass dieses vermutlich einfacher mit setStateDelayed zu lösen gewesen wäre, aber erstmal egal.
Mein Problem war bei einer Party auf der Terrasse. Das Licht ging nur noch an und aus, da ja stets ein neuer Durchlauf erfolgte.
Mein Gedanke wäre daher, dass ich bei Meldung des BWM die Lampe einschalte und eine Zeitschleife starte. Innerhalb dieser Schleife überprüfe ich, ob erneut eine Bewegung registriert wurde und setze den die Schleife (Zeitwert) wieder hoch. Wenn keine Bewegung erfolgt ist, wird die Lampe nach dem Durchlauf der Schleife ausgeschaltet.
Wäre dies in der Theorie korrekt und wie könnte ich die Schleife aufbauen?
Eine For-Schleife mit bspw. 60 Durchläufen bei der eine Sleepfunktion 1 Sekunde pausiert, anschließend die Bewegung erfragt und den Durchlauf ggf. wieder auf 60 setzt, scheint es in Javascript so nicht zu geben.
Wie habt ihr dieses Problem gelöst?Viele Grüße
Fritz
Mod-Edit: Code in Code-Tags gesetzt!
-
@fritz74 sagte:
Die Zeit (bspw. 2 Minuten) soll jedes Mal von vorn starten, solange noch Bewegung erkannt wird.
Das macht das Skript nicht, sondern bei häufiger Bewegungserkennung laufen mehrere Timeouts gleichzeitig. Besser so:
var timer = null; on({id: 'sonoff.0.DVES_CCC9EE.RfReceived_Data', change: 'any'}, function(obj){ var dev = obj.state.val //ID des meldenden Geräts var dauer = 60000 if (dev == "EE780E") { var melder = "Terrasse"; if(timer) clearTimeout(timer); timer = setTimeout(function (){ setState('hs100.0.192_168_22_52.state', false); log("Licht aus. Melder war: " + melder); }, dauer); setState('hs100.0.192_168_22_52.state', true/); } } });
-
Hallo Paul,
vielen Dank für deine Idee mit "setTimeout" und "clearTimeout". Ich habe es eben getestet und es funktioniert schon viel besser!!!
(Bei der Funktion "on" habe ich zusätzlich zu "id" noch "val" auf "true" gesetzt, damit das Licht nicht auch schaltet, wenn presence zurück auf false geht.var timer = null; on({id: 'hue.0.Philips_hue.Bew_Flur_Keller.presence', val: true}, function(obj){ console.log("Bewegung erkannt!"); if(timer) clearTimeout(timer); timer = setTimeout(function (){ //setState('hue.0.Philips_hue.Erkerlampe.on', false); console.log("Licht aus."); }, 60000); //setState('hue.0.Philips_hue.Erkerlampe.on', true); console.log("Licht an."); });
Ein Problem muss ich allerdings noch lösen.
Die Funktion "on" greift ja nur, wenn eine Änderung auf "true" erfolgt. Ich habe dein Script, wie du siehst, jetzt an einem Hue-Innen-Bewegungsmelder getestet. (Hamburg ist gerade kalt und nass ;-))
Dieser BWM schaltet nach ca. 10 Sekunden ohne Bewegung die id: "...presence" zurück auf "false". Dann funktioniert das Ganze wunderbar, sowie immer wieder neue Bewegungen erkannt werden.
Wenn allerdings die ganze Zeit Bewegungen erfolgen (z.B. Gäste ziehen sich im Flur an) kommt der BWM gar nicht in die Versuchung zurück in "false" zu gehen und nach 60 Sekunden (im obigen Fall) ist die Lampe trotz Bewegung aus, da das Script nicht erneut durchlaufen wird.
Da müsste ich doch am besten in der setTimeout-Funktion vor dem Abschalten der Lampe mit einer if-Abfrage zunächst testen, ob "presence" den Wert "true" hat und dann sozusagen zurück in Zeile 3 springen. Aber wie?Hast du dafür vielleicht auch eine Idee oder mache ich einen Gedankenfehler?
Fritz
-
@fritz74 sagte in:
Die Funktion "on" greift ja nur, wenn eine Änderung auf "true" erfolgt.
In dieser Konstellation wird auch getriggert, wenn sich nur der Zeitstempel ändert bei konstantem Wert true.
@fritz74 sagte in BWM: Lampe an, solange Bewegung stattfindet.:
kommt der BWM gar nicht in die Versuchung zurück in "false" zu gehen
Wenn das Licht anbleiben soll, solange Bewegung erkannt wird, muss das verzögerte Ausschalten auf false erfolgen.
var timer = null; on('hue.0.Philips_hue.Bew_Flur_Keller.presence', function(obj){ // triggert bei Wertänderung if(obj.state.val) { console.log("Bewegung erkannt!"); //setState('hue.0.Philips_hue.Erkerlampe.on', true); console.log("Licht an."); if(timer) clearTimeout(timer); } else { timer = setTimeout(function (){ //setState('hue.0.Philips_hue.Erkerlampe.on', false); console.log("Licht aus."); }, 60000); } });
-
Vielen Dank, ich habe das Prinzip -glaube ich- verstanden.
Dein Script klappt wunderbar. Vielleicht habe ich nochmal eine Frage, da ich zwei Bewegungsmelder kombinieren möchte, welche die gleichen Lampen steuern.
Aber erst einmal werde ich versuchen, es selber zu lösen.Ganz lieben Dank für deine festtagliche Hilfe
Fritz
-
Nur als Tipp:
setStateDelayed würde das gleiche in einer Zeile regeln.
Da jedes Mal der Timer von vorne anfängt (außer wenn clearrunning auf false gesetzt wird)
Gruß
-
Vielen Dank für den Hinweis. Leider kann ich dieses noch nicht einfach umsetzen, da mir Wissen und Erfahrung fehlen. Ich bin froh, dass es jetzt schon mal mit den beiden BWM klappt und hänge beim nächsten Problem.
Ich möchte auf eine erkannte Bewegung reagieren, aber nur wenn keiner zu Hause ist und bzw. vielmehr oder es zwischen 22:00 und 08:00 Uhr ist. Also wenn keiner da ist immer und in der genannten Zeit auch wenn einer da ist.
Die Anwesenheit frage ich mir dem Radar2-Adapter ab, was auch gut klappt. Aber wie drücke ich den genannten Zeitraum in javascript aus?on(... var anwesend = getState(radar2.0._allHere).val; if(!anwesend || Zeit zwischen 22 und 08 Uhr) ...
Kann mir da jemand helfen?
Mit schedule oder astro bin ich nicht weitergekommen.
Oder muss ich die Nachtzeit mit:var heute = new date(); var stunde = heute.getHours(); var nacht = if (stunde >= 22 || stunde <=8);
Bitte nicht über die grottige Syntax klagen. Ich übe noch und muss erst die Logik und Optionen verstehen. Und dann leider ein wenig mit Trial and Error.
Viele Grüße
Fritz -
@fritz74 sagte:
wie drücke ich den genannten Zeitraum in javascript aus?
Dafür gibt es die Funktion compareTime(startTime, endTime, between).
-
Dankeschön, so etwas hatte ich gemeint. Werde ich morgen mal testen.