[gelöst] DOIF perl-Modus und Anführungszeichen

Begonnen von Horti, 10 April 2020, 14:57:23

Vorheriges Thema - Nächstes Thema

Horti

Hallo FHEM-Gemeinde,

ich versuche folgendes mit DOIF hinzukriegen:

if {([00:00])
{
my $dstr = dateString();
fhem_set("myHMCCU hmscript /opt/fhem/hmscript.scr Device=JPDISEP000 Text="/1 '$dstr'"");
}

}


Die Anweisung ist nach diesem Muster gestrickt:
set d_hccu hmscript <File> Device=JPDISEP000 Text="/5 'Test ABC' 1"
Der eigentliche Text soll aber in Abhängigkeit von aktuellem Datum berechnet werden, die Funktion ist in myUtils definiert und liefert auch den gewünschten String.
Allerdings scheinen die Anführungszeichen ein Problem zu sein. Ich habe es schon mit \" und diversen anderen Möglichkeiten versucht, leider kein Erfolg. Hat jemand eine Idee?

MadMax-FHEM

#1
Ich nutze ja DOIF nicht...
...und wenn ich schon in DOIF Perl nehme(n muss) warum dann nicht glaich alles in Perl...

Egal ;)

Folgendes:

Also doppelte Anführungszeichen "inerhalb" doppelter Anführungszeichen müssen "escaped" werden:

fhem("set irgendwas mit \"doppelten Anführungszeichen\"")

Oder (falls es keine Variable zum Auswerten gibt, sondern nur fixer Text):

fhem("set irgendeinen 'fixen Text'")

Wenn du Variablen "auswerten" willst, dann musst du doppelte Anführungszeichen verwenden (wenn du welche brauchst):

fhem("set irgendetwas in doppelten Anführungszeichen aber aus einer \"$Variablen\"") -> statt dem "Text" $Variablen wird der "Inhalt" dieser Variablen "ausgewertet" und genommen und steht danach "innerhalb" der doppelten Anführungszeichen (die "escaped" wurden)...

fhem("set irgendwas in Anführungszeichen aber nur den Text wie er ist statt dem Inhalt der '$Variablen'") -> hier wird alles genauso übergeben wie es da steht, also NICHT der Inhalt der Variablen sondern genau der Text '$Variablen'...

Hoffe das hilft...

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

Horti

Zitat von: MadMax-FHEM am 10 April 2020, 15:24:22
Ich nutze ja DOIF nicht...
...und wenn ich schon in DOIF Perl nehme(n muss) warum dann nicht glaich alles in Perl...

Und dabei dachte ich, das wäre schon alles Perl :) Ich habe bis jetzt ohne Perl auskommen können, komme jetzt aber an den Punkt, wo es offenbar nicht ohne geht, blicke aber nicht durch was noch FHEM, was schon Perl und was vielleicht schon das Betriebssystem ist, dementsprechend stehe ich offenbar auf dem Schlauch.

Danke schon mal für Deine Ausführungen, werde sie mir heute Abend zu Gemüte führen!

MadMax-FHEM

#3
Tja ;)

fhem ist da wo du irgendein Device definierst und mit Attributen etc. "rumtust"...

define Name DOIF...
define Name nottify...
define Name at...
usw.

Bei fhem fängt Perl (meist) mit geschweiften Klammern an:

define Name notify TriggerRegEx {Das ist ist dann Perl}

System (also OS) Aufrufe, oh da gibt es vieles:

Angefangen von "einfach" in doppelte Anführungszeichen packen:

define Name notify Trigger-Regex "Das ist dann ein OS-Aufruf"

über system(), qx(), ...

Letztere neigen zum Blockieren...
...die doppelten Anführungszeichen nicht.

Allerdings ist dann bei Verwendung der doppelten Anführungszeichen auch "Essig" mit einem Rückgabewert... ;)

https://heinz-otto.blogspot.com/2018/02/in-fhem-externe-programme-aufrufen.html


Wenn man irgendwie nach Perl wechseln musste, dort aber dann fhem "braucht", geht es eben mit der "fhem-Funktion" zurück:

define Name notify Trigger-RegEx {Oheje Perl; fhem("gut dass ich wieder in fhem bin ;)  ");}

Heißt:

define Name notify Trigger-RegEx {fhem("set MeinDummy on")}

ist dasselbe wie:

define Name notify Trigger-RegEx set MeinDummy on

https://wiki.fhem.de/wiki/Klammerebenen


Mischen von Perl ind fhem im Ausführungsteil ist naja (gibt es Threads dazu) und damit ist nicht gemeint in einem Perl-Teil fhem-Aufrufe zu machen...

Also:

define Name notify Trigger-RegEx {Etwas Perl, dann fhem("ich setze was in fhem"), und wieder Perl}

ist ok, weil der Ausführungsteil (alles nach dem RegEx) ist erst mal Perl...

...dass da drinnen dann "rumgesprungen" wird ist "ok".

Folgendes kann "eigenartig" werden (kommt aber auch auf das Modul an):

define Name notify Trigger-RegEx set MeinDummy on;;{hier dann etwas Perl}

da wäre der Ausführungsteil ja gemischt...
(wenn das überhaupt so "geschluckt" wird / bzw. kommt es auf's verwendete Modul an etc.)


Das nur, weil ich grad Zeit hatte ;)

Viel Spaß, Joachim

P.S.: irgendwo gibt es hier einen anderen Thread wo jemand HM-Scripte mit dynamischen Daten aufrufen will... Evtl. da mal schauen, da war noch was neben den Anführungszeichen... (oder ist das auch von dir!?)
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

jkriegl

#4
Habe fhem_set noch nicht probiert. Ich erzeuge einen variablen reading-namen in einem at mit
my $reading = strftime('Ergebnis-%y-%m', localtime);
fhem("setreading month_end $reading $Erg");

Das reading sieht dann so aus "Ergebnis-20-03 G: 61.34 55.75 ......"
Versuch mal ab /opt/fhem ... alles in einer Variablen zusammen zu bauen.
Die Anzahl der Parameter bei fhem_set muss wohl mit set, setreading usw. übereinstimmen?
Rpi 3/4, buster, Fhem, Cul 868, HM-CC-RT-DN, HM-Sec-Sco, HM-ES-PMSw1-Pl, ebus (Vaillant), ECMD, Telegram, HTTPMOD, Xiaomi, Shelly

Damian

Zum DOIF-Perl kann man sagen: Innerhalb der geschweiften Klammern befindet man sich, mit Ausnahme von Trigger-Angaben in eckigen Klammern, in Perl. Damit gelten hier alle Regeln von Perl. Das Problem mit Anführungszeichen hat man genauso, wenn man den Code in eigene Perl-Funktionen auslagert.
Abgesehen davon ist die geschweifte Klammer hinter if nicht sinnvoll, es sei denn du möchtest den "Perlblock" if benennen.

Mögliche Lösungen deines Problems:

{if ([00:00])
{
my $dstr = dateString();
fhem_set("myHMCCU hmscript /opt/fhem/hmscript.scr Device=JPDISEP000 Text=\"/1 '$dstr'\"");
}
}


oder z.B. auch

{[00:00];fhem_set("myHMCCU hmscript /opt/fhem/hmscript.scr Device=JPDISEP000 Text=\"/1 '". dateString()."'\"");}



oder oder oder ...

Nach fünf Jahren Perl-Studium kennt man die meisten Möglichkeiten, meistens aber immer noch nicht alle ;)



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

Horti

Zitat von: Damian am 10 April 2020, 16:44:28
Mögliche Lösungen deines Problems:

{if ([00:00])
{
my $dstr = dateString();
fhem_set("myHMCCU hmscript /opt/fhem/hmscript.scr Device=JPDISEP000 Text=\"/1 '$dstr'\"");
}
}


Das ist auch die Variante, die mir als Erstes in den Sinn kam und die ich meinte, bereits ausprobiert zu haben, aber Fehlermeldungen bekam von wegen "irgendwas nicht in Ordnung near "". Wie auch immer, ich habe das gerade noch mal copy&paste übernommen und bekomme eine Fehlermeldung, die einer anderen Natur ist und vermutlich nichts mehr mit DOIF zu tun hat:
condition c01: Undefined subroutine &DOIF::dateString called, line 3.

Wie eingangs beschrieben ist die Funktion dateString() bei mir in 99_myUtils.pm definiert, ich kann sie auch mit
{dateString()}
mit FHEM-Kommanozeile oder wie auch immer dieses Feld am oberen Rand heißt aufrufen.

Oder muss ich myUtils in DOIF irgendwie importieren? Nach meinen Recherchen im Forum eher nein, aber vielleicht mache ich auch wieder einen dummen Anfängerfehler  :-[

Damian

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

Horti


RichardCZ

Excerpt aus: https://forum.fhem.de/index.php/topic,109616.msg1036051.html#msg1036051

Pro Tipp:

my $string = q{Hier kann's echt "dicke" stehen.};

Dann stellt man fest, man möchte doch eine Variable drin interpolieren:

my $string = qq{Hier kann's echt "dicke" stehen: $tralala};

Ein q vorne dazu oder weg und fertig. Überdies muss man keine Angst vor " oder ' im String haben.




Weil sonst sieht das alles ja aus wie arbeitslose Zahnstocher.
Witty House Infrastructure Processor (WHIP) is a modern and
comprehensive full-stack smart home framework for the 21st century.