sleep in Funktionen

Begonnen von ftsinuglarity, 04 Juni 2018, 17:08:59

Vorheriges Thema - Nächstes Thema

ftsinuglarity

Hallo liebe Gemeinde,

ich komme nicht so recht klar mit Pausen in Funktionen. Mir ist klar, daß das ein vieldiskutiertes Thema ist, ich schnalls trotzdem nicht. Ich entschuldige mich im Vorraus für die Frage und machs so kurz wie es geht.

Scriptbeispiel:
sub irgendwas {
    my $oldstate = ReadingsVal("xyDummy","xyReading",unset);
    my $state = do_anything_that_needs_time();
   
    if($state eq $oldstate) { print("ist gleich"); }
    else { print("ist NICHT gleich"); }
}
Hier kann es passieren, das $state noch nicht gesetzt ist.


Funktionieren würde:
    ..
    my $oldstate = ReadingsVal("xyDummy","xyReading",unset);
    my $state = do_anything_that_needs_time();
    fhem("sleep 10; set other_Dummy $state");
    ..

   
Nur wie bringe ich eine Pause non-blocking in das erste Scriptbeispiel ?
Also etwa :
    ..
    my $oldstate = ReadingsVal("xyDummy","xyReading",unset);
    my $state = do_anything_that_needs_time();
    sleep 10;
    if($state eq $oldstate) { print("ist gleich");
    ..

   
Wenn ich das so mache, würde ganz FHEM blockiert.

CoolTux

Schau dir im Developer Wiki mal InternalTimer ab
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

ftsinuglarity

#2
Zitat von: CoolTux am 04 Juni 2018, 17:55:13
Schau dir im Developer Wiki mal InternalTimer ab
Danke CoolTux!
Damit müsste ich eine weitere Funktion definieren, die ich dann aufrufe. (Oder die gleiche Funktion aufrufen und mit dafür reserviertem Parameter, gesetzter Variable o.ä.)
Das wird bei mehreren "sleep's" in einer Funktion schon sehr umständlich oder gesplittet.

Eine "einfachere" Form im Sinne von
sleep 10 &&  if($state eq $oldstate) .. die ich direkt einfügen kann, .. gibt es eine ähnliche Möglichkeit ?

(ich habe etliches ausprobiert, nichts davon hatte die gleichen Vorstellungen von sleep wie ich :D )

CoolTux

Wer oder was führt denn die Funktion aus, und wieso ist state dann Deiner Meinung nach noch nicht aktuell?
Das ist viel interessanter.
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

ftsinuglarity

#4
Zitat von: CoolTux am 04 Juni 2018, 18:21:14Wer oder was führt denn die Funktion aus
Aktuell habe ich eine Funktion, in der ein Linux-Script im Hintergrund einen DNS-Check durchführt.

Zitat von: CoolTux am 04 Juni 2018, 18:21:14
.. und wieso ist state dann Deiner Meinung nach noch nicht aktuell?
Die Auführung des Scripts dauert ein paar Sekunden, erst dann sind die Variablen in der aufrufenden 99_*.pm Funktion gefüllt. (die momentan per DNS aufgelöste IP zb)
Die aufrufende Funktion wartet jedoch nicht, bis die Scripte zu Ende ausgeführt wurden, sondern startet gleich den darauffolgenden Vergleich
"aktuelle_IP" eq "letzte_gespeicherte_IP"
Dazwischen bräuchte ich eine Pause.

Sleep brauche ich hin und wieder in Funktionen, um auf ähnliche Dinge wie in obigem DNS Beispiel warten zu können. Bisher habe ich immer Wege gefunden, das letztlich auch zu erreichen, aber sauber ist das alles nicht so wirklich.  Ich suche noch nach einem knackigen sleep 10 && mach irgendwas ... oder habe damit einen falschen Ansatz gewählt. Brauchst du sowas nie in Funktionen Tux?


Edit: Achso, die DNS Funktion wartet deshalb nicht auf das Ende des Scripts um dann erst die IP's zu vergleichen, weil ich sie im Hintergrund ausführen lasse um non-blocking zu arbeiten.
Beispiel: my $cur_ip = `$script cur_ip &`;

CoolTux

mir persönlich würde da noch Blocking.pm und die Funktion BlockingCall einfallen.
Aber das ist wieder Mehraufwand, ähnlich InternalTimer. Mir persönlich fällt da nichts schnelles ein.
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

ftsinuglarity

#6
Zitat von: CoolTux am 04 Juni 2018, 19:07:07mir persönlich würde da noch Blocking.pm und die Funktion BlockingCall einfallen.Aber das ist wieder Mehraufwand, ähnlich InternalTimer.
Ja :D . Blocking.pm hatte ich schonmal bei einer anderen Frage. Da kam ich auf die nicht-wirklich-geile Idee, immer wiederkehrende Checks komplett in den Hintergrund zu verlagern.
Letztlich stellte sich heraus, das es Unsinnig war, überhaupt derartig große Checks im Hintergrund als quasi-cronjob auszuführen, sondern die Checks einzeln über entprechende Events anzustoßen. Was dazu führte, das es zum erstenmal richtig klick gemacht hat, das FHEM eben ein Event-basiertes System ist, und es deshalb kontrproduktiv ist, mit Gewalt was anderes rüberstülpen zu wollen.  Manchmal brauchts das .. uff  :o


Zitat von: CoolTux am 04 Juni 2018, 19:07:07Mir persönlich fällt da nichts schnelles ein.
Ich dank dir dennoch für deine Zeit.

Edit: Wenn nichtmal dir auf-die-schnelle was einfällt, brauchst du sleep in der Form anscheinend auch nicht. Dann hab ich hier einen falschen Ansatz anscheinend.

rudolfkoenig

Ich wundere mich, warum man so selten das Feature nutzt, dass man mit "..." einen nicht blockierenden externen Prozess starten kann. Das kann gerne ein Shell-, Python-, Perl-Script, oder sonstwas Ausfuehrbares sein. Mit FHEM kann man z.Bsp. via
perl fhem.pl 7072 'set x y'
kommunizieren, oder per wget, Beispiele zu wget gibts sicher irgendwo.

ftsinuglarity

Zitat von: rudolfkoenig am 04 Juni 2018, 22:57:09
Ich wundere mich, warum man so selten das Feature nutzt, dass man mit "..." einen nicht blockierenden externen Prozess starten kann. Das kann gerne ein Shell-, Python-, Perl-Script, oder sonstwas Ausfuehrbares sein. Mit FHEM kann man z.Bsp. via
perl fhem.pl 7072 'set x y'
kommunizieren, oder per wget, Beispiele zu wget gibts sicher irgendwo.

Hallo Rudolf. Könntest du "..." näher erläutern ?
Ich bin bisher am besten mit: my $var = `/pfad/script parameter &` gefahren.

my $var = "/pfad/script parameter" ist nur ein String, deswegen bin ich etwas verwirrt was du genau meinst.

perl fhem.pl 7072 '{functionName("test")}'
ist ein wenig Kanone auf Spatz  oder ?

Kannst du bitte ein Beispiel geben, wie du ein x-beliebiges Script mit Parameter innerhalb einer 99_*.pm Funktion so aufrufst, wie du das meinst ?

CoolTux

Im Grunde geht es darum das Du ein externes Script auf rufst, das machst Du aber innerhalb von FHEM also nicht in Perl wechseln

fhem('"meinscript.pl"');


Glaube so muss es gehen. Ist am Ende das selbe als wenn Du in FHEMWEB oben in der Kommandozeile "meinscript.pl" auf rufst. Damit startest Du ein externes Script nonBlocking. Problem ist und bleibt aber der Erhalt des Ergebnis. Das musst Du dann im externen Script so machen das es die erhaltenen Daten wieder an FHEM liefert mit

perl fhem.pl 7072 'set dummy reading ergebnis'
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

rudolfkoenig

Ein Beispiel dafuer sieht man in contrib/garden.pl.
Diesen Skript (bzw. den Nachfolger davon) rufe ich aus einem at auf.
Das muss aber (wie geschrieben) kein Perl sein, falls jemand sich mit anderen Sprachen wohler fuehlt.

ftsinuglarity

Zitat von: rudolfkoenig am 05 Juni 2018, 09:32:15
Ein Beispiel dafuer sieht man in contrib/garden.pl.
Diesen Skript (bzw. den Nachfolger davon) rufe ich aus einem at auf.
Das muss aber (wie geschrieben) kein Perl sein, falls jemand sich mit anderen Sprachen wohler fuehlt.

Okaaay .. das geht dann an die Grenzen meiner Kompetenz. Du rufst sicher nicht das ziemlich spezielle komplette Script auf, sondern nutzt dessen Funktionen, richtig?

Insbesondere den Teil hier:
..  fhzcommand("set $dev $how");..

###########################
sub
fhzcommand($)
{
  my $cmd = shift;

  my ($ret, $buf) = ("", "");
  $server = IO::Socket::INET->new(PeerAddr => "localhost:$fhzport");
  die "Can't connect to the server at port $fhzport\n" if(!$server);
  syswrite($server, "$cmd;quit\n");
  while(sysread($server, $buf, 256) > 0) {
    $ret .= $buf;
  }
  close($server);
  return $ret;
}


Tut mir leid wenn ich nicht ganz mitkomme und deswegen frage, was für dich der springende Punkt an der garden.pl ist und wie du das dann nutzt.
fhzcommand() löst das "sleep-Problem" durch das auslesen des Buffers bis nichts mehr kommt, wenn ich das richtig deute (hab die Funktion noch nicht vollständig verstanden), und gibt erst dann das Ergebnis ($ret) zurück. War es das worauf du hinaus wolltest ?

rudolfkoenig

ZitatDu rufst sicher nicht das ziemlich spezielle komplette Script auf, sondern nutzt dessen Funktionen, richtig?
Falsch. Ich rufe per at den "ganzen" Skript auf, was einen Bewaesserungsvorgang (dauert zwischen 5 und ca 120 Minuten) durchfuehrt.Das von Dir zitierte Funktion ist nur eine veraltete Kopie der gleichen Funktionalitaet aus fhem.pl, was man mit
Zitatperl fhem.pl 7072 'set x y'
erreichen kann.

ftsinuglarity

Zitat von: rudolfkoenig am 05 Juni 2018, 14:10:53
Falsch. Ich rufe per at den "ganzen" Skript auf, was einen Bewaesserungsvorgang (dauert zwischen 5 und ca 120 Minuten) durchfuehrt.
Ahso. Du hast wirklich ne Bewässerungsanlage :D ..

CoolTux

Zitat von: ftsinuglarity am 05 Juni 2018, 14:31:41
Ahso. Du hast wirklich ne Bewässerungsanlage :D ..

Wie gesagt es ist lediglich ein externes Script welches Deine Aufgabe erfüllt (unabhängig von FHEM) und die Rückgabewerte welches es bekommt über einen FHEM Kanal an FHEM übermittelt.
Im Script von Rudi ist es telnet, Du kannst aber auch FHEM direkt aufrufen und die Daten übermitteln.

perl fhem.pl 7072 'set dummy reading ergebnis'


Ich hätte es in Erwägung gezogen hättest Du nicht von EINFACH und SIMPEL gesprochen  ;D
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