FHEM Forum

FHEM => Sonstiges => Thema gestartet von: Thyraz am 24 Juli 2018, 11:28:23

Titel: Modulentwicklung: 99_MyUtils Funktionen aus Modul aufrufen (sub-name als String)
Beitrag von: Thyraz am 24 Juli 2018, 11:28:23
Hallo zusammen,

für ein Modul zur Sprachsteuerung (https://forum.fhem.de/index.php/topic,89548.0.html) soll der User per Attribut Callback Funktionen konfigurieren können,
um FHEM abseits der normalen Abfragen/Steuerbefehle auf komplexere Fragen antworten zu lassen.

Da ich weder ein alter Hase bin was die FHEM Entwicklung angeht, noch der große Perl Profi,
frage ich mich was der sauberste Weg ist die Userfunktionen aufzurufen und einen FHEM Crash zu verhindern falls sie nicht exisitert.

Mal ein Beispiel wie das aussehen soll:
Der User fügt dem Attribut userIntents z.B. diese Zeile hinzu:
CalcIntent=myCalcSub(Number1,Operator,Number2)

Sagt der Anwender nun Rechne 4 plus 5, würde das Modul einen neuen Aufruf vom Typ "CalcIntent" bekommen.
Dazu die Werte für die Slots Number1, Operator und Number2.

Er müsste dann in seiner 99_myUtils eine sub erstellen die etwa so aussehen könnte:


sub myCalcSub($$$) {
  my ($val1, $operator, $val2) = @_;
  my result = "Sorry, außer zwei Zahlen zu addiere kann ich bisher leider noch nichts.";

  if (looks_like_number($val1) && $operator eq "plus" && looks_like_number($val2) {
    $result = "Das Ergebnis ist " . ($val1 + $val2);
  }

  return $result;
}


Funktionieren würde das sicher mit dem "fhem" Perbefehl und in diesem dann wieder auf Perl zurückwechseln:

  fhem("{myCalcSub($number1,$operator,$number2}");


Aber das ist kommt mir das innerhalb eines Moduls irgendwie nicht so ganz State of Art vor. ;)
Oder ist es durchaus legitim aus einem Modul heraus per fhem("..."); auf die FHEM Ebene zu wechseln?
Titel: Antw:Modulentwicklung: 99_MyUtils Funktionen aus Modul aufrufen (sub-name als String)
Beitrag von: CoolTux am 24 Juli 2018, 11:30:21
Pack den Aufruf der Funktion in ein eval.
Titel: Antw:Modulentwicklung: 99_MyUtils Funktionen aus Modul aufrufen (sub-name als String)
Beitrag von: betateilchen am 24 Juli 2018, 11:48:10
Zitat von: Thyraz am 24 Juli 2018, 11:28:23
Funktionieren würde das sicher mit dem "fhem" Perbefehl und in diesem dann wieder auf Perl zurückwechseln:

Das ist absoluter Quatsch. fhem() ist kein perlbefehl, sondern eine von FHEM bereitgestellte perl-Funktion, der man FHEM-Befehle übergeben kann.

Bevor Du solche Zusammenhänge nicht verstanden hast, solltest Du nicht darüber nachdenken, eine Modul für FHEM zu schreiben.
Und wenn ich hier lese, was Du da mit Attributen und usereigenen Funktionen vorhast, wird mir einfach nur schlecht.

Titel: Antw:Modulentwicklung: 99_MyUtils Funktionen aus Modul aufrufen (sub-name als String)
Beitrag von: Thyraz am 24 Juli 2018, 12:48:53
Irgendwie war ich mir schon zu 100% sicher, dass dieser Beitrag von dir kommen wird Udo. :)

Allerdings hatte ich neben dem Zerriss auf etwas mehr zufällig beigestreute Informationen gehofft.
Ich kann dich beruhigen, der Unterschied zwischen einer Perl-Funktion und einem FHEM Befehl ist mir durchaus bewusst.

Den Vorschlag erst dann Perl zu programmieren, wenn ich ein Perl-Profi bin kann ich leider nicht annehmen,
da dies dann nie eintreten würde und ich schon viel zu alt bin um ewig zu warten.
Es zwingt einen aber niemand das Modul zu nutzen.  ;)

Über Vorschläge wie man solch ein flexibles System einfacherer abbildet, bei dem der User die Kommunikation mit einem Sprachassistenten praktisch frei programmieren kann, bin ich immer dankbar.

Die Vorgehensweise über Attribut und usereigene Funktionen ist übrigens inspiriert vom AlexaFhem Modul von Andre, welches das auch so löst.
Ich hatte gehofft hier ein wenig Standardisierung und eine einfachere Einarbeitung für Nutzer die bereits die anderen Module kennen zu erreichen.

Beste Grüße,
Tobias


@Leon danke, damit scheint es zu funktionieren.
Gibt es an dieser Version Einwände?


my $val1 = 4;
my $val2 = 5;
my $operator = "plus";
my $result;

my $nameOfSub = "myCalcSub";

eval {
  no strict 'refs';
  $result = $nameOfSub->($val1,$operator,$val2);
};

if ($@) {
    # Something went wrong...
}


Danke schonmal. :)
Titel: Antw:Modulentwicklung: 99_MyUtils Funktionen aus Modul aufrufen (sub-name als String)
Beitrag von: DS_Starter am 24 Juli 2018, 13:40:48
Hallo Tobias,

zum Aufruf von Kommandos aus einem Modul heraus kannst du AnalyzeCommand oder AnalyzeCommandChain aus der API verwenden. siehe  https://wiki.fhem.de/wiki/DevelopmentModuleAPI
Im DbRep verwende ich das Konstrukt für die Abarbeitung einer User eigenen Routine des Attributes userExitFn. Siehst du auch im Modul in der Sub DbRep_userexit.
Vielleicht auch eine Anregung für eigene Experimente.

VG
Heiko
Titel: Antw:Modulentwicklung: 99_MyUtils Funktionen aus Modul aufrufen (sub-name als String)
Beitrag von: CoolTux am 24 Juli 2018, 13:48:09
Zitat von: DS_Starter am 24 Juli 2018, 13:40:48
Hallo Tobias,

zum Aufruf von Kommandos aus einem Modul heraus kannst du AnalyzeCommand oder AnalyzeCommandChain aus der API verwenden. siehe  https://wiki.fhem.de/wiki/DevelopmentModuleAPI
Im DbRep verwende ich das Konstrukt für die Abarbeitung einer User eigenen Routine des Attributes userExitFn. Siehst du auch im Modul in der Sub DbRep_userexit.
Vielleicht auch eine Anregung für eigene Experimente.

VG
Heiko

Finde ich persönlich sogar noch viel sauberer.
Titel: Antw:Modulentwicklung: 99_MyUtils Funktionen aus Modul aufrufen (sub-name als String)
Beitrag von: Thyraz am 24 Juli 2018, 13:50:49
Stimmt, das wäre auch noch eine schöne Lösung. :)

Danke euch.
Titel: Antw:Modulentwicklung: 99_MyUtils Funktionen aus Modul aufrufen (sub-name als String)
Beitrag von: rudolfkoenig am 24 Juli 2018, 14:37:39
Die "offizielle" Alternative zu eval ist AnalyzePerlCommand.
Vorteile:
- prueft die Authorisierung, wenn man $cl spezifiziert hat (man kann mit allowed die Ausfuehrung von perl untersagen)
- setzt $we (siehe holiday2we) und $hms,$sec,$min,...
- falls der ausgefuehrte Code eine Perl-WARNING produziert, dann wird zusaetzlich auch der ausgefuehrte Befehl geloggt.

fhem("") ist mehr oder weniger nur der Aufruf von AnalyzeCommandChain().
Titel: Antw:Modulentwicklung: 99_MyUtils Funktionen aus Modul aufrufen (sub-name als String)
Beitrag von: DS_Starter am 24 Juli 2018, 14:58:13
Danke für den Hinweis Rudi. AnalyzePerlCommand fehlt noch in der DevelopmentModuleAPI Beschreibung wenn ich mich nicht verguckt habe.
Wenn ich daran denke würde ich es im Wiki ergänzen und vllt. schaut dann noch einer drüber um sicher zu gehen dass ich keinen Mist geschrieben habe.
Titel: Antw:Modulentwicklung: 99_MyUtils Funktionen aus Modul aufrufen (sub-name als String)
Beitrag von: CoolTux am 24 Juli 2018, 14:59:47
Zitat von: DS_Starter am 24 Juli 2018, 14:58:13
Wenn ich daran denke würde ich es im Wiki ergänzen und vllt. schaut dann noch einer drüber um sicher zu gehen dass ich keinen Mist geschrieben habe.

Gib mal bitte Bescheid wenn Du soweit bist. Dann schaue ich es mir gerne an.
Titel: Antw:Modulentwicklung: 99_MyUtils Funktionen aus Modul aufrufen (sub-name als String)
Beitrag von: DS_Starter am 25 Juli 2018, 21:08:51
Hallo Leon,

habe in https://wiki.fhem.de/wiki/DevelopmentModuleAPI#AnalyzePerlCommand etwas zum Thema geschrieben.
Kannst mal bitte drüberschauen und ggf. abändern/ergänzen.

Grüße
Heiko
Titel: Antw:Modulentwicklung: 99_MyUtils Funktionen aus Modul aufrufen (sub-name als String)
Beitrag von: CoolTux am 25 Juli 2018, 21:30:14
Hallo Heiko,

Habe es mir durchgelesen und klingt für mich verständlich. Vielen Dank für Deine tolle Arbeit.


Grüße
Leon.