Signale für PHP Module um besser auf Antwort zu warten

Hallo,

ich habe ein Splitter Modul gebaut, das einen Serial Port als Parent hat. Jetzt möchte ich eine Nachricht an den Parent schicken und warten, ob ein ACK zurückkommt und dann erst den nächsten Befehl senden. Dazu überschreibe ich ReceiveData und schreibe die Daten in einen Buffer. Jetzt könnte ich nach dem Senden immer manuell die erste Nachricht rausnehmen und schauen ob es die Antwort ACK ist. Aber es kommen auch Statusnachrichten rein, welche an die Devices automatisch weitergeleitet werden sollen. Und da bin ich jetzt überfragt. Sende ich einfach alle Nachrichten an alle Childs und Filter das dann bei den Childs entsprechend raus? Oder sende ich nur die entsprechenden Nachrichten an die Childs die sie auch benötigen? Aber wie fange ich dann die Nachrichten ab, welche ich nur um Splitter brauche.

Ich möchte also beim Senden von Nachrichten auf die Antwort warten und trotzdem die Nachrichten die reinkommen die für die Devices/Childs relevant sind automatisch weiterleiten.

Das Modul mit Splitter und mehreren Devices soll analog zum Z-Wave Modul funktionieren mit Rollos und Schaltsteckdosenaktoren usw. Das Splitter Modul soll den Initialisierungsprozess mit dem Stick machen (Sendet Nachrichten zum Stick und schaut ob die richtige Antwort zurück kommt)

Die einzelnen Devices sollen auch Befehle senden können und die Antwort abwarten und auswerten (z.b. Rollo1 Position 15 mit Antwort OK (HEX: 81 00 00 …))

Zusätzlich müssen aber die Status Nachrichten automatisch ausgewertet werden (z.B. Rollo2 meldet das es in Pos 100 gefahren wurde)

Ich hoffe ich konnte das Problem irgendwie beschreiben.

Danke

Gruß Basti

// EDIT: Die Antwort ist immer die selbe Nachricht, wie ich sie geschickt habe nur mit 81 am Anfang:


HEX: 07.05.2017 02:12:06.00 |             TRANSMIT | 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
HEX: 07.05.2017 02:12:06.00 |             RECEIVED | 81 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 

Nun wird es kompliziert :wink:
Ich beschreibe Mal meinen Weg, welchen ich in den meisten Modulen gegangen bin, muss aber nicht der Beste sein.
Alles was von ForwardData im Splitter reinkommt lege ich in eine SendQueue, bevor ich es an den Parent versende, ab. Das ist ein Array welches mit serialize in einem Buffer landet.
Anschließend wird gewartet bis die Antwort in dem Array liegt.
ReceiveData nimmt die empfangenen Daten, prüft ob es eine Anfrage in der Queue gibt, aktualisiert diese, und wenn es dort keine Anfrage gibt, sende ich es mit SendDataToChildren weiter.
Somit habe ich im Device, wenn ich SendDataToParent aufrufe gleich die Antwort.
Und wenn ein Event eintrifft, kommt die über ReceiveData im Device rein.
Damit nur die korrekten Devices diese Events empfangen, wird im ApplyChanges der ReceiveFilter auf die Geräte-ID gesetzt.
Michael

Zur Zeit geht es nur mit der „Brechstange“ wie Nall-Chan es beschreibt. Schön wäre, wenn man in Zukunft auf „Signale“ warten könnte, die der Splitter dann in ReceiveData an den wartenden Befehl in ForwardData schicken könnte.

Ich habe das mal als Wunsch notiert :slight_smile:

paresy

Als Signal habe ich auch schon Mal einen Buffer genutzt, blöd ist halt das warten und dann teilweise noch Semaphore nutzen damit auf den Buffer nicht gleichzeitig zugegriffen wird.
Wenn du also so etwas wie die TCriticalSection und TNotifyEvent unter Delphi in einem bereitstellst, wäre das schon cool.
Michael

Vielen Dank für eure Antworten, kein leichtes Thema für mich als Anfänger :slight_smile:

OK also alle Nachrichten an alle Childs und dann filtern. Wie siehts aus mit den Nachrichten, die ich nur im Splitter brauche (Initialisierungsprozess)? Sollte ich diese mit einem If abfangen und nicht zu den Childs weiterleiten? Wären aber au nur ca 5 Nachrichten bei initialisierung.

Um eine SendQueue werde ich sowieso nicht kommen, da der Stick irgendwann abstürzt, wenn zuviele Nachrichten in zu kurzer Zeit kommen. @Michael: Du schreibst: „Anschließend wird gewartet bis die Antwort in dem Array liegt.“ Heißt das, dass du die Antworten auch in einem Array ablegst? Ich kann ja nicht davon ausgehen, dass die nächste Nachricht auch die Antwort ist, sondern es könnten ja zwischendurch noch andere Nachrichten reinkommen. Dazu müsste ich irgendwie prüfen, ob eine bestimmte Antwort in einer bestimmten Zeit eingegangen ist. Da hängts momentan noch. Ich hab mir schon einige Module angeschaut, aber habe es scheinbar noch nicht richtig verstanden.

Gruß Basti

Ich werfe die Daten (egal ob die nun ein Objekt , String oder sonstwas sind) im Splitter in ein Array, was die Queue darstellt.
Wenn die Wartezeit auf die Antwort abgelaufen ist, wird es wieder entfernt. Das ist das Timeout.
Beim Empfang wird halt geprüft ob eine Anfrage in der Queue liegt und die Daten ergänzen ich um die Antwort.
Klar kannst du beim Empfang nach den Daten filtern, musst du sogar.
Entweder die Queue aktualisieren oder als Event mit SendDataToChildren weiter schieben oder direkt im Splitter verarbeiten.
Michael

Danke, hab ich endlich soweit verstanden. Leider ist die Antwort doch nicht immer so wie gedacht, muss ich noch schauen