FHEM Forum

FHEM => Automatisierung => DOIF => Thema gestartet von: Rewe2000 am 29 Januar 2025, 13:03:32

Titel: Verwendung von Perl Variablen bei internen Timern get_Exec()
Beitrag von: Rewe2000 am 29 Januar 2025, 13:03:32
Hallo,

entweder habe ich da etwas falsch verstanden oder ich stelle mich nur zu blöd an.
Ist es korrekt, dass in einem doif, im Perl Modus deklarierte Variablen, innerhalb eines internen Timers nicht mehr gültig sind und hier erneut nochmals deklariert werden müssen?

Dies gibt den Fehler "..(did you forget to declare "my $Strom"?)..":
{
my $Strom = AttrNum("$SELF","Min_Ladestrom",0);
if ([du_Test:state] eq "on") {
set_Exec("Timer1",15,'Log 2, "Strom < $Strom Watt!"');
fhem_set "du_Test off"
} else {
del_Exec("Timer1")
}
}

Dies funktioniert korrekt, mit erneuter Deklaration innerhalb des Timers:
{
my $Strom = AttrNum("$SELF","Min_Ladestrom",0);
if ([du_Test:state] eq "on") {
set_Exec("Timer1",15,'my $Strom = AttrNum("$SELF","Min_Ladestrom",0); Log 2, "Strom < $Strom Watt!"');
fhem_set "du_Test off"
} else {
del_Exec("Timer1")
}
}

Bevor ich da unnötig umständlich programmiere, will ich lieber vorher nachfragen.


Gruß Reinhard
Titel: Aw: Verwendung von Perl Variablen bei internen Timern get_Exec()
Beitrag von: betateilchen am 29 Januar 2025, 14:07:35
Das Verhalten ist (für mich) völlig normal.

Du definierst in Deinem set_Exec() quasi einen neuen perl-Codeblock zur Ausführung, dieser weiß nichts über die von Dir außerhalb dieses Blocks definierten Variablen.

Alternativ könntest Du versuchen, Deine Variablen in einen Bereich zu schreiben, der FHEM-weit bekannt ist. Beispielsweise könntest Du statt "my $Strom" den hash-Wert $data{Strom} beschreiben. Dieser sollte auch in Deinem set_Exec() bekannt sein.
Titel: Aw: Verwendung von Perl Variablen bei internen Timern get_Exec()
Beitrag von: Damian am 29 Januar 2025, 18:57:02
Du kannst ersten Vorschlag abändern in :

set_Exec("Timer1",15,"Log 2, 'Strom < $Strom Watt!'");
Damit wird die $Strom-Variable bereits zum Zeitpunkt des Aufrufs ausgewertet und übergeben.

Man beachte die Reihenfolge und die Art der Hochkommas. Das sind nun mal die Eigenschaft von Perl.

In deinem zweiten Ansatz wird dagegen $Strom erst 15 Sekunden später ausgewertet und geloggt.

Je nach dem was man will.

Eine dritte Möglichkeit besteht darin, deinen ersten Vorschlag abzuwandeln in:

{
  $_Strom = AttrNum("$SELF","Min_Ladestrom",0);
if ([du_Test:state] eq "on") {
set_Exec("Timer1",15,'Log 2, "Strom < $_Strom Watt!"');
fhem_set "du_Test off"
} else {
del_Exec("Timer1")
}
}

Variablen im DOIF-Perlblock, die mit $_ beginnen, werden im $hash-Bereich des Devices abgelegt und leben solange das Device existiert. Das ist in der DOIF-Perl-Doku beschrieben: https://wiki.fhem.de/wiki/DOIF/Perl-Modus#Device-Variablen. Das entspricht in etwa dem Vorschlag von betateilchen.
Titel: Aw: Verwendung von Perl Variablen bei internen Timern get_Exec()
Beitrag von: Rewe2000 am 29 Januar 2025, 19:12:30
Hallo,

vielen Dank euch beiden für die Erklärung und die Tipps.
Für jemanden welcher sich nicht täglich und dann auch nicht sehr intensiv mit Perl beschäftigt, wäre ich da alleine nur schwer zum Ziel gekommen.

Ich teste mal die Varianten, damit ich die unterschiedliche Vorgehensweise nachvollziehen kann.

Gruß Reinhard