Verwendung von Perl Variablen bei internen Timern get_Exec()

Begonnen von Rewe2000, 29 Januar 2025, 13:03:32

Vorheriges Thema - Nächstes Thema

Rewe2000

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
Fhem 6.3 auf Raspberry Pi4 SSD mit Raspbian Bookworm, Homematic, Homematic IP, CCU3 mit RapberryMatic, WAGO 750-880, E3DC S10E Hauskraftwerk, E3DC Wallbox, my-PV AC ELWA-E Heizstab, Fritz!Box 7590, KIA Bluelinky

betateilchen

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.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Damian

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.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Rewe2000

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
Fhem 6.3 auf Raspberry Pi4 SSD mit Raspbian Bookworm, Homematic, Homematic IP, CCU3 mit RapberryMatic, WAGO 750-880, E3DC S10E Hauskraftwerk, E3DC Wallbox, my-PV AC ELWA-E Heizstab, Fritz!Box 7590, KIA Bluelinky