FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: jannis am 05 Dezember 2020, 16:02:31

Titel: elegante Lösung für Sonderzeichen, um Devicestatus per Perl zu setzen
Beitrag von: jannis am 05 Dezember 2020, 16:02:31
Mein Ziel: Ich möchte beliebige Zeichen per Perl in den Status meines Devices eintragen. Zum Testen habe ich ein Device:
Zitatdefmod testdevice dummy

... eine Funktion, die ich in 99_myUtils.pm einfüge:
sub setzeTestdevice($) {
  my ($meldung) = @_;
  fhem("set testdevice $meldung");
}


Und dann rufe ich in der fhem-Kommandozeile auf:
{setzeTestdevice("Sonderzeichen ,.'#:;§$%&/ und was passiert hier: hier bei der Ausgabe?")}

Und dann kommen Fehlermeldungen wie:
Unknown command {setzeTestdevice(

Klar, die Sonderzeichen sorgen für Irritation.
Ich habe schon zum Teil erfolgreich versucht mit Perlersetzungen ala
$meldung=~s/:/\:/g
die Probleme in der Ausgabe zu beheben und habe immer mehr Ersetzungen eingefügt. Aber das kann es ja nicht sein und der fhem-Weg ist bestimmt wieder mal viel einfacher: Wie geht's?
Titel: Antw:elegante Lösung für Sonderzeichen, um Status im Device per Perl zu setzen
Beitrag von: amenomade am 05 Dezember 2020, 18:06:33
Minimum: Semikolon verdoppeln. Das reicht aber nicht. Dein einziges Problem ist aber das Semikolon (das als Kommando-Trennzeichen interpretiert wird)

EDIT: das Semikolon muss viermal, da zwei Ebenen von Kommandos:

{setzeTestdevice("Sonderzeichen ,.'#:;;;;§$%&/ und was passiert hier: hier bei der Ausgabe?")}
Titel: Antw:elegante Lösung für Sonderzeichen, um Status im Device per Perl zu setzen
Beitrag von: Otto123 am 05 Dezember 2020, 18:57:56
Aber das hier geht doch nicht:
Zitat("Sonderzeichen ,.'#$%&/ und was passiert hier: hier bei der Ausgabe?")
Innerhalb von " wird doch aufgelöst/evaluiert da muss jedes $ als \$ stehen und ein einzelne ' gehen gar nicht!

was ist mit q(Sonderzeichen ,.'#:;;;;§$%&/ und was passiert hier: hier bei der Ausgabe?) ?

Funktioniert bei mir
{fhem('set w1 '.q(Sonderzeichen ,.'#:;;;;§$%&/ und was passiert hier: hier bei der Ausgabe?))}

Edit: ; bleibt ein Problem ;)
Titel: Antw:elegante Lösung für Sonderzeichen, um Status im Device per Perl zu setzen
Beitrag von: amenomade am 05 Dezember 2020, 19:10:29
{setzeTestdevice("Sonderzeichen ,.'#:;;;;§$%&/ und was passiert hier: hier bei der Ausgabe?")}
funktioniert auch mit der sub, wie er sie geschrieben hat ;)

EDIT: Aber das ist "Zufall". Das funktioniert nur, weil %&/ kein gültiger Name für eine Variable ist. Dann gibt der Perl Interpreter auf.
Sonst hast Du recht. $ muss durch \$ escaped werden
Einzelne ' in einem String gehen.
Titel: Antw:elegante Lösung für Sonderzeichen, um Status im Device per Perl zu setzen
Beitrag von: Otto123 am 05 Dezember 2020, 19:30:59
Ich halte das Ansinnen:
ZitatIch möchte beliebige Zeichen per Perl in den Status meines Devices eintragen.
Für sehr ambitioniert  ;D ;D ;D
Titel: Antw:elegante Lösung für Sonderzeichen, um Status im Device per Perl zu setzen
Beitrag von: jannis am 05 Dezember 2020, 19:41:52
Zitat von: Otto123 am 05 Dezember 2020, 18:57:56
Funktioniert bei mir
{fhem('set w1 '.q(Sonderzeichen ,.'#:;;;;§$%&/ und was passiert hier: hier bei der Ausgabe?))}

Edit: ; bleibt ein Problem ;)

Mit dem "q(" könnte ich leben. Nur kommt die Ausgabe aus der Variable $meldung

my $meldung = "Sonderzeichen ,.'#:;;;;§$%&/ und was passiert hier: hier bei der Ausgabe?";
{fhem('set w1 '.q($meldung))}


da wird dann ausgegeben:
$meldung"

:'( gibt es irgendwo eine perl-x-fhem-Selbsthilfegruppe wo man sich psychisch nach einem Tag wie heute, wo außer ausprobieren und lesen nicht viel rausgekommen ist, wieder aufrichten lassen kann  ;D
Titel: Antw:elegante Lösung für Sonderzeichen, um Status im Device per Perl zu setzen
Beitrag von: Otto123 am 05 Dezember 2020, 20:16:35
{my $meldung = q(Sonderzeichen ,.'#:;;;;§$%&/ und was passiert hier: hier bei der Ausgabe?);;fhem('set w1 '.$meldung)}

https://perldoc.perl.org/perlop#Quote-Like-Operators
Titel: Antw:elegante Lösung für Sonderzeichen, um Status im Device per Perl zu setzen
Beitrag von: jannis am 06 Dezember 2020, 18:35:23
Zitat von: Otto123 am 05 Dezember 2020, 20:16:35
{my $meldung = q(Sonderzeichen ,.'#:;;;;§$%&/ und was passiert hier: hier bei der Ausgabe?);;fhem('set w1 '.$meldung)}

https://perldoc.perl.org/perlop#Quote-Like-Operators

da kam leider immer noch "$meldung" als Ergebnis heraus. Aber was dann funktionierte war: "qq", also:

{my $meldung =q q(Sonderzeichen ,.'#:;;;;§$%&/ und was passiert hier: hier bei der Ausgabe?);;fhem('set w1 '.$meldung)}

Warum? Weiß nicht. Aber so kann ich weitermachen  ;D

Titel: Antw:elegante Lösung für Sonderzeichen, um Devicestatus per Perl zu setzen (gelöst)
Beitrag von: amenomade am 06 Dezember 2020, 19:32:20
q => die Variablen werden nicht interpretiert. Ist gleich '  '
qq => die Variablen werden interpretiert. Ist gleich "  "

Allerdings ist es unmöglich, dass mit dem Code von Otto immer noch "$meldung" kommt. Da hast Du entweder die quotes nicht an der richtigen Stelle im fhem Befehl gesetzt, oder Du machst etwas anderes als was Otto schrieb.

Mit qq: da die Variablen interpretiert werden, musst Du noch unbedingt $ escapen (siehe oben). Und die % wahrscheinlich auch.
Titel: Antw:elegante Lösung für Sonderzeichen, um Devicestatus per Perl zu setzen (gelöst)
Beitrag von: jannis am 06 Dezember 2020, 20:31:33
Zitat von: amenomade am 06 Dezember 2020, 19:32:20
Mit qq: da die Variablen interpretiert werden, musst Du noch unbedingt $ escapen (siehe oben). Und die % wahrscheinlich auch.

Du hast recht, auch  % und $ müssen escapt werden. Habe beim Ersetzen Verdopplungen und Vervierfachungen wie beim ";" probiert ... ohne Erfolg.

und auch hiergegen wehrt sich fhem bzw. lässt die beiden Sonderzeichen einfach weg.
  $meldung=~s/\$/\$/g; # Dollarzeichen
  $meldung=~s/\%/\%/g; # Prozentzeichen


Und wenn zu den beiden auch noch das doppelte Anführungszeichen gehen würde .... aber das beißt sich ja wahrscheinlich mit qq.  Dann würd ich mir halt merken, kein " zu nutzen.
Titel: Antw:elegante Lösung für Sonderzeichen, um Devicestatus per Perl zu setzen
Beitrag von: amenomade am 06 Dezember 2020, 21:06:28
$meldung=~s/\$/\$/g; ersetzt $ durch $. Macht keinen Sinn.

s/\$/\\\$/gwürde mind. $ durch \$ ersetzen.
Titel: Antw:elegante Lösung für Sonderzeichen, um Devicestatus per Perl zu setzen
Beitrag von: jannis am 06 Dezember 2020, 21:12:14
Zitat von: amenomade am 06 Dezember 2020, 21:06:28
$meldung=~s/\$/\$/g; ersetzt $ durch $. Macht keinen Sinn.

s/\$/\\\$/gwürde mind. $ durch \$ ersetzen.

So nach ich das und "Sch**ße auf % und "
Muss ich mir halt merkem, Prozent auszuschreiben und einfache ' zu nehmen :)
Titel: Antw:elegante Lösung für Sonderzeichen, um Devicestatus per Perl zu setzen
Beitrag von: jannis am 06 Dezember 2020, 21:17:13
... und seh gerade
Zitat$meldung=~s/\$/\\\$/g;      # Dollarzeichen

geht nicht ... $ wird trotzdem geschluckt
Titel: Antw:elegante Lösung für Sonderzeichen, um Status im Device per Perl zu setzen
Beitrag von: Otto123 am 06 Dezember 2020, 21:36:08
Zitat von: Otto123 am 05 Dezember 2020, 19:30:59
Ich halte das Ansinnen: Für sehr ambitioniert  ;D ;D ;D
Titel: Antw:elegante Lösung für Sonderzeichen, um Devicestatus per Perl zu setzen
Beitrag von: amenomade am 06 Dezember 2020, 21:52:40
Zitat von: jannis am 06 Dezember 2020, 21:17:13
... und seh gerade
geht nicht ... $ wird trotzdem geschluckt
Das ist abhängig, wo und wie Du es machst. Wenn Du immer noch über deine Funktion gehst, dann ist natürlich $xxx schon beim Aufruf der Funktion weg. Schon vor dem Aufruf muss $ in der Zeichenkette escaped werden.

Ich wundere mich übrigens, warum Du keine Fehlermeldung in der Log hast. Hast Du mal dort geschaut?
Titel: Antw:elegante Lösung für Sonderzeichen, um Devicestatus per Perl zu setzen
Beitrag von: jannis am 06 Dezember 2020, 23:21:15
Ich danke Euch. Da niemand "live" Daten eingibt, die dann ausgegeben werden, achte ich halt bei der Formulierung von Fehlermeldungen darauf, $%" nicht zu benutzen.

Danke
Titel: Antw:elegante Lösung für Sonderzeichen, um Devicestatus per Perl zu setzen
Beitrag von: Beta-User am 07 Dezember 2020, 07:53:08
Na ja; vielleicht wäre es eine Idee, statt den Inhalt für "fhem" aufzubereiten, den "fhem"-Interpreter (AnalyzeCommandChain) erst gar NICHT zu benutzen und direkt CommandSetReading() anzusteuern?

Grundsätzlich bin ich aber der Meinung, dass sowas ggf. durch Schreiben in ein file zu lösen wäre und nicht via Reading-Inhalt. Der führt dann mit einiger Sicherheit bei der nächsten Gelegenheit zum nächsten Problem...