[gelöst] Semikolon in String an Modul übergeben

Begonnen von bismosa, 01 Mai 2019, 19:42:52

Vorheriges Thema - Nächstes Thema

bismosa

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
1x nanoCUL 433MHz (SlowRF Intertechno) für Fenstersensoren
1x nanoCUL 868Mhz für MAX (9x HT 1xWT)
1x ZigBee CUL
Weiteres: Squeezebox server, Kindle Display, ESP8266, Löterfahrung, ...

Ellert

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

bismosa

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
1x nanoCUL 433MHz (SlowRF Intertechno) für Fenstersensoren
1x nanoCUL 868Mhz für MAX (9x HT 1xWT)
1x ZigBee CUL
Weiteres: Squeezebox server, Kindle Display, ESP8266, Löterfahrung, ...

Per

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.

bismosa

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
1x nanoCUL 433MHz (SlowRF Intertechno) für Fenstersensoren
1x nanoCUL 868Mhz für MAX (9x HT 1xWT)
1x ZigBee CUL
Weiteres: Squeezebox server, Kindle Display, ESP8266, Löterfahrung, ...

Per

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?

bismosa

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
1x nanoCUL 433MHz (SlowRF Intertechno) für Fenstersensoren
1x nanoCUL 868Mhz für MAX (9x HT 1xWT)
1x ZigBee CUL
Weiteres: Squeezebox server, Kindle Display, ESP8266, Löterfahrung, ...

Damian

#7
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.

Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

bismosa

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
1x nanoCUL 433MHz (SlowRF Intertechno) für Fenstersensoren
1x nanoCUL 868Mhz für MAX (9x HT 1xWT)
1x ZigBee CUL
Weiteres: Squeezebox server, Kindle Display, ESP8266, Löterfahrung, ...

Damian

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]."\'")}

Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

bismosa

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
1x nanoCUL 433MHz (SlowRF Intertechno) für Fenstersensoren
1x nanoCUL 868Mhz für MAX (9x HT 1xWT)
1x ZigBee CUL
Weiteres: Squeezebox server, Kindle Display, ESP8266, Löterfahrung, ...

Damian

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.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Per

Zitat von: Damian am 11 Mai 2019, 19:04:02Im Perl-Modus ist es egal, wo der Trigger (hier [blitz:html]) steht.
Interessant!

Damian

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.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF