FHEM Forum

FHEM => Automatisierung => DOIF => Thema gestartet von: bismosa am 01 Mai 2019, 19:42:52

Titel: [gelöst] Semikolon in String an Modul übergeben
Beitrag von: bismosa am 01 Mai 2019, 19:42:52
Hallo!

Ich stehe gerade auf dem Schlauch...

Ich habe ein DOIF, das mir aktuelle Blitzer aus einem anderen Modul via Pushover schicken soll. Die Blitzer werden in HTML als String übergeben.
Alles ist gut, bis im HTML ein Semikolon vorkommt. Dann meldet das DOIF einen Fehler, da das Semikolon wohl ausgewertet wird. (?)

Mein DOIF:
defmod di_Blitzer DOIF ([blitz:html])({\
my $msg=ReadingsVal("blitz","html","keine");;\
$msg =~ s/\"/\'/g;;\
fhem("set pushmsg msg device=bismosa sound=none html=1 title=Blitzer \"$msg\"");;\
})
attr di_Blitzer do always

Also eigentlich nicht so spannend.

Ich könnte nun die Umlaute einzeln zurückübersetzen. Also ü -> ü etc. Wären dann ein paar Zeilen...und müsste dann halt öfters mal wiederholt werden. Wäre dann ein Kandidat für die MyUtils  ;)
Aber müsste es nicht auch gehen, wenn ich das Semikolon escape? Ich habe das bisher noch nicht hinbekommen.

Gruß
Bismosa
Titel: Antw:Semikolon in String an Modul übergeben
Beitrag von: Ellert am 01 Mai 2019, 23:37:49
Du könntest versuchen auf die Perl-Ebene im DOIF verzichten und die set magic Syntax verwenden, um das Reading auszulesen, siehe https://commandref.fhem.de/commandref_DE.html#set
Titel: Antw:Semikolon in String an Modul übergeben
Beitrag von: bismosa am 02 Mai 2019, 20:35:18
Hallo!

Danke. Das kannte ich noch gar nicht  :)

Leider klappt dies allerdings auch nicht. Nach dem Semikolon im HTML ist schluss.

Ich habe es jetzt so gelöst:

([blitz:html])({
my $msg=ReadingsVal("blitz","html","keine");
$msg =~ s/\"/\'/g;

my %translate = ("ä" => "ä",
"Ä" => "Ä",
"ü" => "ü",
"Ü" => "Ü",
"ö" => "ö",
"Ö" => "Ö",
"ß" => "ß",
);

my $keys = join ("|", keys(%translate));
$msg =~ s/($keys)/$translate{$1}/g;

fhem("set pushmsg msg device=bismosa sound=none html=1 title=Blitzer \"$msg\"");
})


Gruß
Bismosa
Titel: Antw:Semikolon in String an Modul übergeben
Beitrag von: Per am 06 Mai 2019, 12:58:46
Hast du mal mit einfachen statt doppelten Anführungszeichen probiert? Ich erinnere mich, dass Perl da Unterschiede macht. Ob's was bringt, steht aber auf einem anderen Blatt.
Titel: Antw:Semikolon in String an Modul übergeben
Beitrag von: bismosa am 06 Mai 2019, 18:28:55
Hallo!
Ja...ich glaube das hatte ich. Soweit ich mich erinnere werden bei den einzelnen Anführungszeichen keine Variablen ausgewertet.
Naja...es klappt ja so mittlerweile super  :)
Sorry, ich hatte noch kein [Gelöst] mit in den Titel gepackt. Hole ich sofort nach  :)

Gruß
Bismosa
Titel: Antw:[gelöst] Semikolon in String an Modul übergeben
Beitrag von: Per am 07 Mai 2019, 13:00:04
Zitat von: bismosa am 06 Mai 2019, 18:28:55werden bei den einzelnen Anführungszeichen keine Variablen ausgewertet.

fhem('set pushmsg msg device=bismosa sound=none html=1 title=Blitzer "' . $msg . '"');


Wobei die dortigen doppelten Anführungszeichen der Grund für die Einschränkung sein könnten.


fhem('set pushmsg msg device=bismosa sound=none html=1 title=Blitzer \'' . $msg . '\'');

Bekommst du eine Fehlermeldung, welche den Text nach dem ersten Semikolon beinhaltet?

Außerdem: bei dem hohen Perl-Anteil, warum gehst du nicht gleich auf den Perl-Mode?
Titel: Antw:[gelöst] Semikolon in String an Modul übergeben
Beitrag von: bismosa am 07 Mai 2019, 15:43:14
Hallo!
Zitatwarum gehst du nicht gleich auf den Perl-Mode?
Die Frage wird mir jedes Mal gestellt  ::) Ich denke das ist die Faulheit. Der Syntax für die "normalen" DOIF ist mir einfach schon geläufiger. Ich versuche mich hier zu bessern  :)

Bei
fhem('set pushmsg msg device=bismosa sound=none html=1 title=Blitzer \'' . $msg . '\'');
bekomme ich die Fehlermeldung:
Unknown command neberg, try help.
Da hier das "Schöneberg" als "Sch&ouuml;neberg" in der Variable war.

Ich habe das mal als Perl-Mode DOIF probiert (war gar nicht so schwer):
defmod di_Blitzer DOIF {if ([blitz:html]) {\
my $msg=ReadingsVal("blitz","html","keine");;\
$msg =~ s/\"/\'/g;;\
\
fhem('set pushmsg msg device=bismosa sound=none html=1 title=Blitzer \'' . $msg . '\'');;\
}}
attr di_Blitzer do always


Nun gibt es keine Fehlermeldung mehr...aber nach dem Semikolon ist schluss mit der Nachricht.

Gruß
Bismosa
Titel: Antw:[gelöst] Semikolon in String an Modul übergeben
Beitrag von: Damian am 07 Mai 2019, 22:19:35
Zitat von: bismosa am 07 Mai 2019, 15:43:14
Hallo!Die Frage wird mir jedes Mal gestellt  ::) Ich denke das ist die Faulheit. Der Syntax für die "normalen" DOIF ist mir einfach schon geläufiger. Ich versuche mich hier zu bessern  :)

Bei
fhem('set pushmsg msg device=bismosa sound=none html=1 title=Blitzer \'' . $msg . '\'');
bekomme ich die Fehlermeldung:
Unknown command neberg, try help.
Da hier das "Schöneberg" als "Sch&ouuml;neberg" in der Variable war.

Ich habe das mal als Perl-Mode DOIF probiert (war gar nicht so schwer):
defmod di_Blitzer DOIF {if ([blitz:html]) {\
my $msg=ReadingsVal("blitz","html","keine");;\
$msg =~ s/\"/\'/g;;\
\
fhem('set pushmsg msg device=bismosa sound=none html=1 title=Blitzer \'' . $msg . '\'');;\
}}
attr di_Blitzer do always


Nun gibt es keine Fehlermeldung mehr...aber nach dem Semikolon ist schluss mit der Nachricht.

Gruß
Bismosa

Dein zusammengesetzter String wird vom fhem-Befehl analysiert, dabei wird das Semikolon vom FHEM-Parser als Trennzeichen interpretiert und der String wird zerstückelt.

Im Perl-Modus kann man sich die Analyse des FHEM-Befehls ersparen, das hat nicht nur den Vorteil, dass man Rechenzeit spart. Dadurch, dass der FHEM-Parser gar nicht erst zum Zuge kommt, wird das FHEM-Trennzeichen ; nicht als solches ausgewertet und an den Befehl weitergegeben. Es gibt dafür im Perl-Modus eine Perlfunktion, die unmittelbar den eigentlichen set-Befehl ausführt: https://fhem.de/commandref_DE.html#DOIF_fhem_set

PS

Im Perl-Modus kannst du das do always Attribut löschen.

Titel: Antw:[gelöst] Semikolon in String an Modul übergeben
Beitrag von: bismosa am 11 Mai 2019, 12:40:53
Hallo!

Sorry das ich jetzt erst antworte. Leider ist bei meinem Rechner die SSD abgeraucht...

Nun klappt es! Mit einem PERL-DOIF und wenigen Zeilen:
defmod di_Blitzer2 DOIF {if ([blitz:html]) {\
my $msg=ReadingsVal("blitz","html","keine");;\
$msg =~ s/\"/\'/g;;\
fhem_set("pushmsg msg device=bismosa sound=none html=1 title=Blitzer \'". $msg."\'");;\
}}
attr di_Blitzer2 room Blitzer


Vielen Dank! Die Funktion kannte ich so noch nicht!

Gruß
Bismosa
Titel: Antw:[gelöst] Semikolon in String an Modul übergeben
Beitrag von: Damian am 11 Mai 2019, 13:26:37
Zitat von: bismosa am 11 Mai 2019, 12:40:53
Hallo!

Sorry das ich jetzt erst antworte. Leider ist bei meinem Rechner die SSD abgeraucht...

Nun klappt es! Mit einem PERL-DOIF und wenigen Zeilen:
defmod di_Blitzer2 DOIF {if ([blitz:html]) {\
my $msg=ReadingsVal("blitz","html","keine");;\
$msg =~ s/\"/\'/g;;\
fhem_set("pushmsg msg device=bismosa sound=none html=1 title=Blitzer \'". $msg."\'");;\
}}
attr di_Blitzer2 room Blitzer


Vielen Dank! Die Funktion kannte ich so noch nicht!

Gruß
Bismosa

Im Perl-Modus kommt man oft ohne if-Abfragen aus, es könnte hier sogar ein Einzeiler schon ausreichend sein:

defmod di_Blitzer2 DOIF {fhem_set("pushmsg msg device=bismosa sound=none html=1 title=Blitzer \'".[blitz:html]."\'")}

Titel: Antw:[gelöst] Semikolon in String an Modul übergeben
Beitrag von: bismosa am 11 Mai 2019, 18:49:40
Hallo!

getestet:
defmod di_Blitzer2 DOIF {fhem_set("pushmsg msg device=bismosa sound=none html=1 title=Blitzer \'".[blitz:html]."\'")}
funktioniert. Da wäre ich so nicht drauf gekommen.
Ich glaube ich muss mich doch noch einmal ganz intensiv mit dem Perl-DOIF auseinandersetzen.

Vielen Dank!

Gruß
Bismosa
Titel: Antw:[gelöst] Semikolon in String an Modul übergeben
Beitrag von: Damian am 11 Mai 2019, 19:04:02
Zitat von: bismosa am 11 Mai 2019, 18:49:40
Hallo!

getestet:
defmod di_Blitzer2 DOIF {fhem_set("pushmsg msg device=bismosa sound=none html=1 title=Blitzer \'".[blitz:html]."\'")}
funktioniert. Da wäre ich so nicht drauf gekommen.
Ich glaube ich muss mich doch noch einmal ganz intensiv mit dem Perl-DOIF auseinandersetzen.

Vielen Dank!

Gruß
Bismosa

Im Perl-Modus ist es egal, wo der Trigger (hier [blitz:html]) steht. Wichtig ist nur die korrekte Perl-Syntax.
Titel: Antw:[gelöst] Semikolon in String an Modul übergeben
Beitrag von: Per am 13 Mai 2019, 12:58:45
Zitat von: Damian am 11 Mai 2019, 19:04:02Im Perl-Modus ist es egal, wo der Trigger (hier [blitz:html]) steht.
Interessant!
Titel: Antw:[gelöst] Semikolon in String an Modul übergeben
Beitrag von: Damian am 13 Mai 2019, 13:06:04
Zitat von: Per am 13 Mai 2019, 12:58:45
Interessant!

Deswegen ist der Perl-Mode auch flexibler, weil man nicht auf die typische Syntax DOIF-DOELESEIF-DOELSE festgelegt ist.

Z. B.:

DOIF {set_State([bla:status])}

Hier wird einfach bei einem Trigger der Status von bla übernommen. Das kriegt man noch nicht mal mit einem notify kürzer hin.