Rekursives Aufrufen einer Modulfunktion

Begonnen von freetz, 10 März 2018, 07:33:54

Vorheriges Thema - Nächstes Thema

freetz

Hallo zusammen,

vermutlich ist das keine Anfängerfrage, aber da es für die Programmierung von Modulen kein eigenes Forum gibt (ansonsten bitte gerne verschieben!), probiere ich es einmal hier:
Für die Anbindung meiner Rasenmähroboter-Steuerung "Robotan" (https://github.com/fredlcore/robotan) an FHEM schreibe ich gerade ein dazu passendes Modul. Für einzelne Befehle, die an den Roboter geschickt werden, klappt das auch schon sehr gut. Nun ist es aber so, das es einige Befehle gibt, für die zuerst eine Rückmeldung eines ersten Befehls abgewartet werden müssen, um dann einen entsprechenden zweiten oder dritten Befehl hinterher zu senden.

Bisher habe ich eine _Set Funktion, die über httpNonBlockingGet eine Anfrage schickt, deren Antwort dann in der Funktion _Eval_Response ausgewertet wird. Aus dieser Funktion müsste ich nun unter bestimmten Bedingungen die _Set Funktion nochmals mit anderen Parametern aufrufen.

Meine Frage ist nun: Geht das? Und wenn ja, welche Parameter erwartet die Set-Funktion normalerweise?

Falls es zur Modulprogrammierung speziellere Dokus gibt (in der DeveloperAPI-Artikel im Wiki habe ich zu solchen Details nichts gefunden), dann freue ich mich auch über einen Hinweis.

Vielen Dank schon mal!

F.
Alle Infos zur Anbindung von Heizungssystemen mit PPS-, LPB- bzw. BSB-Bus ans LAN gibt es hier:
https://github.com/fredlcore/bsb_lan

Alle Infos zum WLAN-Interface "Robotan" für Ambrogio/Stiga/Wolf und baugleiche Rasenmähroboter:
https://github.com/fredlcore/robotan

CoolTux

#1
Es gibt das Developer Forum, darin kannst DU SELBER den Thread verschieben. Ganz unten ganz links THEMA VERSCHIEBEN

Dieser erste Befehl gibt es diesen auch in der SetFn? Vielleicht kannst Du etwas mehr erzählen was das genau ist.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

justme1968

#2
natürlich geht das. am einfachsten mit fhem("set $name ...");

aber ich glaube du denkst zu kompliziert. die setFn in deinem modul gehört doch dir. die kannst du es fach direkt aufrufen. so wie jede andere routine auch.

welche parameter erwartet werden siehst du auch direkt in seinem code.

gruss
  andre

ps: den hash bekommst du z.b. in dem du ihn mit in die parameter beim nonBlocking aufruf steckst. siehe z.b. BSB modul [emoji4]

pps: das ganze ist nicht rekursiv da du durch den nonBlocking aufruf alles entkoppelst.

ppps: falls du eine feste reihenfolge von kommandos hast kannst du auch alles auf einen stack pushen und dann nach ankunft einer antwort das nächste kommando vom stack holen und los schicken. auch dafür gibt es z.b. im BSB modul ein beispiel wenn eine reihe kathegorien nacheinander geholt wird.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

freetz

Danke, bis eben hatte ich da noch keinen Zugriff, dachte nicht, dass das so schnell geht :)!

Meine Set-Funktion ist (momentan) nicht viel mehr, als dass auf einen set-Aufruf eine URL aufgerufen wird, deren Rückmeldung in den meisten Fällen nicht relevant ist. Wenn ich z.B. "set Robotan Drive_Left" aufrufe, wird nur nachgeschlagen, welche Befehlsnummer an den Roboter gesendet werden muss und daraus die URL gebildet. Wenn ich "set Robotan Set_Mow_Days 1,5,7" aufrufe, wird neben der Befehlsnummer noch eine Umrechnung der Tage in ein Bitmuster vorgenommen und das dann an die URL übermittelt. httpNonBlockingGet übergibt die Antwort des Roboters dann an die _Parse Funktion, die bisher nur bei Fehlermeldungen den Status entsprechend aktualisiert.

Einige Befehle erwarten aber einen bestimmten Status des Roboters, z.B. dass er sich nicht bewegen darf. Das würde mir über entsprechende Werte in der Rückantwort mitgeteilt, so dass ich dann einen weiteren Befehl zum Pausieren schicken könnte. Ich müsste also aus der Parse-Funktion heraus wieder die _Set-Funktion mit einem anderen Parameter aufrufen und nach erfolgreicher Ausführung den ursprünglichen Befehl erneut senden. Den "Pause"-Befehl gibt es auch in der SetFn, falls das helfen sollte.
Alle Infos zur Anbindung von Heizungssystemen mit PPS-, LPB- bzw. BSB-Bus ans LAN gibt es hier:
https://github.com/fredlcore/bsb_lan

Alle Infos zum WLAN-Interface "Robotan" für Ambrogio/Stiga/Wolf und baugleiche Rasenmähroboter:
https://github.com/fredlcore/robotan

freetz

@Andre: Ja, am BSB-Modul orientiere ich mich auch gerade :) - ich habe den direkten Aufruf über die Set-Funktion auch schon probiert, auch das hash übermittle ich bereits in der httpNonBlockingGet Funktion. Aber ich müsste zum einen noch weitere Parameter übermitteln, zum anderen hatte ich beim direkten Aufruf der Set-Funktion aus der Parse-Funktion bisher das Problem, dass FHEM meckert, dass die Anzahl der übermittelten Parameter nicht mit der erwarteten Anzahl übereinstimmen.  Normalerweise steht ja ein "$" für einen übermittelten Parameter. Aber bei der BSB-Set-Funktion steht z.B. "$$@" und es werden drei Skalare und ein Array erwartet. Oder bei BSB_Attr steht "$$$" und es werden vier Skalare verarbeitet.

Letzteres sind sicherlich ziemliche FHEM-Programmier-Anfängerfragen (obwohl ich schon lange in Perl programmiere), aber ich habe wie gesagt nirgendwo eine genauere Beschreibung dazu gefunden. Falls ich doch etwas übersehen haben sollte, tut mir das natürlich leid und ich freue mich über jeden Hinweis!
Alle Infos zur Anbindung von Heizungssystemen mit PPS-, LPB- bzw. BSB-Bus ans LAN gibt es hier:
https://github.com/fredlcore/bsb_lan

Alle Infos zum WLAN-Interface "Robotan" für Ambrogio/Stiga/Wolf und baugleiche Rasenmähroboter:
https://github.com/fredlcore/robotan

CoolTux

Ich habe mal kurz über Dein Modul geschaut. Wenn Du uns mal Deinen Aufruf zeigst der nicht geht dann kann ich mir das mal anschauen.

Darüber hinaus hast Du etwas zu viel übernommen  :)


$param->{cl} = $hash->{CL} if( ref($hash->{CL}) eq 'HASH' );

Das denke ich mal brauchst Du nicht, zu mindest wertest Du es nirgens weiter aus.

Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

freetz

Danke für's Anschauen! Ja, ich habe Andres Modul Stück für Stück abgespeckt - irgendwie ging etwas ohne diese Zeile nicht mehr, aber da ich sie auch in 98_BSB.pm nicht richtig einordnen konnte, habe ich sie erst mal drin gelassen ;).

Mit dem direkten Aufruf der _Set-Funktion aus der _Eval-Funktion klappt es jetzt seltsamer- bzw. erfreulicherweise auch. Ich hätte dann nur noch zwei Fragen:
Werden bei httpNonBlockingGet zwei direkt aufeinander folgende Aufrufe so gesendet, dass der zweite Befehl erst dann gesendet wird, wenn vom ersten die Antwort gekommen ist? Oder wie kann ich am besten darauf warten?
Und zweitens: Wenn aus der _Eval-Funktion die _Set-Funktion aufgerufen wird, und dann wiederum die _Eval-Funktion: Bleiben Variablen, die ich innerhalb der _Eval-Funktion setze, bei nachfolgenden Aufrufen erhalten? Mir geht es darum, einen Retry-Counter umzusetzen. Dazu müsste ich mir merken, dass es a) einen Fehler gegeben hat und b) wie oft dieser versucht wurde zu beheben. Sollte ich dafür eine paketweite Variable verwenden oder macht man das anders?

Vielen Dank auf jeden Fall noch mal!
Alle Infos zur Anbindung von Heizungssystemen mit PPS-, LPB- bzw. BSB-Bus ans LAN gibt es hier:
https://github.com/fredlcore/bsb_lan

Alle Infos zum WLAN-Interface "Robotan" für Ambrogio/Stiga/Wolf und baugleiche Rasenmähroboter:
https://github.com/fredlcore/robotan

freetz

#7
...und irgendwie werden die Parameter, die ich über die Erweiterung des hashes an _Eval übergebe, dort nicht übernommen:

  my $param = {
    url => $url,
    timeout => 20,
    hash => $hash,
    method => "GET",
    callback => \&Robotan_Eval_HTTP
  };
  $param->{origCmd} = $cmd;
  $param->{origParam} = $params[0];

  HttpUtils_NonblockingGet($param);


Wenn ich diese dann mit
my $origCmd = $hash->{origCmd};
my $origParam = $hash->{origParam};

zuweisen möchte, meldet FHEM:
2018.03.10 10:00:48 1: PERL WARNING: Use of uninitialized value $origCmd in print at ./FHEM/98_Robotan.pm line 298.
2018.03.10 10:00:48 1: PERL WARNING: Use of uninitialized value $origParam in print at ./FHEM/98_Robotan.pm line 298.


EDIT: Ok, ich Hirsch muss natürlich aus $params und nicht aus $hash übernehmen  ;)
Alle Infos zur Anbindung von Heizungssystemen mit PPS-, LPB- bzw. BSB-Bus ans LAN gibt es hier:
https://github.com/fredlcore/bsb_lan

Alle Infos zum WLAN-Interface "Robotan" für Ambrogio/Stiga/Wolf und baugleiche Rasenmähroboter:
https://github.com/fredlcore/robotan

CoolTux

Kann leider nur kurz antworten, die Käselauchsuppe verlangt Aufmerksamkeit  ;D

Die httpNonBlockingGet beachtet nichts. Schickst du damit was los wird das ausgeführt und die Antwort an die Callback Funktion übergeben.
Du musst selber in deiner Funktion eine Logik einbauen. Entweder schickst du die Befehle in eine Queue mittels Array oder du machst es irgendwie anders.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

freetz

Ok, danke! Ein "fertiges" Queue-Handling gibt es noch nicht, oder? Frage nur, weil die Problemstellungen vielleicht schon öfter aufgetreten ist.
Dann aber erst mal guten Appetit :)!
Alle Infos zur Anbindung von Heizungssystemen mit PPS-, LPB- bzw. BSB-Bus ans LAN gibt es hier:
https://github.com/fredlcore/bsb_lan

Alle Infos zum WLAN-Interface "Robotan" für Ambrogio/Stiga/Wolf und baugleiche Rasenmähroboter:
https://github.com/fredlcore/robotan

CoolTux

Schau Dir mal die Funktion
TeslaPowerwall2AC_Timer_GetData($)
im Modul 46_TeslaPowerwall2AC.pm an.
In dieser Funktion wird die Queue gefüllt und ich denke man kann sehr gut verfolgen wie es weiter geht.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

CoolTux

Noch eine persönliche Anmerkung.
Mir ist bewusst das jeder Entwickler seinen eignen Stil hat, dennoch würde ich gerne ein zwei Worte zu Deinem Modul verlieren.

Du solltest vielleicht drüber nachdenken Deine Funktionen kleiner zu machen. Auf jeden Fall die SetFn. Das bringt Übersichtlichkeit und hilft auch mal anderen Entwicklern. Das zusammensetzten der Parameter und der Aufruf der HttpUtils_NonblockingGet Funktion kann man sehr gut in einer weiteren Funktion auslagern. So was muss nicht unbedingt mit in die SetFn. Das sollte Dir auch mehr Flexibilität geben.



Grüße
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

freetz

Danke! Ja, ich wollte das auch noch alles etwas besser strukturieren, wenn erst mal alles läuft - ist als erstes Modul noch ziemlich mit der heißen Nadel gestrickt ;)...
Alle Infos zur Anbindung von Heizungssystemen mit PPS-, LPB- bzw. BSB-Bus ans LAN gibt es hier:
https://github.com/fredlcore/bsb_lan

Alle Infos zum WLAN-Interface "Robotan" für Ambrogio/Stiga/Wolf und baugleiche Rasenmähroboter:
https://github.com/fredlcore/robotan