FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: Fritz Muster am 21 Februar 2023, 12:20:58

Titel: Übergabe Variable von perl in fhem Ebene
Beitrag von: Fritz Muster am 21 Februar 2023, 12:20:58
Hallo Zusammen,

ich habe mir eine kleine subroutine (myutils) gebaut die ich nicht zum laufen bekomme und wäre für Tipps/Anregungen dankbar. Ich möchte bei true einer if Schleife nach 5 Sekunden die identische Abfrage der ersten if Schleife erneut machen und in dessen true Fall den Wert off detected zurückgeben. Der code sieht so aus:

mysub
{
my ($device, $state,) = @_;
my $devstate = ReadingsVal("$device","$state",0);
if ($devstate eq "off") {fhem('sleep 5;; {if ($devstate eq "off"){return ("off detected")}}')}
return "sleeping";
}


In einem device habe ich folgendes userreading zum aufruf der Routine angelegt
watchdog {mysub ($name,"state")}

Das Ganze funktioniert nicht, im log steht

ERROR evaluating {if ($devstate eq "off"){return ("off detected")}}: Global symbol "$devstate" requires explicit package name (did you forget to declare "my $devstate"?) at (eval 4271727) line 1.
After sleep: Global symbol "$devstate" requires explicit package name (did you forget to declare "my $devstate"?) at (eval 4271727) line 1.


Jetzt ist meine Vermutung das ich durch den Wechsel von der perl Ebene in die fhem Ebene {fhem('...} die in perl definierte Variable $devstate verliere bzw. nicht mit "rüber nehme". Kann meine Vermutung jemand bestätigen und wenn ja hat jemand eine Idee wie ich die Variable beim Wechsel von perl zu fhem "mit nehmen kann".

Vielen Dank und viele Grüße
Fritz
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: DeeSPe am 21 Februar 2023, 12:24:54
Wenn Du den Inhalt von Variablen ausgeben möchtest, dann musst Du diese in doppelte Anführungszeichen setzen.
Bei einfachen wird die Variable nicht durch ihren Wert ersetzt oder Du musst die Variable aus den einfachen Anführungszeichen herausnehmen und dann mit einem Punkt hinten dran verknüpfen.

Gruß
Dan
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: DeeSPe am 21 Februar 2023, 12:29:55
z.B.:
if ($devstate eq "off") {fhem("sleep 5;; {if ($devstate eq 'off'){return ('off detected')}}")}

oder

if ($devstate eq "off") {fhem('sleep 5;; {if ('.$devstate.' eq "off"){return ("off detected")}}')}

oder

if ($devstate eq "off") {fhem("sleep 5;; {if ($devstate eq \"off\"){return (\"off detected\")}}")}

Gruß
Dan
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: Fritz Muster am 21 Februar 2023, 12:48:24
Danke für die schnelle Antwort!!

if ($devstate eq "off") {fhem('sleep 5;; {if ('.$devstate.' eq "off"){return ("off detected")}}')}

führt im log zu folgendem

sleep 5;; {if (off eq "off"){return ("off detected")}} : Last parameter must be quiet

und bei

if ($devstate eq "off") {fhem("sleep 5;; {if ($devstate eq 'off'){return ('off detected')}}")}

kommt

sleep 5;; {if (off eq 'off'){return ('off detected')}} : Last parameter must be quiet

und bei

if ($devstate eq "off") {fhem("sleep 5;; {if ($devstate eq \"off\"){return (\"off detected\")}}")}

ist die log Ausgabe

sleep 5;; {if (off eq "off"){return ("off detected")}} : Last parameter must be quiet

Jetzt scheint es so das die die if Abfrage nach dem sleep nicht als "neue Zeile" interpretiert wird sondern noch dem sleep Befehl zugeordnet wird. Und da wird ja wenn überhaupt nur ein "quiet" akzeptiert. lautet nun die Frage wie bekomme ich das hin das die if Abfrage nach dem sleep als "neue Zeile" interpretiert wird?
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: DeeSPe am 21 Februar 2023, 12:55:05
Zitat von: Fritz Muster am 21 Februar 2023, 12:48:24
lautet nun die Frage wie bekomme ich das hin das die if Abfrage nach dem sleep als "neue Zeile" interpretiert wird?

Das brauchst du nicht!
Warum fügst du nicht mal das angemahnte 'quiet' hinzu?
Also:
if ($devstate eq "off") {fhem('sleep 5 quiet;; {if ......


Gruß
Dan
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: Fritz Muster am 21 Februar 2023, 12:58:32
Zitat von: DeeSPe am 21 Februar 2023, 12:55:05
Warum fügst du nicht mal das angemahnte 'quiet' hinzu?
[/code]

Habe ich mal gemacht! Ergebnis
sleep 5 quiet;; {if (off eq "off"){return ("off detected")}} : Last parameter must be quie

:(
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: Fritz Muster am 21 Februar 2023, 13:01:06
Habe jetzt noch ein wenig probiert. Nach dem einfügen eines weiteren Semikolion nach dem sleep

my ($device, $state,) = @_;
my $devstate = ReadingsVal("$device","$state",0);
if ($devstate eq "off") {fhem("sleep 5;;; {if ($devstate eq \"off\"){return (\"off detected\")}}")}
return "sleeping";


erscheint jetzt keine Fehlermeldung mehr im log. Allerdings wird die if Abfrage nicht true (obwohl $devstate eq "off" ist) und der Rückgabewert der Routine ist "sleeping"
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: DeeSPe am 21 Februar 2023, 13:22:20
Klar, die Funktion gibt am Ende immer "sleeping" zurück!
Ich dachte das war so gewollt.
Sonst musst du das in den else Zweig legen:

my $devstate = ReadingsVal($device,$state,0);
if ($devstate eq 'off')
{
  fhem "sleep 5 quiet; {if ($devstate eq 'off'){return 'off detected'}else{return 'sleeping'}")};
}


Somit wird nach 5 Sekunden der Status erneut geprüft und wenn wieder true dann 'off detected' oder bei false 'sleeping'.

Das mit den ;;; ist Quatsch! Ein Semikolon reicht an der Stelle.

Gruß
Dan
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: Fritz Muster am 21 Februar 2023, 16:48:19
Zitat von: DeeSPe am 21 Februar 2023, 13:22:20
Klar, die Funktion gibt am Ende immer "sleeping" zurück!
Ich dachte das war so gewollt.

Aber die Routine kommt ja nicht immer bis zum Ende, da es ja sein kann das die if Schleife(n) true werden und dann mit dem return wert beendet werden ohne das die Routine bis zum Ende durchläuft und das "sleeping" zurückgibt.
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: DeeSPe am 21 Februar 2023, 16:56:42
Ich verstehe den Sinn irgendwie noch nicht so wirklich.
Zumal die eigentliche Frage des Themas hinreichend beantwortet wurde.

Durch wen/was wird denn die Funktion aufgerufen?
Und vor allem was soll das Ziel sein? Bitte nicht den Programmcode beschreiben.

Gruß
Dan
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: Fritz Muster am 21 Februar 2023, 17:06:22
Zitat von: DeeSPe am 21 Februar 2023, 16:56:42
Zumal die eigentliche Frage des Themas hinreichend beantwortet wurde.

Entschuldige bitte aber ich habe alle Deine Hinweise entprechend ausprobiert, leider funktionierte das aber alles nicht. Entsprechendes Feedback bzw. log Meldungen habe ich ja hier auch gepostet.

Ziel ist eine Routine zu bauen die als Art watchdog regelmäßig prüft (Event basiert) ob der state vom device sich geändert hat. Wenn das der Fall ist soll zunächst eine Wartezeit von 5 Sekunden laufen und danach soll der state erneut geprüft werden. Hat sich der state in den 5 Sekunden nicht geändert dann soll das device geschaltet werden. So ist der Plan. Ich möchte das Ganze über myutils / userreading machen da ich die identische Funktion für unterschiedliche devices benötige.

Bitte nicht wundern, im Rahmen des rum probierens arbeite ich in den Anweisungen der if Schleifen zunächst mit Rückgabewerten, wenn dann mal alles funktioniert ersetze ich das entsprechend mit den Schaltbefehlen. 
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: DeeSPe am 21 Februar 2023, 17:33:13
Zitat von: Fritz Muster am 21 Februar 2023, 17:06:22
Entschuldige bitte aber ich habe alle Deine Hinweise entprechend ausprobiert, leider funktionierte das aber alles nicht. Entsprechendes Feedback bzw. log Meldungen habe ich ja hier auch gepostet.

Zitat von: Fritz Muster am 21 Februar 2023, 13:01:06
erscheint jetzt keine Fehlermeldung mehr im log. Allerdings wird die if Abfrage nicht true (obwohl $devstate eq "off" ist) und der Rückgabewert der Routine ist "sleeping"

Das widerspricht sich irgendwie.
Und an meiner Bereitschaft zu helfen liegt es ja offenbar auch nicht!
Es ist immer schwer zu helfen wenn man keine oder zu wenig Informationen bekommt.

Ich würde das evtl. so lösen:
sub myStateCheck
{
  my ($name,$count) = @_;
  my $state = ReadingsVal($name,'state','');
  $count = $count?$count:0;
  if ($state eq 'off' && !$count)
  {
    # wenn off dann prüfe in 5 Sekunden wieder
    $count++;
    fhem "sleep 5 quiet; {myStateCheck('$name',$count)}";
  }
  elsif ($state eq 'off' && $count)
  {
    # mach was du machen willst wenn das Device nicht mehr off ist
    fhem "set $name on";
  }
  return;
}


Die Funktion wird nur mit dem Namen des zu prüfenden Devices aufgerufen.
Sie setzt bei 'off' den Zähler hoch und ruft sich dann selbst nach 5 Sekunden wieder auf.
Nach der ersten Rekursion landet sie gleich im elsif Zweig und schaltet das Gerät ein.
Sind beide Zweige false passiert überhaupt nichts.

Ich hoffe das ist das was Du erreichen wolltest.

Gruß
Dan
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: Fritz Muster am 21 Februar 2023, 17:38:44
Respekt!!

Als noob muss ich das jetzt erst einmal sacken lassen und dann versuchen umzusetzen.

Vielen Dank.
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: DeeSPe am 21 Februar 2023, 17:48:21
Zitat von: Fritz Muster am 21 Februar 2023, 17:38:44
Als noob muss ich das jetzt erst einmal sacken lassen und dann versuchen umzusetzen.

Ist doch bereits fertig umgesetzt!
Habs jetzt nicht getestet, aber ich denke das sollte so gehen.
Wenn Du es benötigst musst Du jetzt nur noch die Funktion mit dem Namen des entsprechenden Gerätes aufrufen und schon geht die einmalig wiederholte Prüfung los.
Willst Du das öfter prüfen, dann musst Du im if Zweig nur auf den entsprechend größeren Zähler prüfen:
if ($state eq 'off' && $count<2)

Gruß
Dan
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: DeeSPe am 21 Februar 2023, 18:57:10
Hier noch eine Version mit in Variablen ausgelagerter Konfiguration der Anzahl der Prüfungen und der Zeitspanne.
Das macht das nachträgliche Anpassen noch einfacher.
Hier kannst du als optionalen zweiten Parameter noch die Anzahl der maximalen Prüfungen mit übergeben, im optionalen dritten Parameter die Zeitspanne und das somit für jedes geprüfte Device individuell bestimmen.
sub myStateCheck
{
  my ($name,$max,$tim,$count) = @_;
  ##### CONFIG START #####
  my $maxi = 1; # Maximale Anzahl an wiederholten Prüfungen wenn keine vorgegeben wurde
  my $time = 5; # Zeit nach der die wiederholte Prüfung stattfinden soll
  ##### CONFIG END #####
  my $state = ReadingsVal($name,'state','');
  $max = $max?$max:$maxi;
  $tim = $tim?$tim:$time;
  $count = $count?$count:0;
  if ($state eq 'off' && $count<$max)
  {
    # wenn offline und Zähler kleiner als Vorgabe dann prüfe in $tim Sekunden wieder
    $count++;
    fhem "sleep $tim quiet; {myStateCheck('$name',$max,$tim,$count)}";
  }
  elsif ($state eq 'off' && $count)
  {
    # mach was du machen willst wenn das Device nicht mehr off ist, aber vorher offline war
    fhem "set $name on";
  }
  # sonst tue nichts
  # Ende immer mit return
  return;
}


Der Erstaufruf der Funktion wäre dann entweder:
myStateCheck(<NAME>)
dabei werden die Werte für Anzahl und Wiederholungen aus der Konfiguration in der Funktion genommen,
oder:
myStateCheck(<NAME>,5,10)
Damit startet die Funktion mit max. 5 Wiederholungen im Abstand von 10 Sekunden.

Gruß
Dan

EDIT: Hab die Reihenfolge der Parameter nochmal geändert, somit ist der Funktionsaufruf einen Parameter kürzer.
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: Fritz Muster am 08 März 2023, 19:32:13
Bin jetzt mal dazu gekommen das Ganze per copy/paste umzusetzen. Leider funktioniert der Code nicht. Es passiert schlichtweg nichts, auch im log findet sich kein Eintrag was evtl. ein Hinweis geben könnte warum nichts passiert.

Viele Grüße
Fritz
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: DeeSPe am 10 März 2023, 11:00:51
Zitat von: Fritz Muster am 08 März 2023, 19:32:13
Leider funktioniert der Code nicht. Es passiert schlichtweg nichts, auch im log findet sich kein Eintrag was evtl. ein Hinweis geben könnte warum nichts passiert.

Hab das jetzt selbst mal getestet und bei mir funktioniert es genau wie erwartet!
Die Funktion habe ich noch um ein paar Debug Ausgaben erweitert und auch diese landen mit dem erwarteten Inhalt im Log.
Code (99_myUzils.pm) Auswählen
sub myStateCheck
{
  my ($name,$max,$tim,$count) = @_;
  ##### CONFIG START #####
  my $maxi = 1; # Maximale Anzahl an wiederholten Prüfungen wenn keine vorgegeben wurde
  my $time = 5; # Zeit nach der die wiederholte Prüfung stattfinden soll
  ##### CONFIG END #####
  my $state = ReadingsVal($name,'state','');
  $max = $max?$max:$maxi;
  $tim = $tim?$tim:$time;
  $count = $count?$count:0;
  if ($state eq 'off' && $count<$max)
  {
    Debug 'Durchlauf '.$count;
    Debug 'if Zweig';
    Debug "$name ist $state";
    # wenn offline und Zähler kleiner als Vorgabe dann prüfe in $tim Sekunden wieder
    $count++;
    fhem "sleep $tim quiet; {myStateCheck('$name',$max,$tim,$count)}";
  }
  elsif ($state eq 'off' && $count)
  {
    Debug 'Durchlauf '.$count;
    Debug 'elsif Zweig';
    Debug "$name ist $state";
    # mach was du machen willst wenn das Device nicht mehr off ist, aber vorher offline war
    fhem "set $name on";
  }
  # sonst tue nichts
  # Ende immer mit return
  return;
}



Code (Dummy zum Testen definieren) Auswählen
define d1 dummy
attr d1 setList on off

setstate d1 off
setstate d1 2023-03-10 10:53:50 state off


Code (Funktion ausführen) Auswählen
{myStateCheck('d1')}

Nach 5 Sekunden wird der vorher ausgeschaltete Dummy noch einmal geprüft und wenn er immer noch ausgeschaltet ist wird dieser eingeschaltet.
Während dessen wird in das Log geschrieben:
2023.03.10 10:53:20 1: DEBUG>Durchlauf 0
2023.03.10 10:53:20 1: DEBUG>if Zweig
2023.03.10 10:53:20 1: DEBUG>d1 ist off
2023.03.10 10:53:25 1: DEBUG>Durchlauf 1
2023.03.10 10:53:25 1: DEBUG>elsif Zweig
2023.03.10 10:53:25 1: DEBUG>d1 ist off


Gruß
Dan
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: Fritz Muster am 12 März 2023, 13:45:38
Habe es jetzt hinbekommen das es läuft. Typischer copy/paste Fehler meinerseits  :-[

Allerdings scheint es das ich nicht exakt genug die Funktionsweise beschrieben habe. Ich möchte gerne das immer nach X Sekunden Wartezeit und nicht erfolgter state Änderung der set Befehl ausgelöst wird. Das Ganze soll in Y Intervallen geprüft werden. So wie ich Deine Funktion verstehe läuft die erste if Schleife die Y Intervalle immer durch ohne in den Intervallen selbst nochmal zu prüfen ob das device den state geändert hat. Oder sehe ich das falsch?

Vielen Dank und viele Grüße
Fritz
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: DeeSPe am 12 März 2023, 14:12:17
Zitat von: Fritz Muster am 12 März 2023, 13:45:38
Habe es jetzt hinbekommen das es läuft. Typischer copy/paste Fehler meinerseits  :-[

Allerdings scheint es das ich nicht exakt genug die Funktionsweise beschrieben habe. Ich möchte gerne das immer nach X Sekunden Wartezeit und nicht erfolgter state Änderung der set Befehl ausgelöst wird. Das Ganze soll in Y Intervallen geprüft werden. So wie ich Deine Funktion verstehe läuft die erste if Schleife die Y Intervalle immer durch ohne in den Intervallen selbst nochmal zu prüfen ob das device den state geändert hat. Oder sehe ich das falsch?

Vielen Dank und viele Grüße
Fritz

Tja, wenn man den genauen Use-Case kennen würde, dann könnte man auch besser helfen.

So wie ich das versteh benötigst Du den else Zweig gar nicht.
sub myStateCheck
{
  my ($name,$max,$tim,$count) = @_;
  ##### CONFIG START #####
  my $maxi = 1; # Maximale Anzahl an wiederholten Prüfungen wenn keine vorgegeben wurde
  my $time = 5; # Zeit nach der die wiederholte Prüfung stattfinden soll
  ##### CONFIG END #####
  my $state = ReadingsVal($name,'state','');
  $max = $max?$max:$maxi;
  $tim = $tim?$tim:$time;
  $count = $count?$count:0;
  if ($state eq 'off' && $count<$max)
  {
    # wenn off und Zähler kleiner als Vorgabe dann schalte ein und prüfe in $tim Sekunden wieder
    fhem "set $name on";
    $count++;
    fhem "sleep $tim quiet; {myStateCheck('$name',$max,$tim,$count)}";
  }
  # sonst tue nichts
  # Ende immer mit return
  return;
}


Gruß
Dan
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: RalfRog am 12 März 2023, 14:20:20
Das Thema scheint ja vom Prinzip her geklärt.

Was passiert in der Perl-Funktion mit dem Wert, der per return zurück gegeben wird. Hier landet er im UserReading (watchdog) von FHEM.

Zitat von: Fritz Muster am 21 Februar 2023, 12:20:58
...
In einem device habe ich folgendes userreading zum aufruf der Routine angelegt
watchdog {mysub ($name,"state")}
...

Wenn ich darf würde ich mich mit einer ähnlichen Frage hier dazu hängen.

Gerade bei den UserReadings ist schon soweit klar, dass der in der Sub per return zurückgegebene Wert im Reading landet.

Wie sieht es z.B. bei einem AT mit dem Aufruf einer Perl-Funktion aus. Möglicherweise doof gefragt:
Kann man da mit dem Rückgabewert im AT etwas anfangen und wo hätte man Zugriff.

Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: DeeSPe am 12 März 2023, 15:00:37
Funktionen sollten nur einen Rückgabewert bieten wenn dieser auch weiterverarbeitet werden soll, wie z.B. bei 'userReadings'.
Rückgabewerte von Funktionen die aus z.B. 'at' oder 'notify' aufgerufen werden landen im 'Nirvana' oder Du schreibst sie explizit irgendwo hin, z.B. ins Log oder ein Reading.

Gruß
Dan
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: RalfRog am 12 März 2023, 15:11:12
Danke dir :D   Aussage Nirwana reicht mir, war mir nicht so klar.

Thema Log und Readings in Perl-Funktionen ist soweit (geläufig.

Gruß Ralf
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: Benni am 12 März 2023, 15:41:11
Zitat von: DeeSPe am 12 März 2023, 15:00:37
Rückgabewerte von Funktionen die aus z.B. 'at' oder 'notify' aufgerufen werden landen im 'Nirvana' oder Du schreibst sie explizit irgendwo hin, z.B. ins Log oder ein Reading.

So Pauschal würde ich das nicht abhandeln! ;)

Zitat von: RalfRog am 12 März 2023, 14:20:20
Wie sieht es z.B. bei einem AT mit dem Aufruf einer Perl-Funktion aus. Möglicherweise doof gefragt:
Kann man da mit dem Rückgabewert im AT etwas anfangen und wo hätte man Zugriff.

Wenn ich meinen notify- oder AT-Ausführungsteil auf perl-Ebene setze, dann kann ich den Rückgabewert sehr wohl dort weiterverarbeiten:


defmod myAt at +*00:01:00 {\
   my $name='IrgendeinDeviceName';;\
   ## Übernahme des Rückgabewertes auf Perl-Ebene in einer Variable\
\
   my $rueckgabewert=mysub ($name,"state");;\
\
   ## den kann ich jetzt bspw. auf FHEM-Ebene in eineme Reading im at selbst speichern\
   ## (oder was auch immer damit machen)\
\
   fhem("setreading $SELF mysub_result $rueckgabewert");;\
}


gb#
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: DeeSPe am 12 März 2023, 15:44:41
Zitat von: Benni am 12 März 2023, 15:41:11

defmod myAt at +*00:01:00 {\
   my $name='IrgendeinDeviceName';;\
   ## Übernahme des Rückgabewertes auf Perl-Ebene in einer Variable\
\
   my $rueckgabewert=mysub ($name,"state");;\
\
   ## den kann ich jetzt bspw. auf FHEM-Ebene in eineme Reading im at selbst speichern\
   ## (oder was auch immer damit machen)\
\
   fhem("setreading $SELF mysub_result $rueckgabewert");;\
}


Das bestätigt doch nur meine Aussage:
Zitat von: DeeSPe am 12 März 2023, 15:00:37
Rückgabewerte von Funktionen die aus z.B. 'at' oder 'notify' aufgerufen werden landen im 'Nirvana' oder Du schreibst sie explizit irgendwo hin, z.B. ins Log oder ein Reading.

Gruß
Dan
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: Benni am 12 März 2023, 16:02:43
Irgendwie bin ich zur Zeit wohl etwas unaufmerksam!   :-\

gb#
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: DeeSPe am 12 März 2023, 16:04:43
Zitat von: Benni am 12 März 2023, 16:02:43
Irgendwie bin ich zur Zeit wohl etwas unaufmerksam!   :-\

Vielleicht doch mal ne Runde Gassi gehen? :D

Gruß
Dan
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: Benni am 12 März 2023, 16:06:33
Zitat von: DeeSPe am 12 März 2023, 16:04:43
Vielleicht doch mal ne Runde Gassi gehen? :D

War ich eigentlich vorhin erst  :D

gb#
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: RalfRog am 12 März 2023, 16:22:03
Jungs danke euch.
Beispiel von Benni war trotzdem nicht schlecht  ;)

Hoffe Fritz Muster ist jetzt nicht aus dem Tritt  8)

Schönen Sonntahg
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: Fritz Muster am 12 März 2023, 16:52:41
Danke, jetzt muss es nur noch eine weitere if Schleife in der 1. if Schleife geben, welche nach dem sleep erneut prüft ob das state noch off ist. Wenn das der Fall ist soll ein fhem "set on" kommen. und es soll dann im nächsten Intervall nach X Sekunden geprüft werden ob state nicht mehr off ist. Ich habe mich mal versucht mit folgendem Code, funktioniert aber nicht, Syntax Error im Log

if ($state eq 'off' && $count<$max) 
  {
    $count++;
    fhem "sleep $tim quiet;
           {if ($state eq 'off')
               {fhem "set $name on"; {myStateCheck('$name',$max,$tim,$count)}
           else {return;}";
          }
  }

 
Zitat von: RalfRog am 12 März 2023, 16:22:03
Hoffe Fritz Muster ist jetzt nicht aus dem Tritt  8)

Schönen Sonntahg

War noch nie drin im Tritt  ;D
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: DeeSPe am 12 März 2023, 17:30:33
Zitat von: Fritz Muster am 12 März 2023, 16:52:41
Danke, jetzt muss es nur noch eine weitere if Schleife in der 1. if Schleife geben, welche nach dem sleep erneut prüft ob das state noch off ist.

Aber genau das macht doch die Funktion indem sie sich selbst wieder nach Zeit X (verzögert durch sleep) aufruft und das so lange bis $max erreicht ist bzw. $state nicht mehr 'off' ist:
sub myStateCheck
{
  my ($name,$max,$tim,$count) = @_;
  ##### CONFIG START #####
  my $maxi = 1; # Maximale Anzahl an wiederholten Prüfungen wenn keine vorgegeben wurde
  my $time = 5; # Zeit nach der die wiederholte Prüfung stattfinden soll
  ##### CONFIG END #####
  my $state = ReadingsVal($name,'state','');
  $max = $max?$max:$maxi;
  $tim = $tim?$tim:$time;
  $count = $count?$count:0;
  if ($state eq 'off' && $count<$max)
  {
    # wenn off und Zähler kleiner als Vorgabe dann schalte ein und prüfe in $tim Sekunden wieder
    fhem "set $name on";
    $count++;
    fhem "sleep $tim quiet; {myStateCheck('$name',$max,$tim,$count)}";
  }
  # sonst tue nichts
  # Ende immer mit return
  return;
}


Also nochmal: Die Funktion prüft beim ersten Aufruf ob das Device 'off' ist und $max noch nicht erreicht ist, ist das der Fall wird das Device eingeschaltet und die Funktion nach Zeit X wieder aufgerufen. Dann kommt die selbe Prüfung wieder. Ist das Device also immer noch 'off' und $max immer noch nicht erreicht, dann wird wieder eingeschaltet und die Funktion nach Zeit X wieder aufgerufen. Das geht so lange bis das Device bei der Prüfung nicht mehr 'off' ist, oder $max erreicht ist.

Ich nehme an dass diese Funktion sicherstellen soll dass ein Device (mit evtl. schlechtem Funkempfang) auch wirklich eingeschaltet wurde.

Gruß
Dan
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: Fritz Muster am 12 März 2023, 17:54:16
Zitat von: DeeSPe am 12 März 2023, 17:30:33
Ich nehme an dass diese Funktion sicherstellen soll dass ein Device (mit evtl. schlechtem Funkempfang) auch wirklich eingeschaltet wurde.

Korrekt, das device wird geschaltet, der Trigger lässt die subroutine starten und diese soll dann in Y Intervallen nach X Sekunden prüfen ob device geschaltet hat.

So wie ich den Code verstehe wird das device in der if Schleife sofort geschaltet, das braucht es nicht. Es soll zunächst X Sekunden gewartet werden. Dann soll erneut geprüft werden ob device geschaltet hat. Wenn nicht soll geschaltet werden. Dann wieder X Sekunden warten und erneut prüfen ob device geschaltet hat. Das Ganze soll Y Intervalle erfolgen.

Viele Grüße
Fritz
Titel: Antw:Übergabe Variable von perl in fhem Ebene
Beitrag von: DeeSPe am 12 März 2023, 18:38:50
Dann so:
sub myStateCheck
{
  my ($name,$max,$tim,$count) = @_;
  ##### CONFIG START #####
  my $maxi = 1; # Maximale Anzahl an wiederholten Prüfungen wenn keine vorgegeben wurde
  my $time = 5; # Zeit nach der die wiederholte Prüfung stattfinden soll
  ##### CONFIG END #####
  my $state = ReadingsVal($name,'state','');
  $max = $max?$max:$maxi;
  $tim = $tim?$tim:$time;
  $count = $count?$count:0;
  if (!$count)
  {
    $count++;
    fhem "sleep $tim quiet; {myStateCheck('$name',$max,$tim,$count)}";
  }
  elsif ($state eq 'off' && $count<$max)
  {
    # wenn off und Zähler kleiner als Vorgabe dann schalte ein und prüfe in $tim Sekunden wieder
    fhem "set $name on";
    $count++;
    fhem "sleep $tim quiet; {myStateCheck('$name',$max,$tim,$count)}";
  }
  # sonst tue nichts
  # Ende immer mit return
  return;
}


Gruß
Dan