Message Sink - zeitlich Abfolge bei Auslösung

Ich habe eine Frage zu Message Sink und die zeitliche Abfolge bei Auslösung.

IP-Symcon 5.1, Ubuntu, 03.05.2019, c9a193b6b44

Beispiel:

Ich habe in einem Modul eine Liste mit Handsendern und der zugehörigen Aktion, was passieren soll.

Die Handsender sind mit RegisterMessage auch für Message Sink registriert.

Mein Message Sink sieht so aus:


public function MessageSink($TimeStamp, $SenderID, $Message, $Data)
    {
        // Send debug
        $this->SendDebug('MessageSink', 'Message from SenderID ' . $SenderID . ' with Message ' . $Message . "
 Data: " . print_r($Data, true), 0);

        switch ($Message) {
            case IPS_KERNELSTARTED:
                $this->KernelReady();
                break;
            case VM_UPDATE:
                // Remote controls
                $remoteControls = json_decode($this->ReadPropertyString('RemoteControls'), true);
                if (!empty($remoteControls)) {
                    if (array_search($SenderID, array_column($remoteControls, 'ID')) !== false) {
                        $this->DetermineRemoteControlButton($SenderID);
                    }
                }
                break;
        }
    }

Generell funktioniert das auch, was mich nur wundert, ist die zeitliche Abfolge und die Visualisierung im Webfront.

In meiner Methode DetermineRemoteControlButton wird anhand der Handsenderliste geprüft, welche Aktion ausgeführt werden soll.

Ist dies ermittelt wird eine weitere Methode ausgeführt, z.B.


$this->ToggleAbsenceMode(false, 'Test');

Rufe ich die Methode DetermineRemoteControlButton (z.B. im Skript Editor) direkt auf so passiert auch der Ablauf den ich geplant habe, Visualisierung im WebFront passt auch.

Wir die Methode per Message Sink aufgerufen, wird auch alles ausgeführt, aber die Visualisierung im WebFront z.B. mit $this->SetValue(‚Abwesend‘, true); Variable passiert erst am Ende mit zeitlicher Verzögerung auch dann erfolgt erst der SendDebug Eintrag.

Verstehe ich nicht ganz. Ich bin davon ausgegangen, dass die registrierte Variable auslöst, der SendDebug wird geschrieben und dann geguckt, welche Methode ausgeführt werden soll.

Dies scheint bei mir nicht der Fall zu sein.

Ideen?

Uli

push

Jemand von Symcon Team eine Idee?

Ich habe jetzt an die Variable ein Ereignis gehängt bei Variable aktualisieren eine Aktion auszuführen.

Das geht wesentlich schneller und ordentlicher als mit Message Sink.

Uli

Tut es auch. Aber die Änderung der Variable wird ans Ende der internen MessageQueue gelegt. (Nicht direkt hinter die aktuelle Nachricht, welche du verarbeitest)

Somit kann im WebFront gerne noch etwas anderes davor aktualisiert werden, und dann deine Änderung. Schau dir mal im WebFront das Debug an - dort siehst du in welcher Reihenfolge die Meldungen kommen.

paresy

Hi Michael,

danke für die Info, schaue ich mir nochmal an… Muss mich dann wohl entscheiden was wichtiger ist…

Uli

Du willst den Code-Teil den du im MessageSink hast wahrscheinlich irgendwo direkt einbauen. Die MessageSink ist eben vollkommen losgelöst vom Ablauf und ist Nebenläufig zu allem.

paresy

Hmmmm, so ganz habe ich das noch nicht verstanden…

Wenn im Message Sink erkannt wird, dass eine Variable aktualisiert wurde, in meinen Fall ein Handsender, verweise, bzw. rufe ich eine Methode auf. In dieser werden Variablen im Webfront zunächst gesetzt und anschließend noch weitere Methoden ausgeführt.

Was mit der Variable zeitlich passiert ist mir relativ egal.

Die Abarbeitung meiner Methoden ist mir wichtig.

Was ich nicht verstehe, dass die Abarbeitung der ersten Methode nicht in der Reihenfolge erfolgt, als wenn ich die Methode ausserhalb vom Message Sink aufrufe.

?

Uli

Gesendet von iPhone mit Tapatalk

Bau einfach ein paar $this->SendDebug ein und du siehst die Reihenfolge im Debug deiner Instanz.

Michael

Gucken ob ich das nachher noch zeitlich schaffe, sonst morgen.

Uli

Gesendet von iPhone mit Tapatalk

so hier ist das Ergebnis, was ich feststellen konnte, wenn es über MessageSink detektiert wird:

Debug1.JPG

D.h. die Abfolge der Methoden passt.

Folgendes konnte ich feststellen (in der Reihenflolge):

  1. Betätigen des Handsenders

  2. Die Methoden werden im Hintergrund ausgeführt.

  3. Wenn alle Methoden durchlaufen sind wird das gesammte Debug Log geschrieben.

  4. Erst dann wird das WebFront aktualisiert

Zumindestens ist das, was ich beobachten konnte.

Sorry, was ich aber immer noch nicht verstehe ist, warum die WebFront Aktualisierung so lange dauert, obwohl in der Methode das gesetzt wird.

Uli

Weil die Abarbeitung der MessageSink durch dein Skript (welches aktuell deine MessageSink Abfrage ausführt) blockiert wird. Erst wenn dein Skript fertig ist, können weitere Meldungen verarbeitet werden - dazu gehören auch die Variablen Updates.

paresy

Gut, dann ist das durch die Architektur / Prozess so.

Dann muss ich nur für mich überlegen, ob für diesen Einsatz nicht auf die „alten Ereignisse mit Aktionsausführung“ wieder zurückkehre oder mit dieser „Verzögerung“ leben kann.

Uli

Mach es anders. Nutze MessageSink und ruf per RunScriptText eine Public Funktion deiner Instanz zur Abarbeitung auf. Diese wird dann abgekoppelt von der MessageSink.

paresy

Probiere ich nachher aus. Danke für die Info.

Uli

Perfekt, so gefällt mir das :smiley:

Uli