Best Practice: Umsetzung von Master / Master bzw. beidseitiger Werte-Synchronisation zwischen externen Geräten und NeuroomNet [Dashboards]
Beschreibung Szenario
Vorbemerkung: Dieses Kapitel / Best Practice betrifft in erster Linie die Steuerung von externen Geräten mit NeuroomNet Dashboards, aber ist per se nicht auf Dashboards beschränkt.
Wenn NeuroomNet in einer NeuroomNet-Installation andere Geräte fernsteuert, dann erfolgt dies meistens so, dass nur NeuroomNet diese anderen Geräte steuert und die Geräte nicht noch von anderer Seite gesteuert werden (zumindest bzgl. der auch von NeuroomNet gesteuerten Funktionalität dieser Geräte). Hier liegt dann ein sog. Master / Slave Setup vor.
Anmerkung: Die aus der Informatik der 1980'er bis 2000'er Jahre sehr bekannten Begrifflichkeiten "Master / Slave" (und das daran angelehnte "Master / Master") wurden in diesem Kapitel gewählt in Ermangelung alternativer prägnanter und passender Begrifflichkeiten. Es ist hiermit nur die technische Bedeutung gemeint, ähnlich wie bei "Client / Server", "Primary / Replica" oder "Server". Es ist von den Autoren kein Zusammenhang, Konnotation oder Denotation zu den Begriffen aus anderen Kontexten (wie Sklaverei in der Geschichte der Menschheit) intendiert.
Es gibt aber auch Fälle - und um diese geht es bei diesem Best Practice -, wo sowohl NeuroomNet, als auch eine andere Instanz dieselben Werte desselben externen Geräts steuern. Hier muss dann NeuroomNet
- sowohl Werteänderungen, die von NeuroomNet ausgehen, an das externe Gerät melden,
- als auch vom externen Gerät eingehende Werteänderungen bei sich (insbesondere im Dashboard) aktualisieren.
Diese Fälle bezeichnen wir als beidseitige Synchronisation von Werteänderungen oder synonym als Master / Master Setups.
Beispiel:
In einem Hörsaal ist im Podium ein Tablet verbaut, welches ein NrN-Dashboard anzeigt. Auf dem Dashboard lässt sich eine Lautstärke in einem Audio DSPs steuern über einen Slider und ein Mute ein- und aus-togglen über einen Button:
Hierzu gibt es 2 Variablen in NeuroomNet, deren Werte durch den o.g. Slider respektive Button ändern lassen:
- AudioDSP_Lautstaerke1: Integer
- AudioDSP_Mute1: Boolean
Angenommen, diese Lautstärke und / oder Mute lässt sich noch direkt im AudioDSP / dessen Software steuern, dann liegt hier eine solche benötigte beidseitige Wertesynchronisierung oder Master / Master Setup vor.
Falscher Lösungsweg (Don't)
Folgender Lösungsansatz ist nur zur Erklärung gedacht und ist KEINE gute Lösung für das Problem "beidseitige Wertesynchronisierung bzw. Master / Master":
Man erstellt für die beiden Variablen "Value changed" Auslöser in den Skript Blöcken, so dass, wenn sich die Variablen ändern, der jeweils neue Wert an das Audio DSP geschickt wird:
An sich funktioniert dies sehr gut im Master / Slave Setup und ist dort auch relativ elegant, da es pro Variable nur eine zentrale Stelle gibt, die dafür sorgt, dass neue Werte an die Hardware geschickt werden.
Bei einem Master / Master Setup muss hier dann noch zusätzlich ein Event-Handler hinzugefügt werden für eingehende Werte-Änderungen vom Audio-DSP:
Dies kann dann aber zu Problemen wie "Flattereffekten" und insgesamt schlechter Performanz kommen, weil eingehende neue Werte wieder eine Variablen-Änderung hervorrufen, so dass die neuen Werte (an sich ja die gleichen Werte, die gerade reingekommen waren), wieder rausgeschickt werden. Bei binären Werten wie Mute ist dies vermutlich weniger kritisch, aber bei Zahlenbereichen, wo häufig in kurzer Zeit viele kleine Änderungen über das Netz geschickt werden (weil ein Mensch mehr oder weniger schnell einen Slider bewegt), kann dies zu "Flatter-Effekten" führen. Ein mögliches Stichwort wäre hier auch noch "Throttling", welches aber in diesem Zusammenhang eher ein Workaround wäre als wirkliche Lösung des Kernproblems.
Empfohlener Lösungsweg (Do)
Im Folgenden der vorgeschlagene Lösungsweg zur beidseitigen Synchronisation einer Variable X am vorhergehenden Beispiel:
Der entscheidende Punkt hierbei ist, dass man NICHT in den Skript-Blöcken einen "Value changed" Auslöser für die Variable X hat, der bei Werteänderungen von X greift und diese dann an das externe System schickt.
Stattdessen führt man für jede betroffene Variable ein Custom Event inkl. entsprechender Aktion ein, welches die aktuellen Variablen-Werte an das externe System schickt:
(ggf. lassen sich diese auch bündeln)
Diese Custom-Action konfiguriert man dann auch im Dashboard bei den entsprechenden Controls (z. B., wie hier bei einem Slider beim Unter-Control Knob als onChange-Event):
(und ggf. noch in den Script-Blöcken, falls dort noch über sonstige Script-Logik sich Variablenwerte ändern und an das externe Gerät geschickt werden soll).
Dadurch wird diese Custom-Action und damit die Heraussendung von Variablenwerten an das externe Gerät nur genau dann ausgeführt, wenn händisch Werte an den Controls im Dashboard geändert werden (nur dann werden die Custom Actions ausgelöst und nicht, wenn sich die Variablenwerte ändern und die Controls automatisch die neuen Werte anzeigen).
Empfohlener Lösungsweg (Do) - Kurzfassung
- Keine Variable Changed Trigger in den Script-Blöcken für Variablen, welche Werte in externen Geräten repräsentieren und welche dann geänderte Werte an die externen Geräte schicken
- Stattdessen Custom Actions definieren, welche alleine dafür zuständig sind, neue Variablen-Werte an externe Geräte zu schicken
- Die Custom Actions entsprechend konfigurieren im Dashboard und ggf. an nötigen Stellen in den Script-Blöcken