Dispatch bringt logische Geräte durcheinander

Begonnen von thmarx, 14 Dezember 2014, 15:54:21

Vorheriges Thema - Nächstes Thema

thmarx

Hallo,
vermutlich gehört meine Frage eher zu den Entwicklern. Da ich dort aber (noch) nicht schreiben darf versuche ich es mal hier (schließlich bin ich Anfänger).

Ich habe den thread zum Anlass genommen, mich mal ein bisschen in die Innereien einzuarbeiten. Charlie71 hat hier gute Arbeit geleistet, um über libnodave auf Siemens SPS zuzugreifen. Er benutzt dabei eine Aufteilung in physikalische und logische Geräte. Ich möchte das Modul für mehrere physikalische Module erweitern und bin dabei auf ein Problem gestossen, für das ich keinen Lösungsansatz finde:
Die logischen Module werden bei ihrer sub X_Define per AssignIoPort mit dem physikalischen Modul verbunden. Das klappt soweit, in den IODev-Attributen der logischen steht dann das korrekte physikalische Modul. In definierten Intervallen liest das physik. Modul "seine" SPS über libnodave aus und ruft dann Dispatch auf. In den ersten Zyklen kappt das auch ganz gut, die logischen Module werden richtig aufgerufen und können ihre Daten abholen. Nach so ca. 10-20 solcher korrekter Aufrufe passiert es dann aber, dass Dispatch  vom physik. Modul 1 die logischen Module, welche eigentlich zum physik. Modul 2 gehören, aufruft. Das ganze lässt sich reproduzieren, wenn bei beiden physik. Modulen das gleiche Intervall definiert wird. Logisches und physikalisches Modul finden dann auch nicht mehr zusammen. Benutze ich verschiedene Intervalle, tritt der Fehler sporadisch auf. Aber auch in diesem Fall kann man an den Internals der log. Module erkennen, dass immer wieder Nachrichten, die eigentlich zu einem anderen log. Modul gehören, eingeschleust werden. Wahrscheinlich immer dann, wenn die entsprechenden Abfragen zeitlich nahe beieinander liegen.
Ich hoffe, ich konnte mein Problem erstmal verständlich machen und hoffe jetzt auf Tipps zur Erklärung / Lösung.

Danke fürs lesen.
Thomas

rudolfkoenig

Dispatch hat weder mit IODev zu tun, noch mit den _Instanzen_ der logischen Module, d.h. es kann gar nicht eine falsche Instanz aussuchen.

Dispatch berechnet (mehr oder weniger aufwendig bzw. obskur) eine Liste  der Empfaenger _module_, und prueft via Match welches die Nachricht entgegennehmen will. Wenn eins gefunden, dann wird die ParseFn Funktion dieses (logischen) Moduls aufgerufen, die wiederum die passende Modul-Instanz (d.h. das per define definierte Geraet) findet, und Readings bzw. Events generiert.
-> Dispatch ist hoechsten fuer die Zuordnung des falschen Moduls zu verurteilen, aber sicher nicht fuer die falsche Instanz eines Moduls.

IODev ist nur beim Schreiben des Moduls relevant (bis auf die komische Ausnahme CUL_WS).
Falls ich etwas missverstanden habe, dann bitte mit dem konkreten Beispiel das Problem nochmal schildern.

thmarx

Hallo Rudolf,
schonmal Danke für Deine Unterstützung.
Wenn ich Dich richtig verstanden habe, muss die ParseFn des logischen Moduls (oder der Modul-Instanz?) feststellen können, von welcher pysikalischen Instanz die Daten kommen. Aber wie?

Mein konkretes Problem abstrahiert:
PM1
LM1
PM2
LM2

PM (physikalisches Modul) pollt die Daten und packt sie in einen Puffer (Puffer1 und Puffer2). LM (logisches Modul) soll die Daten aus dem Puffer interpretieren. PM ruft Dispatch auf, Dispatch ruft ParseFn von LM. Wie erkennt ParseFn ob Puffer1 oder 2 richtig ist? Zur Zeit wird im $Hash ein Ptr auf den Puffer gespeichert. Bei LM1 kommt aber manchmal der Ptr von Puffer1, manchmal der von Puffer2 an...

Ich hoffe, ich konnte mich verständlich ausdrücken.
Thomas

rudolfkoenig

Die Parse-Funktion kriegt als Uebergabeparameter den Hash der IO-Instanz.

Eure Vorgehensweise mit zwei Puffer ist ungewoehnlich, und da FHEM kein Interrupt bzw. Multithreading kennt, mAn unnoetig.

Das physikalische Modul liest ueblicherweise die Daten ein, bis ein Datensatz komplett ist, prueft checksum/etc, und verteilt die Nutzdaten per Dispatch. Man koennte auch die ID des fertigen Puffers verteilen, aber sobald das logische Modul direkt auf das Physikalische durchgreift, funktioniert FHEM2FHEM/RAW nicht mehr.

thmarx

ZitatDas physikalische Modul liest ueblicherweise die Daten ein, bis ein Datensatz komplett ist, prueft checksum/etc, und verteilt die Nutzdaten per Dispatch
OK, das habe ich soweit verstanden und scheint mir auch so umgesetzt. Das Einlesen, verifizieren usw. erledigt in unserem Fall eine spezielle library (linodave). Die hält auch die Verbindung offen, bei mehreren Geräten werden auch davon mehrere Instanzen angelegt. (Der Aufbau der Verbindung dauert etwas, ein ständiges öffnen und schließen wäre deshalb nicht so schön.)

Zitataber sobald das logische Modul direkt auf das Physikalische durchgreift, funktioniert FHEM2FHEM/RAW nicht mehr
Wäre schon gut, wenn das ginge. Aber ich brauche wohl noch einen Schubs in die richtige Richtung (Stichworte reichen vielleicht).
Mir ist halt noch nicht klar, wie Dispatch und/oder ParseFn die Zugehörigkeit physikalisches<->logisches Modul auflösen.
Danke für Deine Mühe
Thomas

rudolfkoenig

ParseFn sollte gar nicht aufs IODev zugreifen, sondern alle Daten per Parameter bekommen. Notfalls zusaetzlich ein ID des IODevs, wenn das zur Identifikation der Geraete notwendig ist.

thmarx

Guten Abend,
ich glaube, ich bin einen Schritt weiter.
Ich habe jetzt ein "paar" debug-Ausgaben für die Konsole eingebaut, und das Problem stellt sich so dar:
Anfangs läuft alles wie vorgesehen, Dispatch ruft ParseFn auf. Nach einer Weile kehrt Dispatch / erstes physikalisches Modul zurück, ohne ParseFn aufzurufen. Für das zweite physik. Modul läuft alles wie vorher weiter. Irgendeine Idee wo ich weiter forschen kann?
Danke
Thomas

rudolfkoenig

Falls ParseFn nicht aufgerufen wurde, heisst dass, dass die Nachricht nicht zum Match-Regexp des logischen Moduls gepasst hat.
Das koennte man verifizieren, indem man in fhem.pl/Dispatch weitere Debug-Ausgaben einzubaut.

thmarx

Naja, am Match-Regexp lags auch nicht. Aber ich habe das "Problem" lokalisiert (glaube ich, zumindest läufts jetzt seit ner Stunde fehlerfrei):
CheckDuplikate hat zugeschlagen und quasi jede zweite Nachricht rausgeworfen, wenn sie identisch sind. Habe den Nachrichten daher den Namen des Absenders (physik. Modul) mitgegeben, damit wirds eindeutig und alle NAchrichten kommen korrekt bei den logischen Modulen an.

Danke für die Geduld und Unterstützung
Thomas