NEWS
Auf mehrere Ereignisse subscriben, aber Block nicht mehrmals zeitgleich ausführen
-
Ich stehe gerade auf dem Schlauch, brauche mal bitte nen Tipp.
Ich habe eine Beleuchtung "Bar" und "Vitrine" über eine Funksteckdose.
Diese sollen in Abhängigkeit der Hue Lampen "Esstisch" und "Wohnwand" geschalten werden, aber erst ab einer gewissen Helligkeit (40 bzw. 80 Prozent).
!
var timeout; ! on({id: new RegExp('hue\\.0\\.Hue_Bridge\\.Esstisch\\.level' + "|" + 'hue\\.0\\.Hue_Bridge\\.Wohnwand\\.level'), change: "any"}, function (obj) { if (getState("hue.0.Hue_Bridge.Esstisch.level").val >= 40 || getState("hue.0.Hue_Bridge.Wohnwand.level").val >= 40) { setState("hue.1.HA-Bridge.Bar.on"/*HA-Bridge.Bar.on*/, true); } else { setState("hue.1.HA-Bridge.Bar.on"/*HA-Bridge.Bar.on*/, false); } timeout = setTimeout(function () { if (getState("hue.0.Hue_Bridge.Esstisch.level").val >= 40 || getState("hue.0.Hue_Bridge.Wohnwand.level").val >= 80) { setState("hue.1.HA-Bridge.Vitrine.on"/*HA-Bridge.Vitrine.on*/, true); } else { setState("hue.1.HA-Bridge.Vitrine.on"/*HA-Bridge.Vitrine.on*/, false); } }, 500); }); !
Das Skript funktioniert und tut soweit, was ich will.
Nun habe ich das Problem, wenn in einer Hue Szene (Hue Dimmschalter) sowohl "Esstisch" als auch "Wohnwand" gleichzeitig verändert werden, wird der Block auch 2 mal gleichzeitig ausgeführt.
Dadurch wird jedes auszuführende setState 2-mal zeitgleich ausgeführt und gefunkt, was zur Folge hat, dass die Steckdosen teilweise gar nicht schalten.
Wie kann ich zwar auf Esstisch und Wohnwand subscriben, aber wenn beides zeitgleich aktualisiert wird, den Block nur einmal ausführen?
Mit einer Hilfsvariable hatte es nicht geklappt, diese wird wohl nicht schnell genug gesetzt, da wirklich zeitgleich.
Damit wird es auch nichts bringen, einen Status von "Bar" oder "Vitrine" mit getState vorher abzufragen, das wäre noch langsamer…
-
In nodejs machst du das üblicherweise mit nem Timeouts. Man sagt in welchen Zeitraum man doppelte Trigger ignorieren will(1s oder länger) und kann dann:
Option 1 die Ausführung von dem was getan werden soll verzögern. Jede neue Aktion startet die Verzögerung neu.
Option 2: sofort ausführen (nur wen Variable nicht gesetzt ist) Und eine Variable setzen. Dann mit einer Verzögerung die Variable zurücksetzen …
Hoffe war jetzt nicht zu kryptisch [emoji6]
Ps: wirklich parallel wird nichts ausgeführt. Kommt alles nacheinander.
-
Ich habe jetzt eine andere Ursache gefunden, es funktioniert doch mit der ursprünglichen Methode Hilfsvariable.
! ````
var Threshold_Bar_Esstisch, is_running, Threshold_Bar_Wohnwand, Threshold_Vitrine_Esstisch, Threshold_Vitrine_Wohnwand, timeout1, Esstisch, Wohnwand, timeout2;
! Threshold_Bar_Esstisch = 40;
Threshold_Bar_Wohnwand = 40;
Threshold_Vitrine_Esstisch = 40;
Threshold_Vitrine_Wohnwand = 80;
! is_running = false;
on({id: new RegExp('hue\.0\.Hue_Bridge\.Esstisch\.level' + "|" + 'hue\.0\.Hue_Bridge\.Wohnwand\.level'), change: "any"}, function (obj) {
if (is_running != true) {
is_running = true;
timeout1 = setTimeout(function () {
Esstisch = getState("hue.0.Hue_Bridge.Esstisch.level").val;
Wohnwand = getState("hue.0.Hue_Bridge.Wohnwand.level").val;
if (Esstisch >= Threshold_Bar_Esstisch || Wohnwand >= Threshold_Bar_Wohnwand) {
setState("hue.1.HA-Bridge.Bar.on"/HA-Bridge.Bar.on/, true);
} else {
setState("hue.1.HA-Bridge.Bar.on"/HA-Bridge.Bar.on/, false);
}
timeout2 = setTimeout(function () {
if (Esstisch >= Threshold_Vitrine_Esstisch || Wohnwand >= Threshold_Vitrine_Wohnwand) {
setState("hue.1.HA-Bridge.Vitrine.on"/HA-Bridge.Vitrine.on/, true);
} else {
setState("hue.1.HA-Bridge.Vitrine.on"/HA-Bridge.Vitrine.on/, false);
}
is_running = false;
}, 500);
}, 500);
}
});Das Problem war, dass bei gleichzeitigem Schalten von Esstisch und Wohnwand nicht sofort die Werte von "hue.0.Hue_Bridge.Esstisch.level" und "hue.0.Hue_Bridge.Wohnwand.level" gesetzt sind wenn die Subscription zuschlägt, da der Adapter diese seriell abfragt. Daher habe ich "timeout1" von 500 ms hinzugefügt. Im Zusammenspiel mit "is_running", welches sofort auf "true" gesetzt wird, wird der Block jetzt nur noch exklusiv aber mit korrekten Werten ausgeführt.