ich fange mal einen eigenen thread an um nicht hier Link (http://forum.fhem.de/index.php?topic=14106.msg88769#msg88769) weiter off topic zu bleiben.
- was das html encoding angeht hast du recht. ich war verwirrt weil mein safari es tatsächlich trotz charset=utf8 manchmal falsch macht und ich an der falschen stelle danach gesucht hatte (in der seite statt im header)
- für die console bzw telnet ist es aber noch nicht gelöst.
du schreibst du hast viele negative erfahrungen damit gemacht. für die anwender ist es aber eine mindestens genau so schlechte erfahrung wenn es in der console falsch dargestellt wird und es noch nicht mal die möglichkeit gib es richtig zu machen.
vielleicht wäre folgendes vorgehen hilfreicht es doch ein wenig besser in den griff zu bekommen:
- festlegen das alle ausgaben und user sichtbare texte eines devices utf8 sein sollen
- ein $hash->{Encoding} einführen das alle neuen module auf UTF-8 setzen müssen. module bei denen das nicht gesetzt ist gelten rückwärtskompatibel als latin1
- die beiden latin1_2_utf8 und utf8_to_latin1 von betateilchen in 99_Utils.pm bereitstellen (die sollten im gegensatz zu den perl Encoding funktionen auch auf fritzboxen funktionieren).
- attribut für telnet um das (client) encoding anzugeben
- kommando um in einer telnet session das encoding zwischen beidem umzuschalten
- für beides zunächst nur utf8 und latin1 erlauben
- zunächst beschränkung der automatischen konvertierung auf die ausgaben eines moduls aus der SetFn und GetFn
- die ausgaben der SetFn und GetFn mit den beiden obigen funktionen konvertiern wenn das telnet encoding nicht zum device encoding passt.
Ich bin einverstaden damit, das alles in FHEM als UTF-8 gespeichert bzw. nach aussen gegeben wird, FHEMWEB verlaesst sich auch jetzt schon darauf.
Die beiden Konvertier-Routinen werde ich in fhem.pl aufnehmen falls einer der Module mit einer latin1 Quelle kommunizieren muss und die Quelle nicht auf UTF-8 schaltbar ist. Dazu moege sich bitte der Modul-Autor melden.
Ein telnet-Attribut bzw. fallabhaengige Konvertierung sehe ich nicht: wenn man ein telnet client mit FHEM verbindet UND Wert auf korrekte Darstellung von Umlauten legt, dann muss man im Terminal-Fenster UTF-8 einstellen.
Es ist nicht FHEMs Aufgabe Character-sets zu konvertieren, sondern die der Anzeige-Programme (Browser/telnet-Fenster/etc), alles was von FHEM kommt ist UTF-8.
Konvertieren ist auf den ersten Blick leicht, wird aber kompliziert, wenn weitere Teilnehmer (wie z.Bsp. Datenbanken) auf die gleiche Idee kommen. Wenn dann nicht ganz klar ist, wer was wie speichert, kommt ein Durcheinander zustande.
das konvertieren ist ganz leicht. auch in verbindung mit datenbanken und beliebig vielen beteiligten. vorausgesetzt es wird eine einzige regel eingehalten: es muss zu jeder zeit und an jeder stelle ganz klar sein in welchem encoding ein text gerade ist.
die eigentliche schwierigkeit ist nicht das konvertieren sondern die information über das encoding konsequent überall mit zu schleifen und nicht aus versehen an irgend einer stelle eine annahme zu treffen die nicht stimmt. das client encoding für das telnet interface konfigurierbar zu machen würde genau das erlauben.
ich würde schon sehen das es eben genau aufgabe des jeweiligen ausgabe moduls ist dafür zu sorgen das das encoding stimmt. beim fhemweb ist das kein problem weil das protokoll das schon vorsieht. bei telnet gibt es genau diese möglihkeit das der server dem client das encoding der daten mitteilt aber leider nicht und es kracht dann eben genau deshalb weil jede seite der meinung ist es ist eigentlich aufgabe der anderen statt einzusehen das beide seiten zusammen etwas dafür tun müssen das es reibungslos geht.
gerade beim telnet client denke ich (ganz wirklich ohne den aufwand zu unterschätzen) das es relativ einfach möglich ist das problem zu lösen wenn eindeutig festgelegt ist was von der fhem seite kommt.
ich bin auch gerne bereit dafür patches zu liefern. aber das macht natürlich keinen sinn ohne dein ok :)
edit: es gibt sogar ein rfc (http://tools.ietf.org/html/rfc2066 (//tools.ietf.org/html/rfc2066)) für telnet und encoding. scheinbar hat das niemals jemand umgesetzt...
Zitat von: rudolfkoenig schrieb am Mo, 05 August 2013 13:04Die beiden Konvertier-Routinen werde ich in fhem.pl aufnehmen falls einer der Module mit einer latin1 Quelle kommunizieren muss und die Quelle nicht auf UTF-8 schaltbar ist. Dazu moege sich bitte der Modul-Autor melden.
Also ich brauche diese Konvertierungsroutinen in meinem derzeit entstehenden 55_GDS und Boris nutzt latin1_to_utf8() in 59_Weather.
Man sollte auf jeden Fall auf eine eindeutige Benennung der beiden Funktionen achten. Ich verwende derzeite <sourceCharset>_2_<targetCharset> und Boris <sourceCharset>_to_<targetCharset>
Wenn die Funktionen in
fhem.pl integriert sind, brauchen wir sie beide nicht mehr in unseren Modulen.
ich habe ein wenig mit dem encoding im telnet modul gespielt und für die ausgabe richtung funktioniert es ohne probleme wenn man vor dem syswirte an den client $ret ein mal durch utf8_2_latin1 schickt wenn der client latin1 möchte.
ich glaube also immer noch das es ein sehr kleiner patch an genau einer definierten schnittstelle von und zu fhem wäre.
> Wenn die Funktionen in fhem.pl integriert sind, brauchen wir sie beide nicht mehr in unseren Modulen.
Ich habe die Funktion aus 59_Weather.pm als latin1ToUtf8 in fhem.pl uebernommen, da wenn ich mich recht erinnere, irgendwo wir uns mal auf diese Schreibweise geeinigt haben.
> ich glaube also immer noch das es ein sehr kleiner patch an genau einer definierten schnittstelle von und zu fhem wäre.
Na gut, ich ergebe mich. Bevor ich unglueckliche Mitstreiter habe... :)
Zitat von: rudolfkoenig schrieb am Di, 06 August 2013 09:22Ich habe die Funktion aus 59_Weather.pm als latin1ToUtf8 in fhem.pl uebernommen, da wenn ich mich recht erinnere, irgendwo wir uns mal auf diese Schreibweise geeinigt haben.
Hallo Rudi,
könntest Du das Gegenstück utf8ToLatin1 bitte auch noch aufnehmen?
sub
utf8ToLatin1($)
{
# http://perldoc.perl.org/perluniintro.html, UNICODE IN OLDER PERLS
my ($s)= @_;
$s =~ s/([\xC2\xC3])([\x80-\xBF])/chr(ord($1)<<6&0xC0|ord($2)&0x3F)/eg;
return $s;
}
Danke & viele Grüße
Udo
eingecheckt.
ZitatNa gut, ich ergebe mich. Bevor ich unglueckliche Mitstreiter habe... :)
und ich hatte gehofft du sagst ja weil du siehst das es sinnvoll ist :)
hier ein vorschlag für einen patch der das encoding bei der ausgabe für telnet konfigurierbar macht.
- ein attribut encoding mit den möglichen werten utf8 und latin1. der default ist utf8.
- wenn das encoding auf latin1 gestellt ist wird utf8ToLatin1 vor dem senden der daten an den client aufgerufen
- ein 'encoding' kommando um das encoding zur laufzeit abzufragen und zu setzen.
das attribut habe ich schon dokumentiert. das kommando noch nicht.ich wusste zum einen nicht so recht wo und zum anderen nicht ob dir der teil auch noch gefällt :)
das das 'encoding' kommando nicht an fhem durchgereicht wird sondern direkt im telnet modul behandelt wird könnte man es noch mit einem prefix (z.b. einem doppelpunkt oder semikolon) versehen um es von 'normalen' fhem kommandos zu unterscheiden. aber wenn es das einzige meta kommando bleibt ist das vielleicht auch zu viel des guten.
die eingabe habe ich mir nicht weiter angeschaut.
gruss
andre
Nach denken und Irrlaeufen:
Ich meinte zunaechst, dass man Attribute nicht mit speziellen Kommandos setzen und anzeigen sollte, sondern mit allgemeinen FHEM-internen, und habe deswegen das bisher fehlende displayattr in fhem.pl eingebaut und eingecheckt.
Erst danach ist es mir aufgefallen, dass wenn man per telnet sich verbunden hat, keine Ahnung hat, ueber welche Server-Verbindung man reingekommen ist, weiterhin kann man schlecht temporaer nur fuer die aktuele Verbindung das encoding aendern, man benoetig also doch sowas wie dein encoding Befehl.
Eigentlich traegt man Befehle in die globale %cmds ein (siehe 98_XmlList.pm), damit diese in help angezeigt werden, und von ueberall aufgerufen werden koennen. Das Aufrufen von ueberall (z.Bsp aus FHEMWEB) ist in diesem Fall nicht erwuenscht, das kann man aber pruefen: der erste Parameter einer CommandEncoding Funktion ist der hash der telnet-Verbindung.
-> Kannst Du bitte encoding auf diese Weise umbauen, damit es kein shortcut bzw. Sonderweg ist?
Weiterhin fehlt noch die Konvertierung beim input.
ja. genau. es global zu machen funktioniert in diesem fall nicht. es ist wirklich verbindungsspezifisch.
natürlich kann ich das auf %cmds umbauen finde es aber eigentlich nicht so schön wenn das kommando auch im web auftaucht und dort gar keinen sinn macht. das fand ich auch bei exit und quit schon nicht schön. inform ist glaube ich noch ein kandidat der im web nicht sinnvoll ist.
was würdest du davon halten wenn man in dem commando hash für %cmds optional angeben kann das ein kommando nur beim aufruf aus einem bestimmten clientmodul heraus sinnvoll ist? z.b. in dem man zusätzlich zu Fn und Hlp noch Client setzen kann. dann könnte man ein Kommando z.b. auch bei help ausblenden wenn es nicht matched.
beim input bin ich noch dabei zu schauen wie es genau geht. der erste schritt dazu ist die verbindung auf binär zu stellen. das hat aber beim ersten versuch noch den seiteneffekt gehabt das die zeilenenden nicht mehr gepasst haben.
da man zur zeit über die telnet verbindung aber sowieso weder latin1 noch utf8 sondern nur ascii eingeben kann würde ich das dann in einem zweiten patch nur für die eingabe nach meinem urlaub machen. vorher schaffe ich das nicht mehr.
hier der gleiche patch mit verwendung von %cmds.
input kommt erst nach meinem urlaub.
Eingecheckt.
Hab zusaetzlich dein Vorschlag als ClientFilter eingebaut, damit ist exit/quit/inform aus FHEMWEB nicht mehr ausfuehrbar.
ich nehme es zurück. hier ist doch schon eine version mit input.
das ganze funktioniert in dem fhem den telnet client auffordert in den binär modus zu schalten. die gegenrichtung wird ignoriert. erst wenn man auch die gegenrichtung umschaltet stimmen die zeilenenden nicht mehr.
getestet z.b. mit:
set gds warnlage Baden-Württemberg
oderdefine dummy dummy
attr dummy room Büro
beides wäre vorher nicht gegangen. weder mit dem default utf8 noch mit latin1. jetzt geht es mit beidem.
gruss
andre
ach ja: ich habe es von linux und mac os x aus getestet. was anderes habe ich nicht zur verfügung.
edit: lach. so schnell und doch zu langsam :)
und noch mal nur die input seite als sauberen patch gegen die aktuelle version.
Dieser patch ist aber noch nicht ganz ok, nach connect muss ich zweimal return tippen, um zu meinem Prompt zu kommen. Habs erstmal nicht eingecheckt.
Das Problem hat hier vermutlich damit zu tun, dass telnet.pm im Normalfall kein Telnet Protokoll spricht, sondern nur einen dummen socket anbietet.
Erst beim gesetzten Passwort faengt telnet.pm an telnet Escape-Sequenzen zu versenden, um das Echo abzuschalten.
ich verwende telnet immer ohne prompt weil der beim copy und paste ziemlich im weg ist und war schon drauf und dran einen patch zu bauen den prompt abzuschalten.
das man jetzt zwei mal return drücken muss statt ein mal ist mir noch gar nicht aufgefallen.
es hat tatsächlich mit den iac sequenzen zu tun. aber nicht damit das es zu wenig sind sondern eine mehr als vorher. fhem sendet ja jetzt am anfang dem client das er auf binär umschalten muss. dafür sendet der client am anfang eine bestätigung. da fhem das telnet im line mode betreibt wird die bestätigung von client an fhem mit dem ersten return gesendet. d.h. d.h. das erste return sendet nicht wirklich eine leere nachricht sondern enthält die unsichtbare bestätigung.
wenn du die drei zeilen if( $cmd =~ s/\xff(\xfb|\xfd)(.)// ) {
#syswrite($hash->{CD}, sprintf("%c%c%c", 255, (ord($1)==253?251:253), ord($2)));
}
die in meinem patch vor dem latin1ToUtf8 stehen etwas weiter nach vorne genau zwischen $gotCmd = 1;
if($cmd) {
schiebst müsste es wieder passen mit dem prompt nach dem ersten return.
edit: und als patch.
> ... müsste es wieder passen mit dem prompt nach dem ersten return.
Stimmt, obwohl ich es noch nicht verstehe wieso.
Beim analysieren ist mir aber aufgefallen, dass ich in diesem Form das encoding patch (noch) nicht akzeptieren kann, und habe es deswegen erstmal komplett entfernt.
Grund: telnet.pm sendet mit dem encoding Patch direkt nach dem connect ein Telnet-Kommando (==Escape-Sequenz) um auf Binaer zu schalten, und dies wird etliche Clients (FHEM2FHEM, manche mobile Frontends, fhem.pl im client mode) verwirren.
Ich gebe zu, das ist (teilweise) auf meinem Mist gewachsen, da ich die einfache Socket Verbindung telnet genannt habe, ist aber nunmal so. Bisher hat telnet nur dann Escape-Sequenzen verschickt, wenn Passwort aktiviert war, was auch nicht konsequent ist.
Folgendes ist mein Vorschlag, vielleicht hast du aber was besseres:
- ein Attribut, was gesetzt sein muss, um einem telnet Instanz zu erlauben, telnet-Befehle zu schicken, dieses Attribut wird mit passwort automatisch aktiviert. Was default sein soll, ist mir noch nicht klar.
- FHEM2FHEM bzw. "fhem.pl in client-mode" muss das parsen von escape Sequenzen beigebracht werden, und damit zusammen auch das verstehen/senden von Passwoertern. Sinnvoll waere auch die Unterstuetzung von SSL.
Kommt auf meine TODO Liste, wird aber ein bisschen dauern.
ich denke es ist schade die encoding patches wieder raus zu nehmen:
- der patch für die ausgabe verwendet keine iac kommandos und ändert auch am verhalten nichts so lange nicht per attribut oder kommando auf latin1 geschaltet wird. d.h es sind mit keinem client probleme zu erwarten.
- der patch für die eingabe sendet ein iac kommando an den client. die iac kommandos sind seit etwa 30 jahren standardisiert. es sollte auf der welt keinen telnet client geben der sie nicht unterstützt (im schlimmsten fall ignoriert). auch hier sollten keine probleme mit dem client zu erwarten sein.
ich würde die encoding geschichten auch ungern an das password knüpfen. beides hat nicht wirklich etwas miteinander zu tun ausser das für das password auch iac sequenzen verwendet werden (wenn auch andere: um das echo zu unterdrücken)
die iac sequenz für den binary mode sollte im übrigen nicht mehr probleme machen als die für das password. wenn ein client das eine kann kann er auch das andere. das schlimmste ist das er antwortet er untersütz binary nicht. dann geht halt die eingabe von umlauten nicht.
mein vorschlag:
- den ausgabe patch unverändert drin zu lassen. er sendet keine iac kommandos und wird jetzt schon erst dann aktiv wenn man das encoding explizit setzt.
- den eingabe patch so abändern das das iac kommando für binary nur dann gesendet wird wenn das encoding attribut überhaupt gesetzt ist oder wenn das encoding kommando verwendet wird. damit wäre auch die eingabe rückwärtskompatibel so lange man das encoding nicht verwendet.
ich filtere die iac kommandos für binary und die antwort darauf jetzt schon raus. damit sollte fhem2fhem direkt schon gehen. mit der obigen änderung aber auf jeden fall.
auf die todo list würde ich dann das 'richtige' iac handling sezten und vor allem einen character mode für telnet damit man z.b. mit den cursor tasten in der history zurück gehen kann und eine zeile editieren kann.
die passwörter sind eigentlich ganz normale in band daten. die iac kommandos nicht. der zusammenhang ist nur das echo abschalten. das wäre bei fhem2fhem fast egal.
ssl könnte man auch komplett ausserhalb sehen wenn man direkt ein IO::Socket::SSL verwendet.
edit: es gibt zwar einen standard um tls innerhalb der telnet session zu starten (so wie es für imap auch zwei versionen gibt - direkt auf einem ssl soket oder mit start tls). das unterstützt aber tatsächlich fast kein client weil der standart noch relativ 'neu' ist und es zu der zeit schon ssh gab das telnet im prinzip völlig verdrängt hat.
der vorschlag von oben als patch. so lange nicht das encoding per attribut oder kommando gesetzt wird ist alles beim komplett beim alten.
ich kann mir zwar keinen client vorstellen der mit dem binary mode probleme hat. aber wenn du ganz sicher gehen willst würde es so gehen.
Ich will vor dem Anwenden dieser Patch wenigstens FHEM2FHEM und fhem.pl anpassen, damit beim gesetzten Attribut diese beiden keine Probleme bekommen.
meiner meinung nach gehört jede anpassung in das telnet modul. es sollte für sender und empfänger transparent sein.
für den fall ohne passwort sollte das schon so sein. das iac do binary das die server seite sendet wird von der client seite gelesen und verworfen.
da das password handling eine art sonderfall ist muss man das gleiche da eventuell noch mal tun.
Habs (wieder) eingespielt.
fhem.pl in Kommando-Mode kann es inzwischen filtern (genauso wie die Passwort-Zeile), FHEMWEB & Blocking.pm muesste noch angepasst werden, aber damit warte ich solange, bis es jemanden stoert :)
sehr schön. ich hatte es schon sehr vermisst. und inzwischen die eingabe sogar noch mehr als die ausgabe.
kann man eigentlich ein list auf einen raum machen?
list room=XY
Siehe http://fhem.de/commandref.html#devspec (//fhem.de/commandref.html#devspec)