ReceiveDataFilter auf dem ClientSocket - wie geht das

Moin,

derzeit fische ich einige LCN Busmeldungen wie Schwellwerte, Tastensperren, Modulinfos, etc. über eine RegVar am PCHK Client Socket ab, was meinen RasPi aber ganz schön in die Knie zwingt.

Abhilfe schafft dazwischen zwar der Cutter, jedoch brauche ich dann pro Modul und pro Kommando je einen Cutter - das sprengt die Grenze aus einer anderen Richtung erneut.

Paresy gab mir mal den vielversprechenden Hinweis, über ein Modul mit ReceiveDataFilter und entsprechenden RegEx diese Sachen zu holen - aber ich merke, es ist komplizierter als ich denken kann. Mir fehlt komplett der Ansatz.

Daher meine Frage:
Hat jemand ein Beispielmodul, wo mit ReceiveDataFilter die Meldungen eines Client Socket irgendwie ausgewertet werden ?

Danke,
Tom

Hast du denn schon mal angefangen? Empfängt dein Modul ggf. erstmal alle Daten? Wenn ja, hast du mal z.B. mit Online regex tester and debugger: PHP, PCRE, Python, Golang and JavaScript versucht einen passenden Filter auf deine Daten zu bauen?

paresy

Hi Paresa,

danke für deine Antwort. So weit bin ich noch gar nicht, regex wären auch nicht das Problem. Ich habe noch nie ein Modul gebastelt und stecke daher noch „in den Anfängen“.

Andererseits machen die implementierten Module „LCN ShutterMotor“ etc. sicherlich auch nichts anderes - daher hatte ich mir erhofft, diese Module abzukupfern und umzumodeln.

Leider erscheinen die aber nicht unter dem Ordner und die Quelltexte davon scheinen nicht offen rumzuliegen.

Viele Grüße,
Tom

Genau. Es gibt für LCN kein „Beispiel“ welches ich dir kopieren könnte. Im Prinzip musst du dir mal die Beispiele im SymconTest Repo ansehen (GitHub - symcon/SymconTest: Symcon modules for demonstration and testing) und insbesondere den Datenfluss anpassen. Dafür musst du die GUIDs dir ansehen, über die die LCN Module miteinander kommunizieren.

paresy

Ah, diese Testmodule sind in jedem Fall hilfreich, danke.

Aber eigentlich läuft die Aufgabe darauf hinaus, dass ich den Cutter neu entwerfe.

Mal ne Frage (Bambi-Blick an):
Könnte man den Cutter nicht dahingehend erweitern, dass

  1. einfache Suchmuster à la dos (wildcards) oder sogar reguläre Ausdrücke als Schnittzeichen gewählt werden können
  2. Es eine Option gibt, die auch die Schnittzeichen selbst als Übergabe erlauben ? (sinnvoll, falls mehrere Cutter ein gemeinsames Skript triggern)

naja, das „man“ heißt natürlich „du“…

Das soll aber nur eine Anregung sein. Ich fände das ungemein hilfreich, der Cutter ist schon ein wichtiges Tool, wenn man datenintensive Ströme auswerten will.

Hm, ich habe das Beispiel IOFilterTest eingebunden und die Instanz angelegt.Dazu den Socket gewählt und im ReceiveFilter einen String gesetzt - jetzt müssten doch eigentlich Meldungen mit „IOTest“ erscheinen, oder ?
Tut es aber leider nicht.

Was für ein String?
Es muss gültiges RegEx sein, welches IPS auf das ankommende Paket anwenden kann.
Also z.b. ‚.Blablup.
Wichtig: IPS filtert auf den im Datenfluss genutzten JSON-String.
Somit sind alle nicht darstellbare Zeichen escaped.
Hier ein sehr ekeliges Beispiel um auf ein DHCP-Paket einen Filter zu setzen.
Die Klimmzüge um dir Bytes der Mac in den Filter zu bekommen sind nicht ohne.

Michael

Ich meinte den ReceiveFilter in dem Beispiel von Paresy, der als String deklariert ist. Selbst wenn ich dort als Wert „.*“ eingebe, kommt nichts im Meldungsfenster, wo in dem Beispiel das „IPS_LogMessage“ steht.

https://github.com/symcon/SymconTest/blob/master/IOFilterTest/module.php

Oha, es geht ja doch - ich bin darauf reingefallen, dass die Zeile mit

IPS_LogMessage("IOTest", $this->GetBuffer("Test"));

ein mehrzeiliges Ergebnis zurückliefert.

Im Klartext: Der Filter lautet:

.*=M[0-9]{6}\.TX([0-9]{3}).*

jedoch bekomme ich im GetBuffer durchaus:

=M000022.TX063000000000
%M000022.T1200161
%M000022.T1300289

ich habe noch nicht verstanden, wie ich den Filter setze, damit ich wirklich nur die Zeilen bekomme mit dem TX

nächste Frage gleich danach: Kann ich auf den Inhalt zwischen den runden Klammern (bei mir oben also die 3 Nummern, also diese gtrennt benannten Teilbereiche im Suchmuster, wäre da oben ja „063“) bei der regex zugreifen ? Oder muss ich das im Code „nachfiltern“ ?

Probier mal Online regex tester and debugger ;), da kannst du die Regel und deine Inhalte testen und lernen :).

Der findet mit deiner Regeln nur die erste Zeile.

Du könntest ja auf verschiedene „.=M[0-9]{6}.TX063.“ filtern, dann hast du die Rückmeldung pro Modul.

Hallo Ralf,

danke für deine Hinweise. Der regex Tester ist ein jedem Fall ein guter Tip. Meinst du mit deinem Hinweis, dass ich die LCN Modulid im Suchmuster hardcode ? Dass wollte ich gerade vermeiden, sonst benötige ich wirklich für jede LCN-Modulid eine eigene Instanz - und dann kann ich gleich den fertigen Cutter nehmen.

Ich wollte erreichen, dass die Meldungen nach dem Muster M000???.TX??? im IPS-Modul landen, wobei das ? jetzt für jeweils eine Ziffer steht.

Das Problem ist, dass ich nicht weiß, wie ich explizit end exklusiv diese Meldungen aus dem ReceiveDataFilter rausfische. Ich habe ehrlich gesagt auch gar nicht verstanden, wieso Paresys Beispiel erst den Buffer füllt und dann wieder ausliest. Die für mich rätselhaften Zeilen in der ReceiveData Function:

$this->SetBuffer("Test", utf8_decode($data->Buffer));
//Print buffer
IPS_LogMessage("IOTest", $this->GetBuffer("Test"));

da wird wohl irgendwie der Urspung sein, dass ich die Meldungen gestaffelt bekomme.

Ist es der richtige Weg, mit diesem Buffer so zu arbeiten und das dann in der ReceiveData Function auseinanderzudröseln ? Wär ja programmtechnisch nicht so das Hexenwerk, aber ich weiß nicht, ob das so der korrekte Weg ist oder ob ich einen (weiteren) Denkfehler habe…

Gestaffelt = Zeilenumbrüche?
Dann kommt das Protokoll so rein.
Besser SendDebug nutzen, dort siehst du auch die Zeilenumbrüche.
SendDebug — IP-Symcon :: Automatisierungssoftware
Der Buffer ist transparent, kannst du ignorieren.
Aber das utf8decode ist wichtig.
Zum Filter:
RegEx kann auch ODER und Wildcards gehen ja auch.
Und ja, man erzeugt in IPS pro ‚Gerät‘ eine Instanz.
Also 5 Instanzen welche alle am IO hängen und unterschiedliche Filter haben. Warum nicht. Für jede Modulid also eine Instanz.

Michael

Ich glaube, wir können den Thread schließen. Ihr habt mir alle sehr geholfen - nur der Sinn des SetBuffer und Getbuffer in dem IOFilterTest erschließt sich mir nicht - es geht tatsächlich auch ohne.

Wenn das Modul steht, werde ich es hier posten.