NEWS
gelöst - Exclusiver Zugriff auf Funktion
-
Moin,
wieder mal eine typische Anfängerfrage ...
Ich habe mir ein script gebastelt, dass den Wert eines Sensors (miflora) nimmt und in einen ec-Wert umrechnet.
Da es mehrere Sensoren sind kommt es nun öfter vor, dass dabei die Daten "vermischt" werden, wenn 2 Sensoren zur fast gleichen Zeit Werte senden (da Bluetooth, kommen die Daten willkürlich vom Sensor und man kann es nicht steuern, wann Werte kommen sollen).
Ich habe mir dafür eine Hilfsvariable "Frei" eingebaut, die die Funktion nur starten soll, wenn diese auf true steht. Ist das der Fall setzt sie "Frei" auf false und übergibt den empfangenen Wert an eine Rechenfunktion. Diese setzt dann den umgerechneten Wert in einen Datenpunkt und setzt abschließend den "Frei"-Wert wieder auf true. Funktioniert bis hierhin prima, es sei denn, 2 Sensoren senden fast zeitgleich ihre Werte. Dann scheint mir die "Frei" Variante nichts zu bringen, da sich der 2. Wert trotzdem "vordrängeln" kann. Ergebnis ist dann, dass der von der Funktion angesprochene Datenpunkt die Werte vom 2. Sensor enthält.
Kann man das irgendwie verhindern, so dass immer nur ein Wert zur Zeit abgearbeitet wird? Wenn der zweite Wert dann in dem Moment nicht abgearbeitet werden kann wäre das nicht schlimm. Der Intervall ist klein genug, sodass der Wert des 2 Sensors dann einfach in der nächsten Runde berechnet wird, wenn die Rechnerfunktion eben wieder frei ist.
Weiß jemand Rat?Vielen Dank im Voraus!
var ecWertT = "javascript.0.variable.Statustext.ecwert.ecwertTemp"; var Frei = "true"; var Flora01 = "ble.1.xx:xx:xx:xx:xx:xx.fertility"; var Flora02 = "ble.1.xx:xx:xx:xx:xx:xx.fertility"; var Flora03 = "ble.1.xx:xx:xx:xx:xx:xx.fertility"; function ecWertRechner(ec) { var data = getState(ecWertT).val; if (data >= 0 && data <= 99) setState(ec, '0.0'); else if (data >= 100 && data <= 219) setState(ec, '0.1'); else if (data >= 220 && data <= 329) setState(ec, '0.2'); else if (data >= 320 && data <= 429) setState(ec, '0.3'); else if (data >= 430 && data <= 549) setState(ec, '0.4'); else if (data >= 550 && data <= 559) setState(ec, '0.5'); Frei = "true"; setState(ecWertT, ""); }; on({id: Flora01, change: "ne"}, function(wert) { if (Frei = "true") { Frei = "false"; setState(ecWertT, wert.state.val); ecWertRechner("javascript.0.variable.Statustext.ecwert.ecwert1")}; }); on({id: Flora02, change: "ne"}, function(wert) { if (Frei = "true") { Frei = "false"; setState(ecWertT, wert.state.val); ecWertRechner("javascript.0.variable.Statustext.ecwert.ecwert2")}; }); on({id: Flora03, change: "ne"}, function(wert) { if (Frei = "true") { Frei = "false"; setState(ecWertT, wert.state.val); ecWertRechner("javascript.0.variable.Statustext.ecwert.ecwert3")}; });
-
@Smartin
Die Vergleiche sind keine, sondern Zuweisungen. Außerdem sollte man für eine Variable (Frei) mit 2 Zuständen keine Strings zuweisen. Will man die Freigabe erst dann machen, wenn setState() beendet ist, muss man es in einer Callback-Funktion machen.var ecWertT = "javascript.0.variable.Statustext.ecwert.ecwertTemp"; var Frei = true; var Flora01 = "ble.1.xx:xx:xx:xx:xx:xx.fertility"; var Flora02 = "ble.1.xx:xx:xx:xx:xx:xx.fertility"; var Flora03 = "ble.1.xx:xx:xx:xx:xx:xx.fertility"; function ecWertRechner(ec, data) { if (data >= 0 && data <= 99) setState(ec, '0.0'); else if (data >= 100 && data <= 219) setState(ec, '0.1'); else if (data >= 220 && data <= 329) setState(ec, '0.2'); else if (data >= 320 && data <= 429) setState(ec, '0.3'); else if (data >= 430 && data <= 549) setState(ec, '0.4'); else if (data >= 550 && data <= 559) setState(ec, '0.5'); setState(ecWertT, 0, function() {Frei = true;}); // enthält eine Zahl, sonst wären die Vergleiche falsch }; on({id: Flora01, change: "ne"}, function(wert) { if (Frei == true) { Frei = false; setState(ecWertT, wert.state.val); ecWertRechner("javascript.0.variable.Statustext.ecwert.ecwert1", wert.state.val)}; }); on({id: Flora02, change: "ne"}, function(wert) { if (Frei == true) { Frei = false; setState(ecWertT, wert.state.val); ecWertRechner("javascript.0.variable.Statustext.ecwert.ecwert2", wert.state.val)}; }); on({id: Flora03, change: "ne"}, function(wert) { if (Frei == true) { Frei = false; setState(ecWertT, wert.state.val); ecWertRechner("javascript.0.variable.Statustext.ecwert.ecwert3", wert.state.val)}; });
Weshalb wird der Datenpunkt "javascript.0.variable.Statustext.ecwert.ecwertTemp" am Ende der Funktion zurück gesetzt ?
-
@paul53
Besser macht man die Funktion ohne x mal setState().function ecWertRechner(data) { let ecWert = '0.0'; if (data >= 100 && data <= 219) ecWert = '0.1'; else if (data >= 220 && data <= 329) ecWert = '0.2'); else if (data >= 320 && data <= 429) ecWert = '0.3'); else if (data >= 430 && data <= 549) ecWert = '0.4'); else if (data >= 550 && data <= 559) ecWert = '0.5'); return ecWert; } on(Flora01, function(dp) { if (Frei) { Frei = false; setState("javascript.0.variable.Statustext.ecwert.ecwert1", ecWertRechner(dp.state.val), function() { Frei = true; }); } }); // usw.
-
Wow, sehr interessant ...
Also erstmal vielen Dank für die Hilfe!
Warum ich einen String für "Frei" genommen habe weiß ich gerade ehrlich gesagt selber nicht. Macht ja gar keinen Sinn.
ecWertTemp setze ich zurück, weil ich dachte, dass der mir eventuell in die Parade grätscht, wenn er nicht leer ist vor dem nächsten abarbeiten. Ich habe ja vorab selber einiges getestet und das war ein Punkt davon. Ich habe ihn drin gelassen, weil er nicht störte, scheint aber gar nicht nötig zu sein.
Das man den setState mit function ausführen kann wusste ich gar nicht. Und ist natürlich ein wirklich eleganter Weg.
Hier macht das lernen ja echt Spaß -
@Smartin
Meiner Meinung nach kann man auf den Datenpunkt "javascript.0.variable.Statustext.ecwert.ecwertTemp" und die Variable Frei verzichten, wenn die Funktion ecWertRechner(data) nur umrechnet und die Datenpunkte außerhalb dieser Funktion gesetzt werden. -
Ich werde es gleich mal testen ohne den Datenpunkt bzw. die Variable.
Sie ist ja nur mein hilfloser Versuch gewesen, eine Art "Exklusivität" einzubauen
Noch viel lernen er muss ....
Ich muss aber sagen, dass es mir immer wieder Freude macht, zu sehen wie jemand mit Durchblick so etwas angeht. Daraus lerne ich dann, wie man es eben richtig macht. Für zukünftige Projekte. -
@paul53
Es funktioniert einwandfrei ohne Datenpunkt und "Frei" Variable.
Ein schönes kurzes Script ist es nun geworden, was es auch gleich um einiges übersichtlicher macht.
Vielen Dank!Hier nun noch für alle späteren Leser wie es jetzt aussieht:
var Flora01 = "ble.1.xx:xx:xx:xx:xx:xx.fertility"; var Flora02 = "ble.1.xx:xx:xx:xx:xx:xx.fertility"; var Flora03 = "ble.1.xx:xx:xx:xx:xx:xx.fertility"; function ecWertRechner(data) { let ecWert = '0.0'; if (data >= 100 && data <= 219) ecWert = '0.1'; else if (data >= 220 && data <= 329) ecWert = '0.2'; else if (data >= 320 && data <= 429) ecWert = '0.3'; else if (data >= 430 && data <= 549) ecWert = '0.4'; else if (data >= 550 && data <= 559) ecWert = '0.5'; return ecWert; } on(Flora01, function(dp) {setState("javascript.0.variable.Statustext.ecwert.ecwert1", ecWertRechner(dp.state.val))}); on(Flora02, function(dp) {setState("javascript.0.variable.Statustext.ecwert.ecwert2", ecWertRechner(dp.state.val))}); on(Flora03, function(dp) {setState("javascript.0.variable.Statustext.ecwert.ecwert3", ecWertRechner(dp.state.val))});
-
@Smartin
Andere Variante der Funktion ecWertRechner(data):function ecWertRechner(data) { if (data <= 99) return '0.0'; if (data <= 219) return '0.1'; if (data <= 329) return '0.2'; if (data <= 429) return '0.3'; if (data <= 549) return '0.4'; return '0.5'; }
-
Auch das funktioniert einwandfrei und ist nochmal kürzer