Leider eskalieren aktuell wieder die Probleme mit Sonderzeichen und fhem. Eine Mehrheit dies zu ändern, zeichnet sich nicht ab, daher Hilfe zur Selbsthilfe:
Begriffsbestimmung
Ganz früher™ hatte ein Computerbyte 8Bit, ein byte speicherte einen Buschstaben und Computer konnten maximal 256 Zeichen unterscheiden. Die Anzahl der Buchstaben in allen Sprachen der Welt, Sonderzeichen und Satzzeichen sind in Summe natürlich viel mehr. Also gab es Codepages die jeweils einem Ausschnitt entsprachen, zum Beispiel den in Westeuropa am häufigsten benötigten Zeichen.
https://de.wikipedia.org/wiki/Codepage_850
Mit 16, 32 oder 64 bit Computern kann man in einer ,,Speicherzelle" deutlich mehr als 256 verschiedene Zeichen speichern. Speichern, im Zusammenhang mit Computern, bedeutet aber konkret nur, dass in einer Speicherzelle des RAM eine (neutrale) Zahl gespeichert wird. Welche Zahl welchem Zeichen entspricht, wird weiterhin per Konvention festgelegt. Das älteste Unicode-Kodierungsformat ist UTF-16, etabliert hat sich UTF-8.
https://de.wikipedia.org/wiki/UTF-8
Perl intern wird UNICODE verwendet: https://home.unicode.org/
Wenn ein perl Programm mit der Außenwelt kommuniziert, dann geschieht das klassisch über Strecken auf denen die Einheiten (byte, besser octet) nach wie vor aus 8bit bestehen. Irgendwie muss die große Anzahl verschiedener Buchstaben die perl kennt, in eine Folge von 8bit Zeichen konvertiert werden, wenn perl mit der Außenwelt spricht. Wenn etwas von außen kommt, entsprechend andersrum. UTF-8 schreibt die Regeln dieser Konvertierung fest. UTF-8 ist die Standardkodierung von zB MQTT (Topics), JSON, Websocket.
Wenn perl das alles kann, und alle Konventionen klar sind, warum passiert das nicht alles automatisch? Der Teufel liegt im Detail. Als perl den UNICODE Support eingeführt hat, hat man sich aus gutem Grund entschieden, dass der Programmierer die entsprechenden Funktionen aktiv aktivieren muss. Andernfalls hätte das die Kompatibilität massiv gebrochen. Eine MQTT Verbindung kodiert die topics die UTF-8, hier ist eine Konvertierung erwünscht und erforderlich. Wenn es sich aber um die Übertragung einer Firmware Binary handelt, dann darf da natürlich nichts angefasst werden, die muss originalgetreu übermittelt werden. Perl kennt den Unterschied nicht, das weiß nur der Programmierer. Wenn perl selbst aktiv werden soll, was es sehr einfach könnte, dann muss das explizit ansagen.
UNICODE, UTF-8, UTF-8 octets. Kleine, aber feine Unterschiede
Ein 32bit Perl kennt also 2^32 Zeichen (Buchstaben). Ist jedes dieser Zeichen dann gleichzeitig ein UTF-8 Zeichen? Die Antwort ist nein. UTF-8 definiert Bereiche welche Sonderfunktionen haben. Nicht alle theoretisch für perl verfügbare UNICODE Zeichen sind also gleichzeitig gültige UTF-8 Zeichen. Wie bereits geschrieben legt UTF-8 auch die Konventionen fest, wie die Zeichen umgewandelt werden, wenn sie auf 8bit Medien übertragen oder gespeichert werden. Man spricht dann oft von Octets. Aus diesem Zeichen ,,😀" wird dann zB eine Folge von 4 octects (a 8bit) gebildet. Lässt sich im Umkehrschluss jetzt aus jeder beliebigen Folge von octets ein UTF-8 Zeichen bilden? Die Antwort lautet wiederum nein. Nachschlagen kann man das in Tabellen wie der folgenden:
https://www.utf8-chartable.de/unicode-utf8-table.pl
Um perl den korrekten Umgang mit UTF-8 zu ermöglichen, haben die Entwickler verschiedene Möglichkeiten eingebaut. Beim Lesen eines Files von der Festplatte etwa, ist es sehr leicht möglich dem IO Layer mitzuteilen das es sich um eine Textdatei handelt deren Inhalt UTF-8 kodiert ist. open my $in, '<:encoding(UTF-8)', 'input-file-name' or die $!;
Zur Abgrenzung: natürlich gibt es etliche Gründe das nicht tun zu wollen. Zum Beispiel wenn die Konvertierung unbeabsichtigt binäre Daten, die nur wie UTF-8 aussehen, konvertiert. Deswegen muss man das explizit ansagen.
FHEM unterscheidet (per Konvention) dies alles nicht. Die Zeichen sollen so im Speicher landen, wie sie geliefert wurden. Im Falle des Smileys ,,😀" liegt also nicht ein einzelnes Zeichen da, sondern vier. Das kann man überprüfen:
my $uc = "😀";
print '0: '.length($uc)."\n";
Ergebnis: 4
Trotzdem ist das optisch häufig nur äußerst schwer zu erkennen, denn die Anzeige auf einem Monitor (des Smiley) funktioniert meistens trotzdem. Der Grund dafür ist, dass das entsprechende Ausgabemedium, also der Browser oder ein Code Editor, erkennt (oder sogar davon ausgeht), dass es sich um einen UTF-8 octet stream handelt, und das Zeichen daher korrekt darstellt. Im Gegenzug führt der richtige Umgang (UNICODE = U+1F600) dazu, dass Fehler auftreten. Die Meldung ,,illegal widechar in print" zum Beispiel bedeutet, dass das zugehörige Filehandle nicht informiert wurde, dass es UTF-8 ausgeben soll. Wenn es das wüste, dann würde es klaglos konvertieren. So ist es ratlos und ruft nach Hilfe 😉
Was bedeutet das für den Entwickler?
In der Theorie sind daher alle strings in FHEM UTF-8 octet streams. Das bedeutet das, neben vielen andere Effekten, Funktionen (oder Routinen), welche die Länge von Strings verarbeitet, ... "alternative Fakten" abbilden.
my $uc = "😀";
my $t = substr($uc, 0, 1);
print "=[$t]\n";
Das erste Zeichen des Strings mit dem Smiley sollte der Smiley sein. Stattdessen wird daraus ein ,,�". Surpise. Gleichfalls führen Versuche den String zeichenweise zu verarbeitet zu unerwarteten Effekten. Das resultierende Array wird vom Programmierer mit einem Element erwartet (ein Buchstabe), hat aber vier.
split(//, $uc)
Perfide dabei ist, dass solche Effekte nur auftreten, wenn auch wirklich Sonderzeichen verarbeitet werden. Wer sein eigenes Modul testet, und dabei anstelle des Smileys den Text ,,Foo" verwendet, wird den Fehler nicht bemerken. Es wird perfider. Versprochen. Es passieren haufenweise implizite Konvertierungen. JSON, zum Beispiel, definiert UTF-8 per Konvention als Format. Wenn also JSON Daten verarbeitet werden, dann wir die Bibliothek, welche man einsetzt, das dankenswerterweise übernehmen. Wenn ein JSON Key also ,,Jörg" lautet, dann wird der entsprechende Key für FHEM mit einer Länge von ... 4 geliefert. Nicht 5. ,,Professionelle" Bibliotheken für MQTT, Websocket und vieles andere machen das auch. Das Horneburger Schiessen 😉
Abhilfe.
Da also FHEM nicht also Boundary taugt, unvermeidlich aber das eine oder andere im FHEM vorzufinden ist, was tun. Die Grenze kann nur noch das eigene Modul sein. Zumindest wenn jenes potentiell mit ,,Sonderzeichen", also alles was nicht [0-9a-zA-Z] ist, in Berührung kommen kann. Ein altes CUL oder TRX Modul eher nicht. Alles was Webkontakt, JSON, Benutzerfelder (Freitext) hat – vmtl ja.
Alles was von Seiten FHEM selbst, oder von außen kommt, sollte daher nach UNICODE (1 Smiley == 1 Zeichen) konvertiert werden, es sei denn die Bibliothek (JSON) selber macht das. Im Zweifel, checken.
So geht's von UTF-8 ins perl UNICODE format:
use Encode qw(encode decode find_encoding);
eval {$uc = decode(find_encoding('UTF-8'), $uc, Encode::FB_CROAK)};
Falls der zu konvertierende String bereits UNICODE ist, dann ist das ein no-op. Wozu das eval? Wie weiter oben geschrieben gibt es UTF-8 octet Sequenzen, welche sich nicht in UNICODE konvertieren lassen. Mit der gewählten option Encode::FB_CROAK wirft das eval in diesem Fall einen Fehler. Der String ($uc) passiert die Konstruktion in diesem Fall unverändert (unkonvertiert). Darauf kann man reagieren. Wie, das bestimmt der Kontext und den kennt nur der Programmierer.
Alles was vom Modul in Richtung FHEM ,,rausgeht", unter anderem aber nicht abschliessend Log3, Readings, Attribute, DoTrigger, in die andere Richtung:
eval {$uc = encode(find_encoding('UTF-8'), $uc, Encode::FB_CROAK)};
Gleicher Hintergrund. Wenn ein UNICODE Zeichen versucht wird zu konvertieren, das keine UTF-8 octet Entsprechung hat, wird ein Fehler ($@) geworfen. Do what you want then 😉
use utf8; Pragma, is_utf8()
Das use utf8 Pragma macht genau eins: es sagt perl dass der source in einer UTF-8 Kodierung vorliegt.
Is_utf8() ist eigentlich eine Funktion der perl Developer zum Debuggen von perl. Nicht mehr, nicht weniger. Was sie definitiv nicht ist: eine Funktion um UTF-8 octet strings von UNICODE strings zu unterscheiden.
Folgender Code demonstriert beides. Man beachte den Unterschied bei aus-kommentiertem oder aktiviertem use utf8;
use utf8;
use Encode qw(encode decode find_encoding is_utf8);
my $uc = "😀";
print '0: '.length($uc)." flag: ".is_utf8($uc ,1)."\n";
eval {$uc = decode(find_encoding('UTF-8'), $uc, Encode::FB_CROAK)};
print '1: '.length($uc)." flag: ".is_utf8($uc ,1)."\n";
eval {$uc = encode(find_encoding('UTF-8'), $uc, Encode::FB_CROAK)};
print '3: '.length($uc)." flag: ".is_utf8($uc ,1)."\n";
eval { print "4: $uc\n"; };
Ausgabe mit use utf8:
0: 1 flag: 1
1: 1 flag: 1
3: 4 flag:
4: 😀
Ausgabe ohne use utf8:
0: 4 flag:
1: 1 flag: 1
3: 4 flag:
4: 😀
Zu dem Thema fällt mir gleich das FHEM Logfile ein. Wenn ich Unicode String logge bekomme ich eben genau ,,illegal widechar in print", was ich umgehe indem ich das log mit
binmode(LOG,"encoding(UTF-8)");
umschalte.
Wäre es denkbar das per Default zu machen?
Siehe hierzu auch: https://forum.fhem.de/index.php/topic,125866.0.html (https://forum.fhem.de/index.php/topic,125866.0.html)
ZitatWäre es denkbar das per Default zu machen?
Denkbar ist Vieles :)
Das wuerde implizieren, dass FHEM-Intern die Daten als Unicode vorliegen.
Aktuell setzen die meisten (alle?) FHEM-Schnittstellen vor, dass die Daten als utf-8 Bytefolge vorliegen, d.h. man wuerde von einer Fehlermeldung zum Naechsten kommen. Wenn wir umstellen, dann bitte mit einem Plan.
ZitatIs_utf8() ist eigentlich eine Funktion der perl Developer zum Debuggen von perl. Nicht mehr, nicht weniger. Was sie definitiv nicht ist: eine Funktion um UTF-8 octet strings von UNICODE strings zu unterscheiden.
Ich haenge nicht an is_utf8, ich brauche aber eine Methode, die Unicode-Strings erkennt, damit das Framework mit Modulen zusammenarbeiten kann, die Strings im Unicode-Format haben. Bin noch nichtmal sicher, dass es theoretisch immer moeglich ist, mit dieser Methode hatte ich bisher am wenigsten Aerger.
Die Encoding-Probleme werden bleiben, auch wenn wir FHEM-Intern auf Unicode umstellen, da nicht alle Modulschreiber sagen koennen, ob das Input nun UTF-8 ist oder nicht. Und dann bleiben die, die es vergessen, so wie die, die jetzt das utf8::encode vergessen. Perl-Bibliotheken, die direkt mit der Aussenwelt reden, liefern Daten natuerlich im Unicode Format, eine Umstellung macht die Zusammenarbeit hier einfacher. Eine JSON Bibliothek wird das nicht tun, da sie schon fertig kodierte Daten bekommt.
Und natuerlich waere nach einer Umstellung einfacher zu pruefen, wieviele Smileys ein String enthaelt :)
In meinen Augen der groesste Gewinn der Umstellung waere, dass wir solche Diskussionen nicht fuehren muessen.
Das waere fuer mich schon was Wert.
Ähm, stehe grade auf dem Schlauch mit einem Modul, konkret: msgDialog.
Da wird ein JSON für den betreffenden Dialog in die DEF geschrieben, also eigentlich seitens fhem.pl verwaltet und an das Modul übergeben. Beim Überarbeiten hatte ich mich dann etwas gewundert, warum da
$DEF = eval{JSON->new->decode($DEF)};
steht, und nicht gleich ein "decode_json($DEF)" an das eval geht.
Wenn man das umstellt und das Beispiel aus https://wiki.fhem.de/wiki/MsgDialog#Programmierung_der_Waschmaschine (https://wiki.fhem.de/wiki/MsgDialog#Programmierung_der_Waschmaschine) dahingehend modifiziert, dass die Waschmaschine "Wäschmaschine" heißt, wird auch klar, warum: im Internal TRIGGER steht dann was, was nicht verwertbar ist:
ZitatTRIGGER W�schmaschine
Daher habe ich das erst mal so belassen, wie es war, allerdings wirft das die Frage auf, ob bzw. an welcher Stelle eigentlich ein zukunftsgerichtetes Coding aussehen müßte...? Jedenfalls übergibt fhem.pl nach meinem Verständnis eben nicht UTF-8 im Rahmen von DefFn(), oder? (Schon gleich nicht, wenn man FileRead() verwendet).
Testsystem: OS: MSWin32 Perl: 5.32.1 (war aber nach meiner Erinnerung auch auf einem aktuellen Linux nicht anders, version liefert u.a. fhem.pl 25644 2022-02-06 20:01:09Z rudolfkoenig)
Ergänzend: Den Code hatte ich dahingehend überarbeitet, dass die DEF per InternalVal() gelesen wird (nach $content), jetzt wollte ich den Testcode so einbauen:
if ( !eval{ $content = decode(find_encoding('UTF-8'), $content, Encode::FB_CROAK); 1;} ){
Log3($hash, 2, "msgDialog ($name) - DEF or configFile is not decodable to UTF-8: $@");
return("Usage: define <name> msgDialog {JSON}\n\n$@");
}
Dann wirft aber bereits der unüberarbeitete Beispiel-Dialog aus dem Wiki einen Fehler, anscheinend kommt es bei "(bestätigen|zurück|abbrechen)" zu einem Problem:...
Zitatmalformed UTF-8 character in JSON string, at character offset 1014 (before "\x{fffd}gen|zur\x{fffd}...") at ./FHEM/76_msgDialog.pm line 140.
Json liefert Unicode, fhem.pl erwartet utf-8 octet. Wie oben beschrieben in Richtung fhem konvertieren.
decode_json() nimmt an, dass $DEF als utf-8 Bytestream vorliegt, und konvertiert es nach Unicode / Wide-Char.
JSON->new->decode() ist nicht ganz so mutig, und laesst die Daten unveraendert.
Das interne utf8->Flag (siehe utf8::is_utf8) setzen beide auf den zurueckgelieferten Strings.
Zitat von: herrmannj am 10 Februar 2022, 16:27:35
Json liefert Unicode, fhem.pl erwartet utf-8 octet. Wie oben beschrieben in Richtung fhem konvertieren.
Stehe immer noch am selben Fleck, also auf dem Schlauch...
Der betreffende "JSON"-String wird von fhem.pl an das Modul übergeben, sollte also schon UTF-8 sein (davon war die ganze Zeit die Rede, nicht utf-8, was was anderes zu sein scheint). Und logischerweise gibt es dann Probleme, wenn man "normales" decode_json darauf losläßt weil die Quelldaten eben nicht Unicode sind.
Zitat von: rudolfkoenig am 10 Februar 2022, 16:53:20
decode_json() nimmt an, dass $DEF als utf-8 Bytestream vorliegt, und konvertiert es nach Unicode / Wide-Char.
JSON->new->decode() ist nicht ganz so mutig, und laesst die Daten unveraendert.
Nachdem ich die Probleme festgestellt hatte, hatte ich diesen Unterschied bereits eruiert und den Teil so belassen, steht extra ein Kommentar im Code, damit das nicht so schnell in Vergessenheit gerät... ::)
Demnach ist hier die Methode
eval{JSON->new->decode($DEF)};
(auch für die weitere Zukunft) OK, weil die Daten schon im richtigen Format vorhanden sind und man grade die Konvertierung verhindern muss, damit die Konsistenz zu fhem.pl erhalten bleibt... (Das sieht anders aus, wenn die JSON-Daten von außen, z.B. via MQTT kommen; hier kommen sie aber aus der fhem.cfg).
noch ein paar kurze anmerkungen:
- prinzipiell ist es nicht möglich das encoding von unbekannten daten garantiert zu erkennen
jemand der anderes behauptet hat unrecht :).
- deshalb definieren viele 'moderne' protokolle/formate (websocket, json,...) das alles immer utf-8 ist
- ebenfalls deshalb sollte/muß man das encoding anderenfalls immer mit angeben
wenn man das konsequent macht erledigt perl den rest elegant und automatisch in allen richtungen und
kombinationen
- weil das die meisten nicht tun gibt es wege um das encoding zu 'raten' das geht mehr oder weniger gut
- für perl gibt es rate routinen z.b. in Encode::Detect oder Encode:Guess und noch andere
- wenn es um manuell eingaben geht wie quelltexte oder sonstigen code ist wichtig das die eingabe auch
schon mit utf-8 erfolgt ist und das entsprechend angegeben ist. das waschmaschinen beispiel schaut
nämlich gerade so aus also ob da ein latin-1 ä im byte stream format versucht wird direkt als unicode
zu verarbeiten. (das nur ein einziges zeichen dargestellt wird ist ein hinweis darauf) wenn man so etwas
möchte muss man entweder das ä als latin-1 markieren und perl die möglichkeit zur automatischen
konvertierung geben, oder das ä als multibyte/utf-8 kodiert haben. d.h. 'manuelle' tests haben den nachteil
das man zusätzliche unbekannte ins spiel bringt.
ZitatDas waere fuer mich schon was Wert.
war das ein angebot eine umstellung doch ins äuge zu fassen :) ?
Zitatwar das ein angebot eine umstellung doch ins äuge zu fassen :) ?
ich unterstütze die idee :)
ZitatDas sieht anders aus, wenn die JSON-Daten von außen, z.B. via MQTT kommen; hier kommen sie aber aus der fhem.cfg.
MQTT2_CLIENT und MQTT2_SERVER sollten die Daten als utf-8 Bytefolge reinlesen, genauso wie fhem.cfg, telnet und FHEMWEB.
MQTT.pm verwendet vermutlich Unicode.
Zitatwar das ein angebot eine umstellung doch ins äuge zu fassen :) ?
Ja, wenn wir die Bauchschmerzen fuer die Benutzer (aka Supportaufwand) begrenzen koennen.
D.h. die zentralen Module muessen mit beiden Datenformaten zurechtkommen, und das besser als heute.
Zitat von: rudolfkoenig am 10 Februar 2022, 17:29:28
MQTT2_CLIENT und MQTT2_SERVER sollten die Daten als utf-8 Bytefolge reinlesen, genauso wie fhem.cfg, telnet und FHEMWEB.
:) Das erklärt, warum "Spaß" angesagt war, bis RHASSPY die eingehenden Daten verstanden hat. Werde das vermutlich dann auch auf die "JSON->new" Variante umbiegen, im Moment sind da evtl. auch noch ein paar potentiell problematische Umformungen drin.
Wie ist es mit den HttpUtils? (HttpUtils_NonblockingGet) und den Callbacks daraus?
Zitatdie zentralen Module muessen mit beiden Datenformaten zurechtkommen, und das besser als heute.
alles was Zeichenkette innerhalb fhem.pl ist, wird unicode. Alles was nach draußen geht oder von da kommt: Spezifikationen lesen und danach passend konvertieren.
Die "Bauchschmerzen" sind einzig das Resultat von "braucht man nicht" -> modul autor braucht das doch (nicht wahr Beta-User;)) -> workaraounds werden eingebaut -> workarounds für die workarounds -> ...
MQTT topics zb werden per OASIS UTF-8 kodiert. Ergo, am fhem Eingang von UTF-8, zack, aus, fertig. Wenn einmal klar ist, dass alles was reingeht von x nach unicode gewandelt wird - und alles was rausgeht von unicode nach x, dann sind für Alle, alle Unklarheiten beseitigt.
ZitatWie ist es mit den HttpUtils? (HttpUtils_NonblockingGet) und den Callbacks daraus?
HttpUtils konvertiert auch nichts.
Das ist ja das Schoene an dieser Variante: solange keiner auf die Idee kommt, zu konvertieren, funktioniert (fast) alles.
Zitatalles was Zeichenkette innerhalb fhem.pl ist, wird unicode. Alles was nach draußen geht oder von da kommt: Spezifikationen lesen und danach passend konvertieren.
Die Theorie ist klar. Aber auch, dass ich das nicht alles auf einmal umstellen kann, ich keinen neuen Branch dafuer aufmachen werde, und ich mich nicht darauf verlassen kann, dass die Autoren der 500+ Module das koordiniert erledigen. Spezifikation zu lesen bei einem verwaisten Modul, wo man weder Hardware, noch Doku hat, ist auch nicht ohne.
Zitat von: herrmannj am 10 Februar 2022, 17:44:19
Die "Bauchschmerzen" sind einzig das Resultat von "braucht man nicht" -> modul autor braucht das doch (nicht wahr Beta-User;)) -> workaraounds werden eingebaut -> workarounds für die workarounds -> ...
Bin zwar nicht ganz sicher, was du mir damit sagen willst, aber mein Anliegen war zu erfahren, wie workarounds denn nun am besten zu beseitigen sind in dem jeweiligen konkreten Umfeld, um das es geht - und zwar unabhängig davon, wer den workaround ursprünglich mal eingebaut hatte (msgDialog habe ich erst vor ein paar Tagen übernommen, und der RHASSPY-Code war an dieser Stelle vorher schon "halbwegs" fertig, als ich dazugestoßen bin und das in Richtung auf "Kompabilität mit MQTT2-IO" umgebaut habe. Soweit mir die "alten Threads" von "davor" dazu in Erinnerung sind, war es dort "richtig seltsam", je nachdem, welches System auf der Gegenseite war (versionsabhängig, docker, schießmichtot, ...).
Dass dieses ganze Thema "verquer" ist, war mir seit der RHASSPY-Bepflasterung gewahr, und nach deiner Bemerkung weiß ich jetzt immer noch nicht, ob das mit "JSON->new" der "ordentliche Weg" wäre, wenn die Schnittstellen MQTT2-IOs sind...
Zitat von: rudolfkoenig am 10 Februar 2022, 17:56:29
HttpUtils konvertiert auch nichts.
Das ist ja das Schoene an dieser Variante: solange keiner auf die Idee kommt, zu konvertieren, funktioniert (fast) alles.
OK, bedeutet, dass man sich die callbacks anschauen sollte und dort (bei JSON-Input) eben nicht json_decode drauf loslassen sollte, sondern JSON->new...
ZitatSpezifikation zu lesen bei einem verwaisten Modul, wo man weder Hardware, noch Doku hat, ist auch nicht ohne.
da wirst du am seltensten Probleme haben, das sind nämlich genau die, die am unwahrscheinlichsten mit unicode überhaupt in Berührung kommen. Problematisch: fhemweb oder devio, syswrite etc. Aber so funktioniert aufräumen, irgendwo muss man anfangen.
Ich würde als erstes mit reading-inhalten anfangen. Dazu muss der statefile utf8 geschrieben und gelesen werden, fhem intern unicode. Die Kette bis zum fhemweb lässt sich testen und debuggen. Weitere Auswirkungen wird man sehen. Module müssen nachziehen, sonst sieht man Fehldarstellungen. Funktionelle Einschränkungen wird es auch geben (notify triggert auf Wäsche). Schritt für Schritt
Zitat von: Beta-User am 10 Februar 2022, 18:04:48
Bin zwar nicht ganz sicher, was du mir damit sagen willst, aber mein Anliegen war zu erfahren, wie workarounds denn nun am besten zu beseitigen sind in dem jeweiligen konkreten Umfeld, um das es geht - und zwar unabhängig davon, wer den workaround ursprünglich mal eingebaut hatte (msgDialog habe ich erst vor ein paar Tagen übernommen, und der RHASSPY-Code war an dieser Stelle vorher schon "halbwegs" fertig, als ich dazugestoßen bin und das in Richtung auf "Kompabilität mit MQTT2-IO" umgebaut habe. Soweit mir die "alten Threads" von "davor" dazu in Erinnerung sind, war es dort "richtig seltsam", je nachdem, welches System auf der Gegenseite war (versionsabhängig, docker, schießmichtot, ...).
ich wollte dir nicht zu Nahe treten, das war kein Vorwurf. Du bist gerade dass Beispiel dass man unicode Support benötigt und es keinesfalls nur darum geht ob ein smiley 1 oder 4 Zeichen lang ist. Der mangelnde support im framework ist das Problem. Zu Deiner Frage: es gibt keine einfache Antwort. Solange fhem das nicht unterstützt kannst Du die Workarounds nicht beseitigen sondern musst immer mehr davon einbauen.
die größten probleme wird es vermutlich bei den regexen geben. ich denke hier sollten wir:
- die regexen in fhem.pl und fhemweb durchgehen und die workarounds ausbauen
- dabei auch schauen welche regex dabei auf die dann möglichen dinge umgestellt werden können
z.b. umlaute auch wirklich zulassen, \w statt [A-za-z] verwenden und ähnliches
- für die endanwender dokumentieren was sich warum geändert hat und was neu möglich ist
ZitatWeitere Auswirkungen wird man sehen.
Genau das meinte ich mit Bauchschmerzen und Supportaufwand, was ich vermeiden will.
Zitatdie größten probleme wird es vermutlich bei den regexen geben.
Aber nur, wenn man die Menge der erlaubten Zeichen bei Namen erweitert.
Sowas wuerde ich erst nach der internen Encoding-Umstellung angehen, ich meine wir werden auch ohne ein Zeichensatz-Erweiterung genug Aerger haben.
ich würde weitere Probleme erwarten wenn zb irgendwo Texte ausgegeben werden und die dann auf ein syswrite welches auch binäre streams verarbeitet. Automatisch konvertieren geht dann "da unten" nicht mehr. Theoretisch hätte fhem eine (logisch selbstgestrickte;) funktion: latin1ToUtf8($) sowie utf8ToLatin1($)
Da aufsetzen und den developern zentral anbieten (bitte nicht selberstricken): unicode_to_utf8
use Encode qw(encode decode find_encoding);
eval {$uc = encode(find_encoding('UTF-8'), $uc, Encode::FB_CROAK)};
sowie utf8_to_unicode
use Encode qw(encode decode find_encoding);
eval {$uc = decode(find_encoding('UTF-8'), $uc, Encode::FB_CROAK)};
Ab dann kann man schonmal jeden dev sagen: wenn Du "illegal widechar.." siehst - nutze bitte "unicode_to_utf8", vor der Ausgabe, in deinem modul.
Zitat von: rudolfkoenig am 10 Februar 2022, 19:13:16
Genau das meinte ich mit Bauchschmerzen und Supportaufwand, was ich vermeiden will.
und statt dessen laufen dutzende devs gegen die Wand weil sie nicht verstehen können wo sie noch workarounds einbauen müssen.
Diesen ganzen Block (ua) muss ich in JsonMod einbauen weil Readingnamen aus JSON keys generiert werden, der JSON kommt von extern und keiner der da draussen irgendwo JSON anbietet ist bereit sich unseren Restriktionen zu unterwerfen. Klar kann man auch ne regex auf [a_zA-Z] durchlaufen lassen. technisch gibts aber weder für das eine noch für das andere einen Grund.
258 # sanitize reading names to comply with fhem naming conventions
259 # (allowed chars: A-Za-z/\d_\.-)
260 my sub sanitizedSetReading {
261 my ($r, $v) = @_;
262
263 # convert into valid reading
264 # special treatment of "umlaute"
265 my %umlaute = ("ä" => "ae", "Ä" => "Ae", "ü" => "ue", "Ü" => "Ue", "ö" => "oe", "Ö" => "Oe", "ß" => "ss" );
266 my $umlautkeys = join ("|", keys(%umlaute));
267 $r =~ s/($umlautkeys)/$umlaute{$1}/g;
268 # normalize remaining special chars
269 $r = Unicode::Normalize::NFD($r);
270 utf8::encode($r) if utf8::is_utf8($r);
271 $r =~ s/\s/_/g; # whitespace
272 $r =~ s/([^A-Za-z0-9\/_\.-])//g;
273 # prevent a totally stripped reading name
274 # todo, log it?
275 #$r = "_Identifier_$_index" unless($r);
276 $v //='';
277 utf8::encode($v) if utf8::is_utf8($v);
278 $newReadings->{$r} = $v;
279 $oldReadings->{$r} = 1;
280 #printf "1 %s %s %s %s\n", $r, length($r), $v, length($v);
281 };
ZitatAber nur, wenn man die Menge der erlaubten Zeichen bei Namen erweitert.
nein. leider nicht nur. mir fällt gerade die konkrete stelle nicht ein aber es gibt mindestens einen fall
wo wir eine regex explizit angepasst haben weil umlaute aktuell als zwei zeichen (bytes) zählen und an dieser stelle umlaute erlaubt waren. nach der umstellung sind umlaute ein zeichen. wie es sich gehört und werden mit \w auch gematched.
auch an stellen wo aktuell explizit nach umlauten gesucht wird um sie für die ausgabe oder html umzuwandeln muss unter umständen angepasst werden.
trozdem wird alles besser wenn wir es angehen und geschafft haben.
edit: ich glaube es hatte mit den raum namen zu tun. da sind umlaute ja auch jetzt schon erlaubt.
Zitateval {$uc = encode(find_encoding('UTF-8'), $uc, Encode::FB_CROAK)};
Wenn schon FB_CROAK, dann sollte das Ergebnis von eval geprueft werden: was genau sollte man im Fehlerfall tun?
Ich bin eher fuer FB_DEFAULT oder FB_WARN.
Zitatund statt dessen laufen dutzende devs gegen die Wand weil sie nicht verstehen können wo sie noch workarounds einbauen müssen.
Ich sehe es z.Zt. genau andersherum. Ich habe damit kaum bzw. keine Probleme, ein paar wenige manchmal etwas.
Die Umstellung wird massiv Aerger bedeuten, und ich werde monatelang Support fuer verwaiste Module leisten duerfen.
Zitattrozdem wird alles besser wenn wir es angehen und geschafft haben.
Das man _danach_ sagen kann: das ist der Standard, selbst schuld, wenn du dich nicht daran haelst, ist mir klar.
Ob es unter dem Strich besser wird, haengt davon ab, wer die Statistik in Auftrag gibt.
ZitatWenn schon FB_CROAK, dann sollte das Ergebnis von eval geprueft werden: was genau sollte man im Fehlerfall tun?
Ich bin eher fuer FB_DEFAULT oder FB_WARN.
Bin bei Dir, kann man diskutieren. In beide Richtungen gibt es die Chance, dass nicht konvertiert werden kann. Was dann zu tun ist weiß nur der dev. Der muss also die Info bekommen, der Rest liegt bei ihm. Abbrechen, Defaults verwenden, user informieren, whatever
ZitatIch habe damit kaum bzw. keine Probleme, ein paar wenige manchmal etwas.
wie viel probleme man hat hängt sehr stark davon ab welche module man einsetzt, bzw. wieviel kontakt man damit zur aussenwelt und externen apis hat. jemanden der 'nur' in seiner fhem welt bleibt und ein paar rf devices einsetzt sieht wenig probleme, jemand der viele externe geräte und dienste angebunden hat wie hue, HTTPMOD, harmony, ... wird sehr viel mehr probleme haben. vor allem wenn er wie es eigentlich heutzutage selbstverständlich sein sollte in den externen systemen namen mit umlauten oder ähnlichem verwendet. alles andere ist nicht mehr zeitgemäß und wird von jedem nicht idv futzi als veraltet und unmöglich angesehen. ein 'einfacher' anwender verzweifelt unter umständen schon wenn er per regex in einer per Httputils zurückgelieferten seite einen wert extrahieren will und seine regex mit einem . partout nicht auf den umlaut den internen zwei byte matchen will. oder der. umlaut in der regex nicht matched oder, oder, ...
ZitatDas man _danach_ sagen kann: das ist der Standard, selbst schuld, wenn du dich nicht daran haelst, ist mir klar.
Ob es unter dem Strich besser wird, haengt davon ab, wer die Statistik in Auftrag gibt.
es geht ja nicht darum standards zu verwenden weil es schön ist sondern tatsächlich konkret vorhandene probleme ein mal und richtig zu lösen. auch wenn das am anfang schmerzhaft er ist als immer nur ein bisschen oben drauf zu
pfuschen reparieren. das aber immer wieder und irgendwann macht der neue workaround irgend einen alten zu nichte und niemand weiss mehr warum es nicht geht.
Ich habe das global Attribut encoding eingefuehrt, mit den moeglichen Werten unicode und utf8.
utf8 ist default, entspricht dem bisherigen internen Format utf-8.
Mit unicode (das ist EXPERIMENTELL und Work-in-Progess) wird intern Unicode/Wide-Char verwendet, d.h. nach dem Einlesen muss Encode::decode('UTF-8', ...), und vor dem Ausgeben Encode::encode('UTF-8', ...) durchgefuehrt werden.
Mit "attr global encoding unicode" wird die globale Variable $unicodeEncoding gesetzt.
Umgestellt und kurz getestet habe ich:
- fhem.cfg und fhem.state
- FileRead/FileWrite in fhem.pl
- das FHEM Log
- telnet
- FHEMWEB
- HttpUtils.pm
Das Setzen des Attributes im laufenden Betrieb wird nicht empfohlen, getestet habe ich es nicht.
Ich habe darauf geachtet, dass beim nicht gesetzten Attribut der Code gleich bleibt, kann aber sein, dass ich was uebersehen habe.
Ich als Maintainer muss noch eventType, FileLog, MQTT2_CLIENT und MQTT2_SERVER umstellen. Falls ich was vergessen habe, bitte melden.
Natuerlich gibt es eine ganze Reihe anderer Module, die das explizit unterstuetzen muessen, mir faellt im Moment configDB und DbLog ein.
toll. ich schaue mir an was ich in meinen modulen ändern muss.
aber ein kleinlicher kommentar um das risiko für missverständnisse irgendwann später zu minimieren: wir wollen ja zwischen dem perl unicode handling zu dem wir hin wollen und dem aktuellen zustand mit bytefolgen die zwar utf-8 encoded sind aber nicht als perl unicode utf-8 strings markiert sind unterscheiden.
deshalb denke ich das andrere name für die attributwerte besser wäre. z.b. bytestream (fhem legacy utf-8 byte stream, byte semantik) und unicode (perl unicode handling, character semantik). d.h. es sind wirklich zwei gegensätze. was unicode und utf-8 nicht sind.
wie perl intern die strings codiert (utf-8 oder utf-32 oder sogar etwas ganz anderes) ist im prinzip egal und transparent, muss noch nicht mal immer gleich sein, hängt von diversen optimierungen ab, ... das encoding kommt 'nur' und erst dann ins spiel wenn man daten hat die man perl übergeben bzw. aus perl zur weiterverarbeitung abholen möchte. hier gibt man jeweils das encoding an in dem die externen daten vorliegen bzw. vorliegen sollen.
habe utf8 nach bytestream geaendert.
Zitat von: rudolfkoenig am 14 Februar 2022, 22:07:11
Das Setzen des Attributes im laufenden Betrieb wird nicht empfohlen, getestet habe ich es nicht.
Wie soll das Attribut denn sonst gesetzt werden, außer im laufenden Betrieb?
Zitat von: rudolfkoenig am 14 Februar 2022, 22:07:11
Natuerlich gibt es eine ganze Reihe anderer Module, die das explizit unterstuetzen muessen, mir faellt im Moment configDB und DbLog ein.
Sobald ich irgendwann verstanden habe, WAS ich da in configDB unterstützen muss, kann ich das gerne berücksichtigen.
Aus diesem Thread hier kann ich das als Maintainer jedenfalls nicht ableiten.
ZitatWie soll das Attribut denn sonst gesetzt werden, außer im laufenden Betrieb?
Das ist eine berechtigte Frage.
Vermutlich sollte FHEM bei einer Aenderung des Wertes automatisch save+shutdown restart machen.
ZitatSobald ich irgendwann verstanden habe, WAS ich da in configDB unterstützen muss, kann ich das gerne berücksichtigen.
Falls $unicodeEncoding gesetzt ist, muss man alles nach Einlesen "von Aussen" in das interne Unicode/Wide-Char Format konvertieren, und vor dem Rausschreiben "nach Aussen" nach UTF-8 Bytestream (bzw. das, was adequat ist).
Bei Dateien erledigt beide Richtungen:
binmode($fh, ":encoding(UTF-8)") if($unicodeEncoding);
Bei sonstigen FH:
Input, nach sysread:
$buf = Encode::decode('UTF-8', $buf) if($unicodeEncoding);
Output, vor syswrite:
$buf = Encode::encode('UTF-8', $buf) if($unicodeEncoding);
Hallo Rudi,
danke für die Beschreibung der konkreten Maßnahmen.
Zitat von: rudolfkoenig am 14 Februar 2022, 22:07:11
Umgestellt und kurz getestet habe ich:
- FileRead/FileWrite in fhem.pl
Für mein Verständnis gibt es in configDB keine ToDos, solange ich davon ausgehen kann, dass diese beiden Funktionen korrekt arbeiten.
Alle Daten, die von Modulen in die Datenbank geschrieben oder daraus gelesen werden, benutzen dazu den Weg über FileWrite() und FileRead().
configDB selbst nimmt keine Verbindungen zur Außenwelt auf und führt auch keine Konvertierungen durch.
ZitatFür mein Verständnis gibt es in configDB keine ToDos, solange ich davon ausgehen kann, dass diese beiden Funktionen korrekt arbeiten.
Diese Funktionen arbeiten leider nur "korrekt" fuer Dateien, der Aufruf von cfgDB_FileRead / cfgDB_FileWrite wird nicht behandelt.
Ich habe hier noch ein paar Probleme. Wenn ich unter encoding=Unicode Umlaute etc. im Attribut "stateFormat" verwende, bekomme ich sowas
(Rücklauf): 30.4°
auch wenn ich das Attribut nochmal neu editiere und speichere.
Schalte ich zurück auf "bytestream" schaut es wieder richtig aus.
Edit: Und FTUI (alte Version) ist unter Unicode komplett hinüber - identifiziert Icon Namen nicht mehr uvm
ZitatIch habe hier noch ein paar Probleme.
Das sollte bitte keinen ueberraschen, ich habe nicht umsonst EXPERIMENTELL geschrieben.
Und wenn sich daran was aendern soll, dann sollten die Probleme nachstellbar beschrieben werden, da ich es noch nicht kann:
fhem> l global encoding
global unicode
fhem> define d dummy
fhem> attr d stateFormat reading1 Rücklauf
fhem> l d STATE
d reading1 Rücklauf
fhem> setreading d reading1 Küche
fhem> l d STATE
d Küche Rücklauf
Die FHEMWEB Ansicht schaut auch ok aus.
Ich tippe auf noch nicht angepasste FHEM-Module.
Ich habe bei deinem Beispiel in beiden Fällen "kaputte" Umlaute und wenn ich auf bytestream zurückgehe ist alles ok.
Kann das noch mit Einstellungen auf Linux Ebene zusammehängen (LC_ALL?)
Jörg
Danke fuer die Idee.
LC_ALL wurde noch nie beachtet (mW uebertraegt telnet/etc keine Umgebungsvariablen an dem Server), das muss man "schon immer" fuer FHEM mit "encoding utf8" oder "encoding latin1" einstellen.
Ich habe es in einem latin1 Terminal getestet, und ich hatte tatsaechlich trotz "encoding latin1" Probleme.
Ich habe das jetzt in telnet.pm gefixt.
Ich gehe davon aus, dass die Terminals seit eltichen Jahren per UTF-8 Voreinstellung konfiguriert sind.
Man kriegt es leicht raus mit echo ä | wc.
3 ist utf-8, 2 ist latin1 oder Vergleichbares.
telnet könnte das schon, das problem damals war das fhem telnet modul eigentlich die komplette kommunikation dir zwischen client und server bidirektional möglich wäre garnicht richtig unterstützt und eher reine socket kommunikation wie netcat macht.
deshalb hatte ich das damals aufgegeben und auch die idee die cursortasten und cmdline history noch einzubauen aufgegeben :)
es war halt mit dem manuellen konfigurieren gut genug.
Da hab ich dich jetzt vielleicht auf die falsche Fährte gebracht. Ich hab das Problem unter FHEMWEB
attr global encoding unicode
defmod xxx dummy
attr xxx stateFormat abc öüÄ
setstate xxx Küche äüö
schaut dann so aus wie im Bild, wenn ich auf zurück auf bytestream schalte, alles wie gewollt.
Selbiges auch wenn ich Emojis copy&paste - im Editor schauts erst gut aus, aber nach dem Speichern alles in 8-Bit
Browser ist Chrome unter Windows
Zitat von: betateilchen am 17 Februar 2022, 09:20:16
Alle Daten, die von Modulen in die Datenbank geschrieben oder daraus gelesen werden, benutzen dazu den Weg über FileWrite() und FileRead().
configDB selbst nimmt keine Verbindungen zur Außenwelt auf und führt auch keine Konvertierungen durch.
Damit ist dann auch das statefile berücksichtigt?
Die States werden, so weit ich weiß, in einer separaten Tabelle gespeichert
gb#.
@Adimarantis: Danke fuer das Beispiel, habs gefixt (URL war noch nicht dekodiert).
@Benni: Dateibasiert sollte es funktionieren. configDB muss noch angepasst werden.
Weiterhin:
- Unterstuetzung fuer MQTT2_SERVER, MQTT_CLIENT, FHEM2FHEM und FileLog eingebaut.
- da eventTypes, holiday und SVG FileRead/FileWrite verwendet, war hier keine Aenderung notwendig. Dafuer war FileLog extra aufwendig, bin nicht sicher, dass ich alles gefunden habe.
- die Umlaute werden in telnet mit inform auch auf latin1 Terminals richtig dargestellt. Vermutlich nur mit "encoding unicode" :(
- aendern des encoding Attributes bewirkt ein sofortiges save und shutdown restart
- das Attribut ist jetzt dokumentiert.
Eine Liste der Module, die noch umgestellt werden muessen, waere hilfreich.
Ich habe vor bei der naechsten Noetigung laenger Widerstand zu leisten.
Ich habe gerade gesehen dass du mqtt2 Client nachgezogen hast. Das betrifft dort topic und value. Topic ist korrekt weil so standardisiert. Value kann alles sein, auch binary. Daher darf dort nicht automatisch konvertiert werden. Falls der payload json ist, wird der json Decoder zuständig, der wendet das an.
Das mit dem "save" nach Attribut Änderung klappt nicht. (aktuelle Version vom svn)
Dachte gerade ich hätte einen Fehler gefunden, dabei hat er mein encoding=unicode nie genommen, da es nach dem automatischen shutdown immer weg war.
Sonst schauts schon viel besser aus
An welcher Stelle muss ein Modul das implementieren, dass 1. DevIO mit WebSocket, 2. HttpUtils_NonblockingGet benutzt, um mit dem Gerät zu kommunizieren? Bei den Daten handelt es sich, rein wie raus, um JSON (meines Wissens nach UTF8). Übersetzt werden die Daten, ebenfalls wieder in beide Richtungen, mit encode_json und decode_json. Die beiden Funktionen können wohl auch mit Unicode-Strings arbeiten statt mit UTF8. Ich vermute mal, alles, was von DevIO bzw. HttpUtils_NonblockingGet an Daten kommt oder dorthin geht, muss konvertiert werden. Wie ist es mit der URL - muss die auch konvertiert werden?
@hermannj:
Stimmt, value kann auch binary sein.
Das macht mich aber ratlos, da mAn die Konvertierung im JSON-Parser falsch ist: woher soll mein Parser wissen, woher die Daten kommen? Sie koennen intern erzeugt sein oder ueber HTTP/HTML kommen, wo die Kodierung festgelegt und durchgefuehrt ist.
Ich bin auch sicher, dass etliche Gadgets in "einfachen" MQTT-Values (nicht Json-kodiert) UTF-8 verschicken.
Faellt Dir eine generische Loesung fuer die Konvertierung in MQTT ein?
Ich bin zunehmend von meiner urpruenglichen "bytestream" Loesung begeistert.
@Adimarantis:
verwendest Du configDB?
Wenn ja: das funktioniert noch nicht.
Wenn nicht: kannst Du mir was zum Nachstellen zeigen?
Ich habe save gestern eigentlich getestet. Meine ich jedenfalls :)
@xenos1984
Ich gehe davon aus, dass websocket nicht auf UTF-8 festgelegt ist. Wenn das stimmt, dann muss man nach DevIo_SimpleRead ein Encode::decode ausfuehren, und vor DevIo_SimpleWrite ein Encode::encode. Wenn die Konvertierung durch encode_json und decode_json erfolgt, dann musst man nichts unternehmen.
Wenn websocket per Definition auf UTF-8 festegelegt sein sollte, oder die Konvertierung sonstwie rauszukriegen ist, dann baue ich die Umwandlung in DevIo.pm ein => Bitte zeigt mir die Spezifikation.
HttpUtils_NonblockingGet ist anders, da HTTP und Html Direktiven fuers Encoding haben.
Aus diesem Grund uebernimmt HttpUtils das Encoding selbst.
Beim URL kenne ich die Spezifikation nicht, aber im vorherigen Beispiel von Adimarantis kamen die Daten im URL erst URL-encoded, und dann UTF8-encoded. Die UTF-8 Dekodierung habe ich gestern in FHEMWEB / Digest_CGI() eingebaut, seitdem funktioniert sein Beispiel.
der websocket standard sagt das text frames (0x1) utf-8 codiert sind. binary frames (0x2) sind uncodiert.
Nochmal probiert: Attribut geändert -> automatischer Neustart -> Attribut hat alten Wert
Aktuell habe ich eigentlich nur noch das Problem mit dem alten FTUI - dort sind sämtiche Icons/Bilder kaputt.
Ich habe folgendes definiert:
defmod TabletUI HTTPSRV frontend/ ./www/tablet Tablet
Wenn ich jetzt ganz einfach ein Bild via HTTPSRV hole:
http://x.x.x.x:8083/fhem/frontend/cam3.jpg
Dann wird die Binärdatei anscheinend konvertiert und ist kaputt.
Gehe ich direkt auf die URL
http://x.x.x.x:8083/fhem/www/tablet/cam3.jpg
dann wird das Bild korrekt angezeigt.
Edit: Ich verwende fhem.cfg und habe diese mit Notepad++ nach UTF8+BOM konvertiert was gut funktioniert hat
Und leider noch ein Problem (ist mir mit den DOIF cards aufgefallen lässt sich aber auch so nachstellen):
Für ein beliebiges Device das stateFormat Attribut editieren (so dass man den Editor bekommt) und mehrzeiligen Perlcode eingeben, z.B.
{my $abc=1;
print $abc;
}
Beim Speichern kommt der Fehler:
ERROR evaluating my $name= $evalSpecials->{'%name'};{return undef; {my $abc=1;print $abc;}}: Unrecognized character \x{2424}; marked by <-- HERE after my $abc=1;<-- HERE near column 64 at (eval 15241) line 1.
Liegt nachvollziehbar an den Newlines die nach Unicode 0x2424 gewandelt werden.
Mit dem Editor bei einem DEF (z.B. wieder DOIF) passiert das nicht.
Zitat von: rudolfkoenig am 19 Februar 2022, 10:56:24
verwendest Du configDB?
Wenn ja: das funktioniert noch nicht.
Wenn nicht: kannst Du mir was zum Nachstellen zeigen?
Ich habe save gestern eigentlich getestet. Meine ich jedenfalls :)
@Rudi: wenn Du hier die Meinung vertrittst, dass "das" (was eigentlich?) bei configDB "noch nicht funktioniert", solltest Du mir bitte was zum Nachstellen geben, damit ich ein eventuell vorhandenes Problem beheben kann.
Du erwartest ja auch immer ein Beispiel zum Nachstellen.
Zitat von: Adimarantis am 19 Februar 2022, 12:18:56
Nochmal probiert: Attribut geändert -> automatischer Neustart -> Attribut hat alten Wert
Edit: Ich verwende fhem.cfg
Das Speichern des Attributes funktioniert nicht nur bei fhem.cfg nicht, sondern auch bei configDB nicht.
Der Neustart wird aber durchgeführt.
Edit:
Das Problem beim Speichern liegt vermutlich im Zusammenspiel mit dem globalen Attribut "autosave".
Bei mir stand das auf 0. Nachdem ich das Attribut gelöscht habe, wird beim Setzen des Attributes "encoding" das Speichern ausgeführt und ist nach dem anschließenden automatischen Neustart auch wieder vorhanden.
Zitat von: rudolfkoenig
Stimmt, value kann auch binary sein.
Das macht mich aber ratlos, da mAn die Konvertierung im JSON-Parser falsch ist: woher soll mein Parser wissen, woher die Daten kommen? Sie koennen intern erzeugt sein oder ueber HTTP/HTML kommen, wo die Kodierung festgelegt und durchgefuehrt ist.
Ich bin auch sicher, dass etliche Gadgets in "einfachen" MQTT-Values (nicht Json-kodiert) UTF-8 verschicken.
Faellt Dir eine generische Loesung fuer die Konvertierung in MQTT ein?
Du läufst zu weit :) Den topic zu decodieren_ist_ deine Aufgabe. Den 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. Das verbleibende geschätzte 1/3, da bleibt es so wie es heute ist. Ob 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.
ZitatIch bin zunehmend von meiner urpruenglichen "bytestream" Loesung begeistert.
Das fühlt sich nur im Umbruch so an.
Ich habe mein Testsystem jetzt auch mal auf unicode umgestellt.
Fürs erste scheint alles erst mal zu funktionieren, wobei mein Testsystem jetzt auch nicht so umfangreich ist.
Das einzige was mir spontan aufgefallen ist: Egal in welchem Bereich ich in FHEMWEB bin (Menüauswahl/Räume) Wird mir im Titel vom Menü das "ü" falsch dargestellt. Einzig wenn ich auf den Menüeintrag "Logfile" gehe, dann wird es korrekt angezeigt.
gb#
Zitat von: Benni am 19 Februar 2022, 21:17:52
Das einzige was mir spontan aufgefallen ist: Egal in welchem Bereich ich in FHEMWEB bin (Menüauswahl/Räume) Wird mir im Titel vom Menü das "ü" falsch dargestellt. Einzig wenn ich auf den Menüeintrag "Logfile" gehe, dann wird es korrekt angezeigt.
So einen ähnlichen Effekt habe ich an einer einzigen Stelle mit stateFormat, da soll eine Temperatur mit °C angezeigt werden.
<td informId="owo">
<div id="owo" title="5.4 °C / 94 %" class="col2">5.4 °C / 94 %</div>
</td>
Ansonsten konnte ich nach der Umstellung auf unicode noch keine weiteren Anzeigeprobleme feststellen.
Ich habe gerade festgestellt, dass es mir inzwischen auch bei der Anzeige des LogFile nicht mehr korrekt angezeigt wird.
Edit:
Jetzt habe ich mal nachgeschaut, wo das "Menü" eigentlich herkommt.
Das kommt bei mir aus dem Css-Attribut vom FHEMWEB-Device, bzw. dem AdditionalCss des, dem FHEMWEB zugeordneten F18 Styles:
div#menu > .col_header:before {
content: "Menü";
}
Dort steht es also nach der Umstellung auf unicode auch falsch drin.
Nach nun erneuter Eingabe des "ü" ist die Anzeige nun wieder korrekt.
gb#
Ich bekomme das Problem im Attribut stateFormat nicht gelöst, gerade habe ich ein ähnliches Problem bei der Darstellung des € Zeichens im Attributwert festgestellt.
Wenn ich mit dem vorgeschlagenen Weg zu encoding bzw. decoding experimentiere, wird die Sache nur noch schlimmer.
Im Moment wird der Attributwert komplett verhunzt.
Könnte man GetDefAndAttr() in fhem.pl so gestalten, dass die Funktion bereits korrekt konvertierte Daten liefert?
Dann wäre die Konvertierung einheitlich für fhem.cfg und configDB gelöst und der Kram müsste einfach nur noch weggeschrieben werden.
schau mal bitte wo das Problem liegt (Eingabe oder Ausgabe).
Richtiges Verhalten: innerhalb fhem ist das € text. Wenn Du dort irgendwo length($x) einbaust muss das Ergebnis 1 für € lauten. In diesem Fall wäre das Problem die Ausgabe. GetDefAndAttr() sollte Deiner Meinung nach text oder utf8 liefern?
Zitat von: herrmannj am 20 Februar 2022, 14:45:10
Richtiges Verhalten: innerhalb fhem ist das € text.
Es wird aber schon in telnet falsch dargestellt:
Attributes:
reading01Name state
reading01OExpr $val=~s/,//g;$val=~s/\./,/;"$val â¬";
reading01Regex <title>(.*).\(
Eigentlich sollte da "$val €" stehen.
Zitat von: herrmannj am 20 Februar 2022, 14:45:10
GetDefAndAttr() sollte Deiner Meinung nach text oder utf8 liefern?
woher soll ich das wissen?
GetDefAndAttr() liefert mir ein array mit Textzeilen, die ich in die Datenbank schreibe.
Genau so wie sie weggeschrieben werden, werden sie später wieder eingelesen und per AnalyzeCommandChain() verarbeitet.
Mehr habe ich damit eigentlich nicht zu tun.
wenn du in die DB schreibst, dann ist das Dein job dort richtig reinzuschreiben. Sprich, Du bekommst die Daten von fhem als text und schreibst die dann in der Kodierung in die DB welche die DB benötigt. Woher soll fhem denn wissen welche Kodierung die DB gern hätte? ;) Rückwärts dito, alles was von Außen kommt wird von X nach text gewandelt.
Inzwischen habe ich sämtliche Konvertierungskombinationen beim Schreiben und Lesen durchgetestet - ohne Erfolg.
Bisher hat die Kodierung beim Schreiben und Lesen "einfach so" gepasst, es gab bezüglich Zeichenkodierung noch keine Fehlermeldung hier im Forum.
Warum wird das jetzt alles so viel komplizierter gemacht und absichtlich potenzelle Fehler- und Problemstellen geschaffen?
An einigen Stellen kann ich überhaupt keine Konvertierung einbauen, weil die Mechanismen in configDB durchaus auch dafür vorgesehen sind, binäre Daten (z.B. bei Bilddateien) abzuspeichern. Eigentlich will ich mich einfach darauf verlassen können, dass ich mich um den Sinn und Zweck der Daten, die in der Datenbank landen, überhaupt nicht kümmern muss. Jeder andere Ansatz zerstört die bisher vollständig transparente Implementierung der Konfigurationsdatenbank.
Gar nicht so einfach, dieses Schei... Attribut "encoding" wieder loszuwerden.
Nachdem ich das aber geschafft habe, werde ich mich jetzt erstmal darum kümmern, warum meine mqtt Verbindungen in FHEM nicht mehr funktionieren...
wenn du zickst kann ich dir nicht helfen. Das binäre Daten gespeichert werden können ist absolut in Ordnung. Jeder webbrowser kann sowohl Text mit Sonderzeichen als auch Bilder darstellen. Attribute und Readings sind doch aber wohl text, die gehören passend zum Ausgabekanal kodiert. Wenn Du in der DB keine Unterscheidung durchführst (also alles raw ist), dann muss vor dem schreiben von text nach utf8 konvertiert werden.
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.
Quatsch, das Gegenteil ist der Fall. 600+ Treffer allein nur für "Umlaute". "Darstellungsprobleme" etc kommen noch dazu...
@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.
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)
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.
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.
@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.
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?
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.
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.
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
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.
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.
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.
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.
Ja, ein aktuelles vi (bzw. vim) liest die Datei durch, und stellt automatisch ein Encoding ein.
Besonders lustig bei Dateien mit gemischten Encoding, wie bei einem FHEM Logfile, was Umlaeute enthaelt vor und nach Umstellen des encoding Attributes. Ich bin auch staendig mit xxd unterwegs, um den eigentlichen Inhalt festzustellen.
Damit node latin1 als Befehlsinput akzeptiert, muesste man per Kommandozeile oder Befehl das Encoding parametirisieren, ala "encoding latin1" in FHEM telnet. Ich habe aber nichts Vergleichbares gefunden.
Zitat von: rudolfkoenig am 20 Februar 2022, 19:39:28
diese Aufgabe wird dem Benutzer (bzw. attrTemplate) ueberlassen. Ich habe meinen Zweifel, dass das weniger Support bedeutet.
...
Sowas kann ich aber nicht dem durchschnittlichen FHEM-Benutzer ueberlassen, noch dazu, dass das bisher nicht notwendig war.
Protokollerklärung: Es soll durchaus Anwender geben, die MQTT2 verwenden, aber nicht mit attrTemplate arbeiten, weil dabei auch nicht immer zwingend die Ergebnisse rauskommen, die man als Anwender haben möchte.
Zitatden satz verstehe ich nicht.
Ich meinte JSON.parse nimmt kein UTF-8 bytestream (aka Buffer, das was bei MQTT als payload ankommt), sondern ein Javascript String. D.h. wenn man im Node ueber MQTT JSON empfaengt, dann muss man vor dem Aufruf von JSON.parse() die Daten mit buffer.toString('utf8') oder Vergleichbares explizit konvertieren.
Diesen Schritt will ich dem FHEM-Benutzer nicht aufzwingen.
JSON:PP #111
sub decode_json { # decode
($JSON ||= __PACKAGE__->new->utf8)->decode(@_);
}
JSON:PP #729
if ( $utf8 ) {
$encoding = _detect_utf_encoding($text);
if ($encoding ne 'UTF-8' and $encoding ne 'unknown') {
require Encode;
Encode::from_to($text, $encoding, 'utf-8');
} else {
utf8::downgrade( $text, 1 ) or Carp::croak("Wide character in subroutine entry");
}
}
else {
utf8::upgrade( $text );
utf8::encode( $text );
}
Die professionellen JSON Decoder können das. Kein user muss da was tun. Bitte nimm doch das $lval = Encode::encode('UTF-8', $val); wieder raus. Wichtig ist, dass json2nameValue das konvertieren richtig macht.
ZitatDie professionellen JSON Decoder können das.
Dann bin ich sicher, dass sie auch mit Unicode umgehen koennen, nicht nur mit Bytestreams.
Ich habe jetzt fuer beide MQTT2 IO-Module das Attribut binaryTopicRegexp eingefuehrt, damit kann man Ausnahmen definieren.
es fällt mir schwer angesichts der Ignoranz den Fakten gegenüber neutral zu sein: Du hast gesagt das eine Umstellung problematisch ist, und ich sehe Du findest Wege genau diesen Zustand zielsicher aktiv herbeizuführen.
Unter dem Vorwand der user würde nicht wissen welche Daten mqtt bringt führst Du ein Attribut ein wo er das einstellen muss. Btw, ich habe eine deutlich bessere Meinung über die Benutzer. Unter dem Vorwand "weniger Supportaufwand" machst Du genau das Gegenteil: ab jetzt muss man den user also im Fehlerfall fragen ob das attribut gesetzt ist, falls ja wie. Nebenbei bemerkt, alles irrelevant denn auf mqtt Values gabs (bisher) kaum Probleme. Jetzt schon.
Der ursprüngliche Post hier, ist als Hilfe für Modulautoren gedacht.
Das "save" bei Attributwechsel hängt tatsächlich davon ab ob man autosave=1 gesetzt hat.
Mehrzeile Attribute funktionieren jetzt.
Für meine Konfiguration gibt es eigentlich nur noch zwei Blocking Points:
1. HTTPSRV macht Binärdateien kaputt (z.B. Icons, JPGs)
2. UPD bricht ab sobald ein Modul mit Sonderzeichen dabei ist, weil die Prüfung der Länge fehlschlägt, zum Beispiel:
UPD FHEM/37_echodevice.pm
Got 252067 bytes for FHEM/37_echodevice.pm, expected 252243
Zitat von: herrmannj am 10 Februar 2022, 18:57:11
ich wollte dir nicht zu Nahe treten, das war kein Vorwurf. Du bist gerade dass Beispiel dass man unicode Support benötigt und es keinesfalls nur darum geht ob ein smiley 1 oder 4 Zeichen lang ist. Der mangelnde support im framework ist das Problem. Zu Deiner Frage: es gibt keine einfache Antwort. Solange fhem das nicht unterstützt kannst Du die Workarounds nicht beseitigen sondern musst immer mehr davon einbauen.
Hatte ich auch nicht als solchen aufgefasst, und ich habe auch keine allzugroßen Probleme damit, den "DAM" zu mimen, anscheinend bin ich mit den Verständnisproblemen ja nicht alleine...
Zwei Anmerkungen vom DAM:
- Ihr habt mich weiter ziemlich verwirrt zurückgelassen; nachdem ich verstanden zu haben glaubte, dass es sinnvoll ist, die in meinen Fällen relevanten JSON-Daten einfach ohne Änderung des encodings durchzuschleusen (so ist der aktuelle RHASSPY-Code jetzt auch gestrickt), muss man jetzt die neue globale Variable beachten und wenn ja, doch was umcoden. OK, vermutlich halbwegs "gefressen", auch wenn mir das jetzt unnötig kompliziert vorkommt...
- Was attrTemplate angeht, sprechen wir doch vorrangig von mqtt2.template. Auch wenn es lästig sein wird, ggf. irgendwas auf "Einzeldevice-Ebene" zu fixen: Lieber eine Lösung, die "richtig" ist und ggf. eine 2. Variante von json2nameValue() braucht oder irgendwelche Fallunterscheidungen, wie ewige Flickschusterei. Im Zweifel werden sich kompetente User finden, die die notwendigen Fixes beisteuern, im Zweifel ist das eine harte Hauruck-Aktion, aber das bekommen wir notfalls hin...
(OT: Wer Verbesserungsbedarf sieht, kann den gerne im Klartext an passender Stelle benennen. Vieles ist "halt so no wora" und auch aus meiner Sicht nicht unbedingt immer perfekt oder voll "ausentwickelt", und ich finde auch immer mal wieder noch irgendeinen "Klopper" und/oder Dinge, die man heute anders lösen würde (bzw. erst heute anders lösen könnte). Ist halt so... Der Ist- Zustand ist jedenfalls m.E. deutlich besser wie vieles, was mir im Lauf der Zeit zu MQTT-alt an "Lösungen" über den Weg gelaufen ist.)
Zitat von: herrmannj am 21 Februar 2022, 11:50:06
es fällt mir schwer angesichts der Ignoranz den Fakten gegenüber neutral zu sein: Du hast gesagt das eine Umstellung problematisch ist, und ich sehe Du findest Wege genau diesen Zustand zielsicher aktiv herbeizuführen.
Unter dem Vorwand der user würde nicht wissen welche Daten mqtt bringt führst Du ein Attribut ein wo er das einstellen muss.
...
Danke für diesen wertvollen Beitrag! Ich sehe das weitgehend genau so.
Sowohl als user wie auch als developer.
Zitat von: Beta-User am 21 Februar 2022, 13:45:46
anscheinend bin ich mit den Verständnisproblemen ja nicht alleine...
Nein, bist Du nicht.
Zitat von: herrmannj am 20 Februar 2022, 13:59:12
da der TE das file einliest, ist der TE dafür verantwortlich dass die Daten korrekt eingelesen werden. Generell: attr UNICODE setzen. Beim einlesen: wenn die Daten utf8 kodiert sind (hier der fall), als utf8 einlesen (dann wandelt perl selber das in text), oder als binary einlesen und nach dem einlesen von manuell von utf8 nach text umwandeln.
Den wenigen (weniger als eine Handvoll!) Leuten, die sich hier gerade beim Thema Zeichencodierung austoben, ist hoffentlich bewusst, dass es durchaus eine Vielzahl von FHEM Anwendern gibt, die (aus welchen Gründen auch immer, sei es altersbedingt oder weil nicht jeder beruflich mit Programmierung und EDV zu tun hat) mit solch einer Antwort wenig anfangen können?
Es fängt schon damit an:
Zitat von: herrmannj am 20 Februar 2022, 13:59:12
Generell: attr UNICODE setzen.
Der arme Benutzer ist wahrscheinlich jetzt immer noch erfolglos auf der Suche, wo er das genannte Attribut findet.
Es sei denn, er hat inzwischen aufgegeben...
Auch wenn "Cloud" im Moment in aller Munde ist - könnt Ihr bitte mal wieder von Eurer Wolke runterkommen und eine solch tiefgreifende Änderung in FHEM so dokumentieren und kommunizieren, dass auch ein Normaluser versteht, was er künftig tun muss, wenn er beispielsweise irgendwelche Daten, die er per HTTPMOD bekommt, vernünftig angezeigt haben möchte?
FHEM ist nicht (nur) für Entwickler da!
Zitat1. HTTPSRV macht Binärdateien kaputt (z.B. Icons, JPGs)
2. UPD bricht ab sobald ein Modul mit Sonderzeichen dabei ist, weil die Prüfung der Länge fehlschlägt, zum Beispiel:
Ich meine beide Probleme behoben zu haben.
@betateilchen: "encoding unicode" ist fuer mich immer noch EXPERIMENTELL.
Ob das jemals die Voreinstellung wird, wird sich zeigen.
Immerhin gibt es jetzt in meinen Modulen eine Menge Spezialbehandlung und zusaetzlichen Code.
ZitatDanke für diesen wertvollen Beitrag! Ich sehe das weitgehend genau so.
Ich gehe davon aus, dass Ihr den Beitrag nicht verstanden habt.
Die Ausnahmen mit dem binaryTopicRegep Attribut sind fuer Binaerdaten notwendig.
Die Alternative ist die manuelle Konvertierung des MQTT-Payloads durch den Benutzer wenn es nicht binaer ist, was mAn die Mehrzahl der Daten ist.
Wenn die weiterverarbeitende Funktion (wie der professionelle JSON Parser) das Raten der Kodierung uebernimmt, dann sind beide Alternativen gleichwertig.
Zitat von: Benni am 20 Februar 2022, 13:57:36
Jetzt habe ich mal nachgeschaut, wo das "Menü" eigentlich herkommt.
Das kommt bei mir aus dem Css-Attribut vom FHEMWEB-Device, bzw. dem AdditionalCss des, dem FHEMWEB zugeordneten F18 Styles:
div#menu > .col_header:before {
content: "Menü";
}
Dort steht es also nach der Umstellung auf unicode auch falsch drin.
Nach nun erneuter Eingabe des "ü" ist die Anzeige nun wieder korrekt.
Die Falschdarstellung ist nach einem FHEM-Neustart wieder da.
Sobald ich das "ü" über den Link AdditionalCss beim F18-Style wieder manuell korrigiere ist alles i.O. bis zum nächsten Neustart (trotz vorherigem Save!)
Wenn ich die Anpassung am FHEMWEB-Device über das Css-Attribut vornehme, zerhagelt es mir das komplette CSS darin, es gehen sämtliche NewLines verloren, bzw. werden durch irgendein Spezial-Zeichen ersetzt (s. CSS-Auszug im Screenshot)
Die Bearbeitung im Attribut erfolgt dabei übrigens mittels Codemirror (könnte ja relevant sein?)
Edit: Codemirror ist hier wohl eher nicht relevant, denn die Spezialzeichen stehen auch schon im normalen Attribut-Eingabe-Feld, also auch schon vor der eigentlichen Bearbeitung mit Codemirror, bzw. auch dann wenn die Codemirror-Bearbeitung mittels Cancel abgebrochen wird.
Gruß Benni
FHEM-Update funktioniert jetzt bei mir auch nicht mehr:
2022.02.21 20:33:04 1 : Downloading https://fhem.de/fhemupdate/controls_fhem.txt
2022.02.21 20:33:04 1 : UPD ./CHANGED
2022.02.21 20:33:04 1 : Got 377272 bytes for ./CHANGED, expected 377299
2022.02.21 20:33:04 1 : aborting.
gb#
Ich habe ehrlich gesagt komplett den Faden verloren. Keine Ahnung, ob und wenn ja was ich in meinen Modulen ändern muss (oder soll?).
Ich warte also mal ab, ob irgendwann ein kleines Howto für Entwickler und Anwender veröffentlicht wird.
Zitat von: zap am 21 Februar 2022, 20:45:55
Ich warte also mal ab,
Willkommen im Club.
Zum Glück sind im Wartezimmer genug bequeme Sessel vorhanden und Popcorn ist auch genügend da 8)
Die Icons mit HTTPSRV funktionieren jetzt, danke!
Beim Update hakts aber noch (habe jetzt nur FHEMWEB und update vom svn aktualisiert - fehlt noch was?)
Jetzt hab ich noch was mit FTUI gefunden: in <div data-type="calview"> fehlen der Text von Einträgen mit Umlauten.
Das liegt aber wohl irgendwo im FTUI Javascript. In CALVIEW schaut es gut aus
t_003_summary Restmüll
Ganz interessant ist, das ein "set update" auf die CALVIEW device dazu führt, dass die Einträge auftauchen, aber wenn die Seite neu aufgebaut (oder refreshed) wird, die Einträge mit Umlauten verschwinden. Nachdem ja schon geraume Zeit an FTUI3 gebaut wird, wird das wohl keiner mehr fixen....
ZitatBeim Update hakts aber noch (habe jetzt nur FHEMWEB und update vom svn aktualisiert - fehlt noch was?)
Ja, HttpUtils.pm. HttpUtils_NonblockingGet (und die blocking Variante auch) kennt jetzt den Parameter forcedEncoding, wenn das ein Leerstring ist, wird kein Encoding durchgefuehrt, sonst das im HTTP spezifizierte ueberschrieben.
ZitatKeine Ahnung, ob und wenn ja was ich in meinen Modulen ändern muss (oder soll?).
Das sollte aus dem ersten Beitrag dieser Thema ersichtlich sei, und ich habe es bisher auch nur zweimal erklaert.
https://forum.fhem.de/index.php/topic,126088.msg1209560.html#msg1209560
https://forum.fhem.de/index.php/topic,126088.msg1208705.html#msg1208705
Ich versuchs nochmal:
Wenn "attr global encoding unicode" gesetzt (und damit $unicodeEncoding=1) ist, dann gilt:
Alle FHEM-Internen Strings sind Unicode. Darauf muss man beim Einlesen und Rausschreiben der Daten achten, und notfalls passend konvertieren. Zum Konvertieren sollte man die Encode::encode bzw. Encode::decode Routinen nehmen.
ZitatFHEM-Update funktioniert jetzt bei mir auch nicht mehr:
Das habe ich erst gestern Abend gefixt, per FHEM update ist das seit heute verfuegbar.
ZitatSobald ich das "ü" über den Link AdditionalCss beim F18-Style wieder manuell korrigiere ist alles i.O. bis zum nächsten Neustart (trotz vorherigem Save!)
Kann ich nicht nachstellen, weder mit noch ohne CodeMirror.
Kannst Du bitte pruefen, was in fhem.cfg nach einem Save steht?
Steht attr global encoding auf unicode?
Zitat von: rudolfkoenig am 22 Februar 2022, 09:36:29
und ich habe es bisher auch nur zweimal erklaert.
Ich lese das jetzt das dritte Mal und fühle mich weiter als DAM. Vielleicht hilft eine Anzahl konkreterer Beispiele:
RHASSPY nimmt von folgenden Schnittstellen Daten entgegen:
- Usereingaben per Attribut (kann auch Antwortsätze* enthalten)
- Usereingaben per seperater Konfigurationsfile (mögliche Antwortsätze*), eingelesen per FileRead()
- HTTP-Schnittstelle per HttpUtils_NonblockingGet
- MQTT-Schnittstelle, typischerweise über MQTT2_CLIENT-Dispatch
RHASSPY sendet an folgenden Schnittstellen Daten:
- FHEMWEB&Co über list
- HttpUtils_NonblockingGet
- MQTT (IOWrite)
Die Gegenstelle (EDIT: ein externer Serverdienst namens Rhasspy) erwartet - soweit erkennbar - Daten im UTF-8-Format. Dabei kann es sich handeln um:
- Konfigurationsdaten (typischerweise abgeleitet aus den Attributen und der Konfigurationsfile)
- Sätze für die Sprachausgabe (*gebildet aus den oben genannten "Antwortsätzen", die auch nach Auflösung von Variablen "irgendwelche" Infos enthalten können, die z.B. per ReadingsVal() oder InternalVal() abgefragt wurden)
- "technische Parameter" wie die Bezeichnung des Gerätes, an dem die Sprachausgabe erfolgen soll, eine Sitzungs-Kennung usw..
Stellt sich die Frage, an welchen Stellen dann bei "if($unicodeEncoding)" tatsächlich die Abfrage bzw. Konvertierung zu machen ist...
Übersetzt auf obige Aufzählung käme ich jetzt auf folgendes:
ZitatRHASSPY nimmt von folgenden Schnittstellen Daten entgegen:
- Usereingaben per Attribut (kann auch Antwortsätze* enthalten) => Konvertierung erledigt fhem.pl (?), man hat dann "nur" das Problem, dass die Daten dann im "falschen" Format sind (?)
- Usereingaben per seperater Konfigurationsfile (mögliche Antwortsätze*), eingelesen per FileRead() => Konvertierung erforderlich (da File bisher im UTF-8-Format verteilt wurde)
- HTTP-Schnittstelle per HttpUtils_NonblockingGet => erledigt fhem.pl
- MQTT-Schnittstelle, typischerweise über MQTT2_CLIENT-Dispatch = erledigt fhem.pl (was aber nach Auffassung eines Teils der Meinungen hier falsch ist!)
ZitatRHASSPY sendet an folgenden Schnittstellen Daten:
- FHEMWEB&Co über list => erledigt fhem.pl, hat aber uU. Probleme, wenn Daten nicht konvertiert wurden (?)
- HttpUtils_NonblockingGet => konvertiert automatisch nach UTF-8 (?)
- MQTT (IOWrite) => braucht Konvertierung
Anders gesagt: Aktion erforderlich beim Lesen von Dateien und vor MQTT2-IOWrite.
Korrekt?
Zitat von: Beta-User am 22 Februar 2022, 10:54:04
Ich lese das jetzt das dritte Mal und fühle mich weiter als DAM.
Das geht nicht nur Dir so, und ich habe das schon mehr als dreimal gelesen.
Zitat von: rudolfkoenig am 22 Februar 2022, 09:36:29
Ich versuchs nochmal:
Wenn "attr global encoding unicode" gesetzt (und damit $unicodeEncoding=1) ist, dann gilt:
Alle FHEM-Internen Strings sind Unicode. Darauf muss man beim Einlesen und Rausschreiben der Daten achten, und notfalls passend konvertieren.
Damit kann ich immer noch nicht viel anfangen, auch nicht, wenn das noch 5 Mal geschrieben wird.
- was bedeutet "notfalls" im Zusammenhang mit "passend konvertieren"? Welcher Notfall muss da vorliegen?
- was bedeutet "innen" und "aussen" im Zusammenhang mit FHEM?
- wenn ich Daten, deren Herkunft und Bedeutung ich ggf. nicht kenne, aus FHEM "rausschreibe" und exakt die gleichen Daten von der gleichen Stelle wieder "einlese", um sie in FHEM zu verwenden: warum muss ich sie zuerst hin- und dann wieder zurückkonvertieren, damit am Ende der Ursprungszustand wieder existiert?
@Beta-User: wenn dein Modul nur ueber FHEM-Framework Funktionen mit der Aussenwelt kommuniziert (keine syswrite/sysread/etc) dann musst du nichts machen. Die Konvertierung ist Aufgabe denjenigen, die mit der Aussenwelt im direkten Kontakt stehen.
Dem gegenueber steht der Vorschlag, bestimmte Daten (z.Bsp. MQTT-payload) nicht zu konvertieren.
Ich bin gegen diesen Vorschlag, weil damit nicht mehr gesagt werden kann, welche Daten im System als bytestream oder als Unicode vorliegen, und wer genau soll wann konvertieren. Z.Bsp. wenn das JSON vor dem JSON Dekoder mit einer Funktion oder Regexp bearbeitet werden soll.
@betateilchen:
1) "notfalls" heisst, dass dein Modul Daten mit der Aussenwelt austauscht, _UND_ die verwendete Bibliothek keine Konvertierung vornimmt.
2) "innen" ist das, was im FHEM Prozess vorhanden ist, "aussen" ist alles ausserhalb vom FHEM-Prozess (Datei, andere Prozesse, DB, etc)
3) weil man mit "encoding unicode" innen alle Strings als "unicode"(aka Wide-Characters) abgespeichert sind, und solche nicht ohne Weiteres rausschreiben kann, weil sie als Folge von 16-bit (oder 32-bit?) Zahlen gespeichert sind. Diese Daten muss man vorher zum bytestream serialisieren. Z.Bsp. nach iso-8859-1 (aka Latin1), hier wird aus einem Smiley "?" und geht damit verloren. Die Mehrheit verwendet aber UTF-8, damit die Smileys erhalten bleiben :)
Die aktuelle Voreinstellung in FHEM ist "encoding bytestream", damit ist keine Konvertierung notwendig, und auch keine Unterscheidung von innen/aussen, etc. Viele Perl-Bibliotheken bestehen aber auf Unicode, d.h. je mehr Perl-Bibliotheken in FHEM eingesetzt werden, desto problematischer wird das aktuelle Modell. Und dann gibt es das (mAn unbedeutende) Problem von Regexp-Matching mit Umlaut, und Zugriff auf bestimmte Zeichenpositionen (da Zeichen nicht gleich Byte ist)
Zitat von: rudolfkoenig am 22 Februar 2022, 12:26:40
@Beta-User: wenn dein Modul nur ueber FHEM-Framework Funktionen mit der Aussenwelt kommuniziert (keine syswrite/sysread/etc) dann musst du nichts machen.
Danke für diese klare Aussage. Es zahlt sich also aus, wenn man bevorzugt/wenn möglich die "internen" Funktionen nutzt :) , und ansonsten den "sowieso-Tipp" von herrmannj beherzigt, möglichst gar keine Konvertierungen zu versuchen (so hatte ich das zumindest verstanden). Das kann man auch DAM wie mir verklickern...
OT-Anmerkung: Es bedingt aber z.B., dass man mit toJSON() serialisierte Strings nachbearbeiten muss, wenn die Gegenstelle eine "strenge Auffassung" davon hat, wie JSON zu interpretieren ist (und z.B. keine Zahlen oder Wahrheitswerte wie true in Quotes akzeptiert)...
Zitat
Die Konvertierung ist Aufgabe denjenigen, die mit der Aussenwelt im direkten Kontakt stehen.
Dem gegenueber steht der Vorschlag, bestimmte Daten (z.Bsp. MQTT-payload) nicht zu konvertieren.
Ich bin gegen diesen Vorschlag, weil damit nicht mehr gesagt werden kann, welche Daten im System als bytestream oder als Unicode vorliegen, und wer genau soll wann konvertieren. Z.Bsp. wenn das JSON vor dem JSON Dekoder mit einer Funktion oder Regexp bearbeitet werden soll.
Für das konzeptionelle Problem fehlt mir der hinreichende Durchblick über dessen wahres Ausmaß, ich wollte nur neulich nochmal deutlich darauf hingewiesen haben, dass "workarounds" zum "Schutz" von attrTemplate jedenfalls wegen eventuell in meiner Person anfallenden Mehraufwands nicht angezeigt sind. Auch in RHASSPY dürfte das "Problem" überschaubar sein, wenn "unkonvertierte" Daten/Payloads via Dispatch übergeben werden. Ist aber Bauchgefühl...
Update verifiziert. Das geht jetzt.
Gerade versucht ein SVG zu speichern welches Umlaute in den "diagram labels" hatte.
Danach wird das SVG nicht mehr angezeigt:
memGzip: Wide character in memGzip at ./FHEM/01_FHEMWEB.pm line 634.
Manuell die Umlaute mit "vi" wieder hergestellt, dann geht es zumindest wieder, aber man bekommt die hübschen karos mit ? drin statt der Umlaute
Mühsam ernährt sich das Eichhörnchen :)
wenn du das karo mit dem fragezeichen siehst hast du einen latin-1 umlaut ins file gebaut.
das encoding das du im file verwendest muss zur encoding angabe in der ersten zeile deines svg files passen.
Zitat von: justme1968 am 22 Februar 2022, 13:30:22
wenn du das karo mit dem fragezeichen siehst hast du einen latin-1 umlaut ins file gebaut.
das encoding das du im file verwendest muss zur encoding angabe in der ersten zeile deines svg files passen.
War auch nur als Workaround gedacht.
Wobei ich die Fehlermeldung jetzt nicht mehr nachgestellt bekomme, allerdings gebe ich trotzdem Umlaute über den SVG Editor ein (und da stehen sie auch als Umlaute), im Plot jedoch hab die die Fragezeichen - da fehlt also noch irgendeine Umwandlung
ZitatGerade versucht ein SVG zu speichern welches Umlaute in den "diagram labels" hatte.
Habs gefixt.
Ist ein Opfer des HTTPSRV Fixes gewesen :(
ZitatMühsam ernährt sich das Eichhörnchen :)
Habs auch so erwartet.
SVG klappt jetzt (und HTTPSRV funktioniert immer noch).
Beim Anpassen meines Moduls habe ich jetzt den umgekehrten Fall:
Selbst wenn FHEM im bytestream Modus ist, verarbeitete ich intern Unicode - was selten ein Problem ist, außer wenn ich Eingaben von FHEM mit Umlauten bekomme.
Da brauche ich zwei mal ein
$text=decode_utf8($text) if !($unicodeEncoding);
Etwas nerviger ist, dass für mein Logging zu machen um keine "wide character" Warnungen zu bekommen - da habe ich jetzt mal eine alternative zu Log3 implementiert:
sub LogUnicode($$$) {
my ($name,$level,$text) = @_;
$text=encode_utf8($text) if !($unicodeEncoding);
Log3 $name, $level, $text;
}
Könnte man das "encode" nicht generell ins Log3 aufnehmen? Soweit ich das sehe, ist das komplett unschädlich wenn kein Unicode dabei ist, aber hilft jedem der im bytestream Modus "versehentlich" Unicode loggt.
Zitat von: rudolfkoenig am 22 Februar 2022, 09:36:29
Kann ich nicht nachstellen, weder mit noch ohne CodeMirror.
Kannst Du bitte pruefen, was in fhem.cfg nach einem Save steht?
Steht attr global encoding auf unicode?
Wie gesagt, die Verwendung von CodeMirror sollte auch nach meiner Prüfung dafür unerheblich sein, hatte ich ja auch so geschrieben.
Ja encoding war zu dem Zeitpunkt auf unicode eingestellt.
Eine Prüfung auf das, was in fhem.cfg gespeichert wird, kann ich derzeit leider nicht mehr durchführen, ich habe das encoding-Attribut bei mir wieder entfernt, außerdem habe ich auch auf dem Testsystem configDB im Einsatz, mal sehen ob ich heute Abend in der DB selbst noch schauen kann, was dort in einer älteren Config-Version in die DB geschrieben wurde.
gb#
ZitatSoweit ich das sehe, ist das komplett unschädlich wenn kein Unicode dabei ist, aber hilft jedem der im bytestream Modus "versehentlich" Unicode loggt
Unschaedlich ist Ansichstsache.
Ein doppeltes "Encode::encode" Aufruf kann Daten kaputtmachen, das habe ich in FHEMWEB schon festgestellt.
Mir ist lieber, dass ein falsches Encoding durch Fehlermeldungen auffaellt, als dass man nie sicher ist, was man hat.
Zitat von: rudolfkoenig am 22 Februar 2022, 12:26:40
@Beta-User: wenn dein Modul nur ueber FHEM-Framework Funktionen mit der Aussenwelt kommuniziert (keine syswrite/sysread/etc) dann musst du nichts machen. Die Konvertierung ist Aufgabe denjenigen, die mit der Aussenwelt im direkten Kontakt stehen.
Gewonnen! Meine Module lesen und schreiben per Socket-Schnittstelle (sysread, syswrite) und verwenden RPC::XML, was sich vermutlich auch nicht um den Zeichensatz schert.
Es bleibt spannend.
Zitat von: zap am 23 Februar 2022, 19:19:24
Es bleibt spannend.
Für HMCCU & Co kann ich dich beruhigen. Hab schon gut eine Woche umgestellt und kann bisher keine Probleme erkennen. Selbst ein Device mit Umlaut im Namen schaut korrekt aus.
Ich versteh ja nur 75% von Eurer Diskussion. :-[ Und hab natürlich genau dieses Problem. Obwohl ich noch nicht einmal die Hardware besitze. :'(
Hier mein FHEM-Log
############# das Logging findet in meinem logischen Modul statt
2021.11.11 00:20:33 5: DLNAController: process property LastChange, xml-event <Event xmlns=....<dc:title>Die Ärzte : NEU: Noise</dc:title> .....
############# Ich jage die message durch den parser XML::LibXML->load_xml...
2021.11.11 00:20:33 4: DLNAController: parsing did enter load_xml call: <Event xmlns=....<dc:title>Die Ärzte : NEU: Noise</dc:title>......
2021.11.11 00:20:33 4: DLNAController: dom structure: <?xml version="1.0"?>
<Event xmlns=....
<dc:title>Die Ärzte : NEU: Noise</dc:title>
2021.11.11 00:20:33 4: DLNAController: LastChange xml event with root <Event xmlns=...<dc:title>Die Ärzte : NEU: Noise</dc:title>.....
2021.11.11 00:20:33 5: DLNAController: node ...<dc:title>Die Ärzte : NEU: Noise</dc:title>...
2021.11.11 00:20:33 4: DLNAController: node ...<dc:title>Die Ärzte : NEU: Noise</dc:title>.....
############# nun mache ich ein decode_entities(....); Und (immerhin) nur noch 1 Zeichen
2021.11.11 00:20:33 4: DLNAController: parsing did enter metadata: <?xml version="1.0"?> ...<dc:title>Die �rzte : NEU: Noise</dc:title>...
############# und den parser-Aufruf $dom = XML::LibXML->load_xml... und ein Wunder: das Ä ist da
2021.11.11 00:20:33 4: DLNAController: process metadata <?xml version="1.0"?>
...<dc:title>Die Ärzte : NEU: Noise</dc:title>
############# und mit dem Funktions-Aufruf $dom->documentElement() ist das Ä auch schon wieder weg
2021.11.11 00:20:33 5: DLNAController: root ...<dc:title>Die �rzte : NEU: Noise</dc:title>...
2021.11.11 00:20:33 5: DLNAController: node <dc:title>Die �rzte : NEU: Noise</dc:title>, node-name: dc:title node-type: 1 node value: aber text: Die �rzte : NEU: Noise
Ist da jetzt was im Parser falsch ? Oder hätte ich irgendwo etwas anderes tun müssen ? Oder sonst was falsch gemacht ? (XML::LibXML kennen vermutlich nicht viele)
Grüße Markus
Ich gehe davon aus, dass
- bei dem vorherigen Log "attr global encoding unicode" gesetzt war
- dein Modul ohne dieses Attribut mit Ulauten umgehen kann.
Wenn ja, dann muss man hier die
Zitat$buf = Encode::decode('UTF-8', $buf) if($unicodeEncoding);
Zeile vor dem Uebernehmen der Daten in die FHEM-Variablen (bzw. FHEM-Framework-Funktionsufrufen) durchfuehren.
Hi Rudi,
danke fürs Feedback.
ZitatIch gehe davon aus, dass
- bei dem vorherigen Log "attr global encoding unicode" gesetzt war
Nein, das gehört zu den nicht verstandenen 30%. :-[ ;D
Ist das
Zitat- dein Modul ohne dieses Attribut mit Ulauten umgehen kann.
jetzt alternativ gemeint oder besteht wie geschrieben ein Zusammenhang ?
Wichtig: Das Log ist ja schon recht alt. Macht es Sinn den User mal zu bitten mit einem aktuellen FHEM und mal mit und mal ohne Attribut ein Log zur Verfügung zu stellen ?
Grüße Markus
ZitatNein, das gehört zu den nicht verstandenen 30%
Wenn Du Glueck hast, dann kann _dieses_ Problem mit "attr global encoding unicode" geloest werden, weil die Bibliothek automatisch unicode macht, und die Konvertierung zu dem FHEM-Standard utf-8 bytestream nicht durchgefuehrt wurde.
Ansonsten wird es kompliziert, und sollte nicht in diesem Thema diskutiert werden.
Aber bitte nur nach einem FHEM-update und erneuten Tests.
Zitat von: Adimarantis am 23 Februar 2022, 20:43:27
Für HMCCU & Co kann ich dich beruhigen. Hab schon gut eine Woche umgestellt und kann bisher keine Probleme erkennen. Selbst ein Device mit Umlaut im Namen schaut korrekt aus.
Erstaunlich. Eigentlich müsste die CCU und ihre Schnittstellen iso-8859-1 verwenden. Ich hatte verstanden, dass in diesem Fall das Modul die Daten nach UTF-8 konvertieren muss.
Mit der plotAsPng() Funktion habe ich noch den Effekt, dass bei encoding=unicode alle Linien (und deren Legende) in schwarz dargestellt werden. Davon abgesehen schauen die pngs ok aus.
Die normale Darstellung in FHEMWEB ist nicht betroffen.
Bist du ganz sicher, dass das an dem unicode Wert liegt?
Erstens sollten SVG-Farben wenig mit Sonderzeichen zu tun haben, zweitens gibt es ein bekanntes Problem, mit dem gleichen Symptom: https://forum.fhem.de/index.php?topic=116138
Du hast recht. Das Phänomen tauchte zwar auffällig zeitnah mit der Umstellung nach unicode auf, aber lasst sich durch das Attribut plotAsPngFix beheben. Muss wohl ein libsvg update unter Raspberry "buster" gewesen sein (librsvg-2.so.2.44.10) auf meinem "bytestream"-Testsystem unter "bullseye" funktioniert es auch ohne fix-attribut (librsvg-2.so.2.47.0)
@Rudi: Da ich nicht weiss ob du in dem Riesen FTUI3 Thread mitliest:
https://forum.fhem.de/index.php/topic,115259.msg1245354.html#msg1245354
Da geht es darum, dass JsonList2 im unicode Modus "<BINARY>" liefert wenn FTUI Strings mit Umlauten in Readings anfordert.
Danke fuer den Hinweis, habs gefixt.