Senden von Binärdaten mit MQTT2_SERVER bei encoding=unicode

Begonnen von xenos1984, 08 September 2026, 22:14:50

Vorheriges Thema - Nächstes Thema

xenos1984

Da ich einige Readings und Datenquellen mit utf8 Encoding habe, habe ich einmal das (experimentelle) globale Attribut encoding=unicode ausprobiert. Im großen und ganzen tut es das, was ich mir erhofft habe: Ein- und Ausgaben (insbesondere Filelog und fhem.save) werden jetzt explizit als utf8-kodiert behandelt. Damit beschwert sich Perl auch nicht mehr über einen "wide character in print" bei jedem Sonderzeichen.

Allerdings habe ich auch einige über MQTT mittels MQTT2_SERVER angebundene Geräte, die Binärdaten senden bzw. bekommen möchten. Mit encoding=unicode werden nun aber auch alle über MQTT ein- und ausgehenden Daten als utf8 kodiert. Das ist natürlich sinnvoll für Textdaten (insbesondere JSON), zerschießt aber meine Binärdaten.

Nun gibt es bei MQTT2_SERVER das Attribut binaryTopicRegexp, mit dem man Topics definieren kann, die als Binärdaten behandelt werden - dachte ich, gemäß Commandref:

ZitatbinaryTopicRegexp <regular-expression>

this attribute is only relevant, if the global attribute "encoding unicode" is set.
In this case the MQTT payload is automatically assumed to be UTF-8, which may cause conversion-problems if the payload is binary. This conversion wont take place, if the topic matches the regular expression specified. Note: as is the case with other modules, ^ and $ is added to the regular expression.

Das stimmt auch, wenn man Daten empfängt:

487     if($unicodeEncoding) {
488       if(!$shash->{binaryTopicRegexp} ||
489          $tp !~ m/^$shash->{binaryTopicRegexp}$/) {
490         $val = Encode::decode('UTF-8', $val);
491       }
492     }

Allerdings nicht beim Senden:

680   if($unicodeEncoding) {
681     $ltopic = Encode::encode('UTF-8', $topic);
682     $lval   = Encode::encode('UTF-8', $val);
683   }

Würde etwas dagegen sprechen, die gleiche Abfrage auch beim Senden (publish) einzubauen, oder alternativ zwei verschiedene Attribute zu haben, die dann jeweils für eine Richtung gelten? (Ein Attribut fände ich ausreichend, da man ja für gewöhnlich das selbe Topic nicht bidirektional benutzt, also ergibt sich die Datenrichtung ja bereits aus dem Topic selbst. Und wenn gerade empfangene Daten wieder gesendet werden sollen, an andere Subscriber, will man sie ja im gleichen Format senden, in dem man sie empfangen hat. Aktuell werden empfangene Binärdaten als utf8 kodiert wieder gesendet und damit verändert.) Ich habe mal experimentell folgende Änderung eingebaut, die bei mir gut funktioniert, und so weit ich sehen kann keine Nebenwirkungen hat:

680   if($unicodeEncoding) {
681     if(!$shash->{binaryTopicRegexp} ||
682        $topic !~ m/^$shash->{binaryTopicRegexp}$/) {
683       $ltopic = Encode::encode('UTF-8', $topic);
684       $lval   = Encode::encode('UTF-8', $val);
685     }
686   }

In jedem Fall greift die Änderung nur, wenn das als experimentell eingeführte Attribute encoding=unicode gesetzt ist.

rudolfkoenig

Danke fuer den Hinweis, habs uebernommen und eingecheckt.

Welche Anwendung versendet Binaerdaten?


xenos1984

Danke!

Tatsächlich sendet keins meiner Geräte Binärdaten, aber ein paar davon möchte welche empfangen. Das sind ein paar chinesische Character/Matrix Displays, die ich über Arduino eingebunden habe. Die haben einen Zeichensatz von 256 Zeichen, wobei die ersten Zeichen frei programmierbar sind und eine "Bitmap" mit Rasterdaten (im Binärformat) erwarten, dann folgen ASCII-Zeichen, und in der oberen Hälfte 128-255 liegen u.a. japanische Schriftzeichen und andere Symbole. Insbesondere liegt auf 0xDF das ° Zeichen, und das hat sich nicht mit der utf8-kodierung vertragen, wenn ich das senden wollte. Die Daten (Ist- und Soll-Temperatur) schicke ich aus FHEM.