Probleme mit SetReceiveDataFilter

Hallo zusammen,

ich bin zu blöd, den ReceiveDataFilter zu setzen, kann mir jemand helfen?


public function ApplyChanges() {
   $duoFernCode = $this->ReadPropertyString("duoFernCode");
   if (!preg_match(DUOFERN_REGEX_DUOFERN_CODE, $duoFernCode)) {
      $duoFernCode = "XXXXXX";
   }

   $this->SetReceiveDataFilter("(.*" . $duoFernCode . ".*)");
   // $this->SetReceiveDataFilter("(.*" . $this->ConvertMsgToSend($duoFernCode) . ".*)");
}

Die Nachrichten haben die Form: „0DFF0F400000000000000000000000000000FFFFFF01“ und werden mit der Funktion für den Datenaustausch konvertiert:


    private function ConvertMsgToSend($hex)
    {
        $str = "";
        for ($i = 0; $i < strlen($hex) - 1; $i += 2) {
            $str .= chr(hexdec($hex [$i] . $hex [$i + 1]));
        }

        return $str;
    }

Es kommt nichts an und ich weiß nicht wie ich testen soll, ob die regex passt.

Danke!

Gruß Basti

Hier kannst du es online ausprobieren:
Online regex tester and debugger: PHP, PCRE, Python, Golang and JavaScript
Dazu im Splitter das ganze JSON was mit SendDataToChildren weitergeleitet wird, mit SendDebug ausgeben.
Das kannst du dann aus dem Debug-Reiter kopieren.
Ebenso kannst du den FilterString im Device ja auch mit SendDebug ausgeben und dann auf regex101 prüfen ob er funktioniert.
Michael

Danke, das hatte ich mit dem regex online tester versucht, allerdings habe ich mir nicht den JSONString ausgeben lassen und da ist der Fehler


{"DataID":"{244143D3-BABA-44D4-8740-B997B8F09E50}","Buffer":"\u000f\u00ff\u000f#	\u0000\u0002\u0003P2\rd%\u0000\u00ffB_\u008ao\u00f5\u0081\u0001"}

Wie mache ich das mit der UTF8 Kodierung?

Müsste ich dann meine Expression mit utf8 kodieren? Stehe gerade auf dem Schlauch


   $this->SetReceiveDataFilter("(.*" . utf8_encode($duoFernCode) . ".*)"); 

Danke!

Gruß Basti

Ich würde die Daten in Splitter schon zerlegen und dann anstatt Buffer eigene Datenpunkte per json übergeben.
Den Gerätecode z.b. als normalen ASCII String. (Ob es sinnvoll ist den Rest auch schon vorher aufzubereiten kann ich dir aufgrund meiner fehlenden Kenntnis vom Protokoll nicht sagen.)

Die Rohdaten welche du da hast, sind ja immer Bytes welche durch das JSON_encode so kodiert werden.
Michael

Hm, ich hab die Nachrichten so gelassen wie es der Hersteller auch macht. Beim Senden der Daten an den Splitter sende ich die Daten auch in dem Format. Dann müsste ich alles umbauen, sonst sind die Nachrichten vom Aufbau unterschiedlich. Ich wusste noch gar nicht, dass man da im JSON Objekt eigene Eigenschaften hinzufügen kann, muss ich vielleicht mal in der Doku schauen.

Danke

Basti

//EDIT: Ich weiß einfach noch zu wenig über den Aufbau der Nachrichten, als das ich das sinnvoll aufteilen könnte. Mehr als die Geräteadresse rausfiltern macht momentan noch keinen Sinn.

Ich nutze unterhalb vom Splitter nur eigene Formate, weil die Logik des Protokolle in jeder Instanz zu haben ist ja unnötig.

In deinen Fall brauchst du dann auch keinen Splitter, wenn der eh nichts mit den Daten macht.

Der Filter wird so auf jeden Fall ein schwierig.
Eine richtig gute Idee wie du jetzt deine Adresse in das Format für den Filter bekommst, habe ich nicht parat.
Eventuell ein Array mit Index Buffer und Wert dein Code (in binary).
Den Code mit utf8encode in den Index schreiben.
Und das Array dann mit json_encode in einen Json-String bringen.
Dann musst du aber noch am Anfang und Ende etwas abschneiden, damit es passt.
Wenn der Code immer am Anfang des Datenpaket steht, muss dann als Filter so etwas rauskommen:
,„Buffer“:"\u000f\u00ff\u000f# \u0000\u0002
Michael

Ich habe den Code jetzt einfach hinten dran gehangen :slight_smile:


{"DataID":"{244143D3-BABA-44D4-8740-B997B8F09E50}","Buffer":"\u000f\u00ff\u000f#\u000f\u0000\u0002\u0003P2$\u0000\u0013\u0000\u0000L)@o\u00f5\u0081\u0001","DuoFernCode":"4CXX09"}

Ich bin gerade als am überlegen wie ich es am besten mache, bin aber eigentlich zum Entschluss gekommen die Daten erstmal im Rohformat zu lassen, bis ich besser weiß wie die Daten genau aufgebaut sind. Anfangs war mein Plan: Ich lasse die Daten im Rohformat und es gibt für jedes Gerät nen eigenes Modul, was dann auch entsprechend andere Leute programmieren könnten, da ich vermutlich nie alle Geräte haben werde. Aber da das nun vermutlich auch generisch wird, kann ein neues Gerät natürlich auch alten Code gefährden.

Gruß Basti

P.S: Eine Projektidee für dich: Library mit fertigen Splitter, Configurator und Device mit interner Kommunikation, so dass man nur noch das Protokoll des Herstellers in den Splitter implementieren und ggf. Geräte anpassen muss :slight_smile:

//EDIT: Ich müsst mir dann mal Gedanken über nen Format für ne interne Kommunikation machen. Ich wollte jetzt noch nen bisschen Konfigurator bauen und dann muss ich anfangen die Devices zu implementieren und das Protokoll weiter mitzuschneiden, ich denke da kann mir auch der ein oder andere von den Rademacher Usern noch helfen.

Geht nicht, weil der Sync bei BiDi Kommunikation ja bei jedem Protokoll anders ist.
Aber ich baue gerade eine DemoModul mit Kommentaren, dies kann dann als Vorlage genutzt werden.
Michael

Ja Sync is halt so ne Sache bei mir, ich weiß zu wenig über das Protokoll und andere die es bisher versucht haben, haben das auch nicht so optimal implementiert. Aber bisher läufts stabil, mal sehen wies dann aussieht wenn richtig Traffic da ist.

Das mit dem Demomodul ist ne schöne Sache und wird sicherlich einigen helfen.

Gruß Basti

P.S.: Für Fehlermeldungen z.B. wenn der Parent inaktiv ist ist trigger_error das richtige?

Das kommt darauf an wo und wie du den Fehler erkenntlich machen willst.
Von throw Execption bin ich abgerückt, weil dann auch User-Scripte abgebrochen werden.
trigger_error + Return false für Public Instanz Funktionen ist ganz brauchbar.
Für RequestAction reicht auch echo um den Fehler im WF darzustellen.
Michael

Alles klar, so hatte ich’s auch vor, danke :slight_smile:

Morgen, ich habe auch ein kein kleines Problem mit der Funktion.
Ich möchte folgenden String filtern und scheitere an der korrekten Formatierung :confused:


\"serial\":\"12345678\"
$this->SetReceiveDataFilter('.*\"serial\":\"12345678\".*');

für jeden Tip dankbar!

Dazu müsste man jetzt dein Datenpaket kennen.
Gib das doch mit SendDebug (‚receive‘, $JSONstring,0); im ReceiveData aus.
Natürlich ohne vorher einen Filter gesetzt zu haben.
Da IPS ja Json nutzt, kann es sein, dass deine Nutzdaten auch noch mal maskiert sind und dann der Filter nicht greift.
Michael

der String ist im Datenpaket und kommt auch an.
Ich denke, dass bei Nutzung von „“ die Formatierung für den ReceiveDataFilter falsch ist

Deswegen sage ich ja, zeig Mal was wirklich reinkommt.
Komplett mit GUID usw…
Weil ja erstmal werden alle " im Datenaustausch maskiert wenn sie in den Nutzdaten liegen weil es JSON ist.
Dann musst du auch einige Zeichen maskieren im String des RegEx. Weil diese sonst auch falsch interpretiert werden.

Was ich da nutze, ist die RegEx Filterzeichen erst später anfügen und den Teil welcher geprüft werden soll mit preg_quote bearbeiten.

Also ‚.’. preg_quote(’„bla“"’). '.
Michael


23.10.2017 10:33:51 | SymconNEST | <DEVICE|RECEIVEDATA> {"DataID":"{405B59DE-CBB7-4D75-8C63-596DA613AA20}","mode":1403,"method":1208,"buffer":"[{\"id\":\"4e8a4450-61a2-11e7-9e43-0ad43679fe28\",\"serial\":\"14AA01AC2317046J\",\"alias\":\"myNestIQ\",\"model\":\"Nest Cam IQ\",\"where\":\"Lucky Luke\",\"ip\":\"10.0.1.61\",\"state\":0,\"audio\":0,\"share\":0,\"connect\":1508710685000,\"disconnect\":1508710666000,\"software\":\"4220011\",\"aware\":1}]","debug":0,"message":true}

Versuch mal:


$this->SetReceiveDataFilter('.*' . preg_quote('\"serial\":\"12345678\"') . '.*');

Michael

Hammer - jetzt funktioniert es. Besten Dank!

PS: ergibt folgenden Filter
23.10.2017 11:29:19 | SymconNEST | <DEVICE|APLLYCHANGES> .\„serial\“:\„14AA01AC2317046J\“.

Bitte :slight_smile:
Nutz für soetwas aber lieber SendDebug und nicht IPS_LogMessage.
Weil die Debugausgabe kann auch Hex Darstellung von Bytes und verschluckt auch keine Sonder- und Steuerzeichen.
Michael

das ist natürlich auch ein wertvoller Tip :slight_smile:
Der String könnte eigentlich auch ohne reg_quote gebaut werden.