Ersetzung von Variablen verhindern

Begonnen von fritz, 04 November 2017, 01:51:56

Vorheriges Thema - Nächstes Thema

fritz

Hallo Wissende,

ich habe ein etwas komplizierteres Problem: ich möchte gern nach der Definition eines Objektes (hier ist es nur ein dummy) noch einige notifys automatisch installieren (abhängig von der dummy-Initialisierung). Dazu findet sich in meinem Perl-Code u.a. die Zeile:

fhem ("define Fn1$self notify $actor {manualHeizung(\"$self\", \"\$EVENT\")}");

Eine Kontrolle nach dem Neustart zeigt nun aber, dass $EVENT bereits hier durch nichts ersetzt wird, ungeachtet der Tatsache, dass das $-Zeichen mit einem Backslash maskiert wurde.
Wie lässt sich die vorzeitige Ersetzung von $EVENT in diesem Befehl verhindern?

Danke im Voraus - und viele Grüße

Uwe

P.S.: Es muss mal geklappt haben vor ca. 5 Jahren, sonst wäre der Code nicht nach meinen Tests drin geblieben. Aber irgendwann hat es scheinbar nicht mehr geklappt, und ich habe nicht mitbekommen, wann, nur dass die Funktion nicht mehr so arbeitete wie gedacht...

herrmannj

Nimm bei den hochkomma einfache, keine doppelten. String Interpolation ist der Begriff

Markus Bloch

Wenn Du $self ersetzt haben willst aber $EVENT nicht, dann so:

fhem ("define Fn1$self notify $actor {manualHeizung(\"$self\", \"".'$EVENT")}');


der Teil bis zum Beginn von $EVENT schreibt man in " (Anführungszeichen). In diesem Teil wird Variablenersetzung vorgenommen. Dann mit einem Punkt concatted man $EVENT in ' (Hochkommata). Alles was in Hochkommata steht erfährt keinerlei Variablenersetzung und wird daher so verwendet wie es da steht.

Der Vorteil: Man muss ein Anführungszeichen nicht mehr escapen ;)

Gruß
Markus
Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

fritz

Zitat von: herrmannj am 04 November 2017, 05:27:08
Nimm bei den hochkomma einfache, keine doppelten. String Interpolation ist der Begriff
Danke für die Tips, aber das funktioniert nur, wenn Perl das Sagen hat. Hier scheint aber die Funktion EvalSpecials aus fhem.pl zu arbeiten, und die weiß nichts mehr von den ursprünglichen Hochkommata um den String. Ich hab's probiert, das notify ist ohne $EVENT installiert worden.
Weitere Tips sind gern willkommen.

<F>

fritz

Das hier funktioniert leider auch nicht:
    fhem ("define Fn1$self notify $actor {manualHeizung(\"$self\"" . ', "$XXX")}');
    $defs{"Fn1$self"}->{'DEF'} =~ s/XXX/EVENT/;

Im Ergebnis sieht die Definition an der Oberfläche zwar wie gewünscht aus, das Log verrät jedoch, dass die Ersetzung von XXX mit dem gewünschten EVENT bereits zu spät erfolgt:
2017.11.05 13:27:05 5: Triggering Fn1LeseHeizung
2017.11.05 13:27:05 4: Fn1LeseHeizung exec {manualHeizung("LeseHeizung", "$XXX")}
2017.11.05 13:27:05 5: Cmd: >{manualHeizung("LeseHeizung", "$XXX")}<
2017.11.05 13:27:05 1: ERROR evaluating my $EVTPART3='HMLAN1)';my $EVENT='deviceMsg: off (to HMLAN1)';my $EVTPART1='off';my $NAME='LeseOfen';my $SELF='Fn1LeseHeizung';my $EVTPART2
='(to';my $EVTPART0='deviceMsg:';my $TYPE='CUL_HM';{manualHeizung("LeseHeizung", "$XXX")}: Global symbol "$XXX" requires explicit package name at (eval 811) line 1.
2017.11.05 13:27:05 3: Fn1LeseHeizung return value: Global symbol "$XXX" requires explicit package name at (eval 811) line 1.

Im Prinzip müsste man diesen eval-String manipulieren, leider ist nicht dokumentiert, wo der zu finden ist und damit dürfte eine Manipulation an der Stelle weder im Sinne von FHEM sein noch in irgendeiner Form updatesicher.
Ob es hilft, notify_Define aus Perl direkt aufzurufen?
<F>

rudolfkoenig

Versuchs mal mit
CommandDefine(undef, "Fn1$self notify $actor {manualHeizung("$self", "\$EVENT")}" )

Falls das nicht klappt, dann bitte eine nachstellbare Version posten, damit ich mein Vorschlag testen kann.

fritz

Danke, Rudolf, es tut. Ich musste lediglich noch auf das Maskieren der Hochkommata achten (s. oben):
    CommandDefine (undef, "Fn1$self notify $actor {manualHeizung(\"$self\"" . ', "$EVENT")}');

Die Funktion wird aufgerufen und erhält auch die Ereignisse - so soll es sein.

<F>