FHEM und UNICODE, first aid

Begonnen von herrmannj, 08 Februar 2022, 19:28:02

Vorheriges Thema - Nächstes Thema

betateilchen

Ich zicke nicht, aber das MQTT Problem ist im Moment schwerwiegender als dieses Kodierungs-Gefrickel, das auf Dauer FHEM ohnehin mehr schaden als nützen wird, weil es die Akzeptanz bei den Anwendern durch solche Darstellungsprobleme vermutlich stark reduzieren wird.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

herrmannj

Quatsch, das Gegenteil ist der Fall. 600+ Treffer allein nur für "Umlaute". "Darstellungsprobleme" etc kommen noch dazu...

justme1968

@betateilchen: da das ziel ist die ein- und ausgabe korrekt und richtig zu machen, im gegensatz zu jetzt, wo sie nur meist richtig ist (und das auch nur wegen diverser workarounds) ist diese aussage von dir falsch. 

das es wärend so einer umstellung probleme gibt ist normal. erst recht wenn in der aktuellen kette diverse workarounds an (implizite und zum teil falsche) annahmen aufeinander aufbauen und voneinander abhängen. wenn man dann an einer stelle das richtige macht fällt es einem erst mal auf die füße. das wird aber besser und gut wenn man durchhält.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

betateilchen

#63
Das mag ja alles sein. Und ich habe mit Softwareentwicklung nicht erst seit gestern zu tun, sondern inzwischen schon mehr als 40 Jahre.
Aber eine so schlecht koordinierte Umstellung mit solch weitreichenden Auswirkungen wie jetzt hier in FHEM habe ich selten erlebt.

Aktuell habe ich ein "Henne-Ei-Problem":
Das globale Attribut "encoding" wird im Rahmen des FHEM Starts aus der Datenbank gelesen und gesetzt.
Das heißt, ich muss die Datenbank bereits öffnen, die Konfiguration einlesen und mit deren Verarbeitung beginnen, bevor ich überhaupt weiß, welche Codierung FHEM gerne hätte. Die konfigurierte Codierung wirkt sich aber auf die Art und Weise aus, wie ich die Verbindung zur Datenbank herstelle.

Zitat von: betateilchen am 20 Februar 2022, 16:33:00
aber das MQTT Problem ist im Moment schwerwiegender als dieses Kodierungs-Gefrickel,

Das MQTT Problem hing auch mit der Codierungsproblematik zusammen. Wobei mir noch unklar ist, wieso die Codierung zu einem SSL Problem mit anschließendem Protokollfehler führte.
Nachdem ich das ganze Codierungsgedöns komplett zurückgedreht hatte, funktioniert auch MQTT wieder. (ja, ich habe die aktuellen Modulversionen im Einsatz)
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

rudolfkoenig

ZitatWarum wird das jetzt alles so viel komplizierter gemacht und absichtlich potenzelle Fehler- und Problemstellen geschaffen?
Weil die "Welt" um FHEM-herum es leider anders macht, d.h. etliche Perl-Bibliotheken Unicode-Kodierte Daten voraussetzen, bzw. solche liefern. Und dann gibt es noch die Leute, die Smileys zaehlen wollen.

ZitatAber eine so schlecht koordinierte Umstellung mit solch weitreichenden Auswirkungen wie jetzt hier in FHEM habe ich selten erlebt.
Ho, langsam mit den Pferden!
encoding ist EXPERIMENTELL, und jeder der ihn setzt, hilft beim fertigstellen.

ZitatDas heißt, ich muss die Datenbank bereits öffnen, die Konfiguration einlesen und mit deren Verarbeitung beginnen, bevor ich überhaupt weiß, welche Codierung FHEM gerne hätte. Die konfigurierte Codierung wirkt sich aber auf die Art und Weise aus, wie ich die Verbindung zur Datenbank herstelle.
Aus diesem Grund liest FHEM die fhem.cfg zweimal durch: beim ersten mal werden nur die global Attribute betrachtet,  und danach nochmal alles, um die Daten richtig zu interpretieren.

betateilchen

Zitat von: rudolfkoenig am 20 Februar 2022, 17:24:18
encoding ist EXPERIMENTELL, und jeder der ihn setzt, hilft beim fertigstellen.

ein EXPERIMENTELLES Attribut, das man nicht mehr löschen darf... echt super.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

rudolfkoenig

@hermannj:
ZitatDen playload zu dekodieren _ist  nicht_ deine Aufgabe. Falls es sich um JSON handelt (gefühlt 2/3 der Fälle) ist das die Aufgabe des JSON decoders.
Nur zur Protokoll, ich sehe das trotz staendigen Widerholens anders.

ZitatDas verbleibende  geschätzte 1/3, da bleibt es so wie es heute ist.
Es kann nicht so bleiben, du schreibst es ja selbst:
ZitatOb dort konvertiert werden muss (überhaupt nur wenn utf8 _und_ Sonderzeichen) bestimmt nur der Kontext. Dafür soll der user eine Funktion utf8_to_text haben.
D.h. der Benutzer muss wissen, welche Topics UTF-8 uebertragen, und die Behandlung dieser mit einer Funktion korrigieren.
Ich sehe das aber als deutlichen Komfortverlust mit sehr viel Umbau, fuer mich, mehr aber fuer attrTemplate und fuer die Endanwender.

Mein Problem, dass mein JSON-Dekoder von verschiedenen Stellen aufgerugen werden kann, ist damit auch nicht geloest.
Ich warte erstmal, ob nicht bessere Vorschlaege auftauchen.

rudolfkoenig

Zitatein EXPERIMENTELLES Attribut, das man nicht mehr löschen darf... echt super.
Das kann schon passieren, experimentelle Flugzeuge fallen auch haeufiger vom Himmel, als die anderen.

Ich habe aber kein Problem das Attribut zu entfernen.
Wo liegt dein Problem?

betateilchen

Zitat von: rudolfkoenig am 20 Februar 2022, 17:42:26
Ich habe aber kein Problem das Attribut zu entfernen.
Wo liegt dein Problem?

Das Problem ist, dass es in FHEM durchaus Attribute gibt, bei denen schon deren bloße Existenz ausreicht, um unvorhergesehene Ergebnisse zu liefern. Es spielt dabei keine Rolle, welchen Wert das Attribut hat.

Deshalb ist es mir - gerade bei experimentellen Attributen - viel lieber (sicherer?) ein Attribut komplett zu löschen, um den vorherigen Zustand wieder herzustellen.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

rudolfkoenig

Zitatder websocket standard sagt das text frames (0x1) utf-8 codiert sind. binary frames (0x2) sind uncodiert.
Ich habe das jetzt in FHEMWEB und DevIo fuer "encoding unicode" beruecksichtigt.

herrmannj

#70
Zitat von: rudolfkoenig am 20 Februar 2022, 17:40:08
@hermannj:Nur zur Protokoll, ich sehe das trotz staendigen Widerholens anders.
Es kann nicht so bleiben, du schreibst es ja selbst: D.h. der Benutzer muss wissen, welche Topics UTF-8 uebertragen, und die Behandlung dieser mit einer Funktion korrigieren.
Ich sehe das aber als deutlichen Komfortverlust mit sehr viel Umbau, fuer mich, mehr aber fuer attrTemplate und fuer die Endanwender.

Mein Problem, dass mein JSON-Dekoder von verschiedenen Stellen aufgerugen werden kann, ist damit auch nicht geloest.
Ich warte erstmal, ob nicht bessere Vorschlaege auftauchen.
natürlich darfst du das anders sehen :) Das ändert jedoch nichts an der Tatsache das die mqtt2.* aktuell broken sind. Der Value darf nicht pauschal konvertiert werden, dadurch wird "nicht Text" kaputt gemacht. "Nicht Text" ist auch JSON falls dort Sonderzeichen enthalten sind. Was genau ist denn deine Befürchtung wenn Du den Value rausnimmst? Dann geht alles so wie es jetzt geht _und_ die topics sind clean.

Das "Problem" bei JSON Decoder sehe ich nicht. Per Norm (https://www.json.org/json-en.html) ist der serialisierte JSON utf8 kodiert. Alles was seriell reingeht ist utf8, auf der anderen Seite purzelt ein Objekt raus. Einfach so machen. Die Ausnahmen dort einbauen wo von dieser Regel abgewichen werden muss, nicht andersrum. Ausnahmen kann ich sehen zb für den Fall dass in einem attribut oder reading json gespeichert wird

Damian

Um jetzt noch mal auf den ersten Post vom TE zurückzukommen,  siehe den Ursprung: https://forum.fhem.de/index.php/topic,120088.msg1209214.html#msg1209214

Was heißt das jetzt für alle Modulentwickler? Müssen jetzt alle ihren Programmcode nach Sonderzeichen durchsuchen:

Es betrifft ja hier nicht nur den dblog.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

rudolfkoenig

ZitatLiegt nachvollziehbar an den Newlines die nach Unicode 0x2424 gewandelt werden.
Danke habs gefixt.
Soviel darueber, dass mit unicode weniger Workarounds notwendig sind :)

ZitatWas genau ist denn deine Befürchtung wenn Du den Value rausnimmst?
MQTT2 laesst damit ein UTF-8 bytestream ins FHEM System rein. Wo man die Daten konvertiert, ist nicht mehr spezifiziert, diese Aufgabe wird dem Benutzer (bzw. attrTemplate) ueberlassen. Ich habe meinen Zweifel, dass das weniger Support bedeutet.

JSON kann gerne nach UTF-8 konvertiert werden, aber erst wenn es das System verlaesst.
Im JavaScript (wo JSON herkommt) ist das Ergebnis von JSON.stringify kein UTF-8, sondern ein Unicode String.
JSON.parse nimmt auch kein UTF-8, sondern ein Unicode String, sonst waere JSON.parse('{"name":"Küche"}') ein Syntaxfehler.
Das Konvertieren passiert beim Eingang/Ausgang, nicht beim Parsen.

MQTT liefert da ein Bytestream, und der Programmierer muss das je nach Protokoll wandeln.
Sowas kann ich aber nicht dem durchschnittlichen FHEM-Benutzer ueberlassen, noch dazu, dass das bisher nicht notwendig war.

Mein aktueller Favorit ist per Voreinstellung payload nach Unicode zu wandeln, und per optionalen Attribut bestimmte Topics nicht anzufassen.

rudolfkoenig

ZitatWas heißt das jetzt für alle Modulentwickler? Müssen jetzt alle ihren Programmcode nach Sonderzeichen durchsuchen:

Ich habe das hier schon geschrieben: https://forum.fhem.de/index.php/topic,126088.msg1208705.html#msg1208705

Ich versuchs anders zu formulieren.
Bei den Modulen, wo Folgendes zutriifft:
- Daten werden nach FHEM eingelesen oder aus FHEM ausgegeben
- die Daten enthalten lesbare Texte, die aber nicht nur ASCII sind
- die zur Kommunikation verwendete Perl-Bibliothek erledigt diese Aufgabe nicht (HttpUtils_NonblockingGet konvertiert aber)

muss nach dem Eingang / sysread / etc
$data = Encode::encode($encoding, $data) if($unicodeEncoding);

bzw. vor dem Ausgang / syswrite / etc
$data = Encode::decode($encoding, $data) if($unicodeEncoding);
aufgerufen werden.

$encoding haengt vom Kommunikationspartner ab, bei einigermassen aktuellen Systemen sollte das 'UTF-8' sein.

Fuer Dateien kann man das vereinfachen mit
binmode($fh, ":encoding(UTF-8)") if($unicodeEncoding);

nach dem Oeffnen der Datei.

justme1968

#74
ZitatJSON.parse nimmt auch kein UTF-8, sondern ein Unicode String, sonst waere JSON.parse('{"name":"Küche"}') ein Syntaxfehler.

den satz verstehe ich nicht.

UTF-8 ist ein mögliches encoding für einen unicode string.

wenn du in einem terminal fenster das auf utf-8 gestellt ist mit einer shell die auf utf-8 konfiguriert ist interaktiv node aufrufst und JSON.parse('{"name":"Küche"}') (das sind 32 bytes und 31 zeichen) eingibst geht das problemlos. eben weil alle bausteine aufeinander aufbauend utf-8 als encoding verwenden bzw. produzieren.

wenn du deine shell auf latin-1 stellst kannst du zwar z.b. ein ü tippen, aber du wirst es nicht schaffen das auch in node so zu tun das dein JSON.parse beispiel etwas vernünftiges liefert. hier wären das 31 bytes aber nicht unbedingt 31 zeichen.

der fehler ist aber kein syntax fehler. es ist ja 'nur' das encoding des strings kaputt bzw. passt nicht zum erwarteten utf-8. die syntax des ausdrucks ist immer noch völlig ok.

ps: es ist im allgemeinen übrigens schwerer als man denkt solche auf den ersten tlick einfachen test so zu machen das sie auch wirklich aussagekraft haben weil ganz schnell z.b. ein editor zwischen rein funkt der versucht das encoding automatisch zu erkennen und dann nicht mehr wirklich das darstellt das auch wirklich im file steht. oder in der kette irgendwo eine andere komponente dazwischen funkt.

ein file mit console.log(JSON.parse('{"name":"Küche"}')) hat als unicode z.b. eine länge von 45 byte, als latin-1 eine länge von 44byte. vi stellt sie aber identisch dar. wenn man sie in einer utf-8 shell mit node aufruft gibt die erste das erwartet ergebnis, die zweite aber { name: 'K�che' }, in einer latin-1 shell sind geben aber beide einen kaputten string aus. obwohl immer noch eine von beiden (diesmal die andere) per cat korrekt angezeigt wird.

hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968