Hallo,
auch auf die Gefahr hin, gelyncht zu werden: Wie greife ich auf $data in der MyUtils zu? Wenn ich folgendes verwende, stürzt FHEM ab. Aber wie ist der korrekte Aufbau?
$data{LastRainMsg} = time();
Hi,
ich habe das mit dem $data schon einmal irgendwo gesehen, aber nicht verstanden, was es soll. Vielleicht kenne ich da aber auch etwas nicht...
Also: Was ist Deiner Meinung nach $data und was erhoffst Du Dir davon, was Du da machst?
Gruß,
Thorsten
Soweit ich das verstanden habe, ist es ein globaler Variablenstack.
Zitat von: Thorsten Pferdekaemper am 19 Februar 2017, 16:35:07
ich habe das mit dem $data schon einmal irgendwo gesehen, aber nicht verstanden, was es soll. Vielleicht kenne ich da aber auch etwas nicht...
Schau mal hier: https://wiki.fhem.de/wiki/DevelopmentModuleIntro#Wichtige_globale_Variablen_aus_fhem.pl
Zitat von: Det20 am 19 Februar 2017, 16:29:52
Wenn ich folgendes verwende, stürzt FHEM ab. Aber wie ist der korrekte Aufbau?
$data{LastRainMsg} = time();
Das ist vollkommen korrekt. Wo genau in welchem Kontext führst du das aus? Hast du die genaue Fehlermeldung warum FHEM abstürzt?
Gruß
Markus
In einer MyUtils. Finde leider in den Logs nichts außer "PERL WARNING: Use of uninitialized value $data{"LastRainMsg"} in addition (+) at ./FHEM/99_myUtils.pm line 21. ".
Und zack ... Weg ist er. Dachte der ist ev schon initialisiert. Wie initialisiere ich beim Start? Hätte nicht gedacht, dass sowas den FHEM in den Tot reißt.
sub ItsRain()
{
# Nur alle 60 Minuten
if(time()<($data{LastRainMsg}+60*60)) { exit; };
$data{LastRainMsg} = time();
...
Das Problem warum die FHEM dabei um die Ohren fliegt liegt höchstwahrscheinlich daran, dass du $data{LastRainMsg} in deiner IF-Bedingung verwendest ohne vorher zu prüfen, ob der Wert überhaupt in %data existiert, geschweige denn definiert ist. Wenn FHEM frisch startet existiert dieser Wert ja noch garnicht und du greifst damit auf einen nicht existierendes Element zu und versuchst damit zu rechnen. undef+60*60 wirft dabei dann einen Perl-Fehler.
Du solltest daher vor deinem if-Konstrukt prüfen ob dein Wert existiert und definiert ist, z.B. via if(defined($data{LastRainMsg})) und festlegen, was zu tun ist, wenn der Wert nicht definiert ist.
Gruß
Markus
Zitat von: Det20 am 19 Februar 2017, 17:22:19
Wie initialisiere ich beim Start?
z.B. mit einem notify:
define init_LastRainMsg notify global:INITIALIZED {$data{LastRainMsg} = 0}
Ich würde dir aber eher dazu raten, in deiner Funktion eine entsprechende Behandlung zu machen und dort bspw. den Wert initialisiern, sollte er nicht existieren:
sub ItsRain()
{
# Init
$data{LastRainMsg} = 0 unless(defined($data{LastRainMsg}));
# Nur alle 60 Minuten
if(time()<($data{LastRainMsg}+60*60)) { exit; };
$data{LastRainMsg} = time();
Ausserdem sind da für meinen Geschmack zu viele Klammern und ich würde die Verarbeitung lieber mit return als mit exit beenden.
sub ItsRain()
{
# Nur alle 60 Minuten
$data{LastRainMsg} //= 0;
return if( time() < $data{LastRainMsg}+60*60) ;
$data{LastRainMsg} = time();
...
Damit wird der Wert automatisch beim ersten Aufruf der Funktion mit 0 initialisiert und später regelmäßig aktualisiert.
Zitat von: Markus Bloch am 19 Februar 2017, 17:13:26
Schau mal hier: https://wiki.fhem.de/wiki/DevelopmentModuleIntro#Wichtige_globale_Variablen_aus_fhem.pl
Ah, sorry, ich wäre nie auf die Idee gekommen, dass es so etwas gibt, geschweige denn zur Benutzung propagiert wird.
Ich hätte das gelöst, indem ich an ein geeignetes Device ein Reading hänge und das dann mit ReadingsVal abfrage. Da passiert sowas nicht.
...oder aber direkt ein "at" angelegt, dass das alle 60 Minuten erledigt.
Gruß,
Thorsten
$data{LastRainMsg} = 0 unless(defined($data{LastRainMsg}));
Sehr geil, den kannte ich noch nicht. Vielen Dank!
Zitat von: Det20 am 19 Februar 2017, 17:37:04
$data{LastRainMsg} = 0 unless(defined($data{LastRainMsg}));
das ist exakt das gleiche wie
$data{LastRainMsg} //= 0;
nur länger 8)
Zitat von: Thorsten Pferdekaemper am 19 Februar 2017, 17:34:24
Ah, sorry, ich wäre nie auf die Idee gekommen, dass es so etwas gibt, geschweige denn zur Benutzung propagiert wird.
Naja, es ruft jetzt niemand aktiv dazu auf %data zu nutzen. Es dient dazu definitionsübergreifend Daten zur Laufzeit zu speichern. Definitionen können bspw in %data Extensions für FHEMWEB registrieren.
Zitat von: betateilchen am 19 Februar 2017, 17:38:24
das ist exakt das gleiche wie
$data{LastRainMsg} //= 0;
nur länger 8)
Ich störe mich da immer an den Schrägstrichen und denke dabei immer an Regexp :-\
Zitat von: Markus Bloch am 19 Februar 2017, 17:40:01
Ich störe mich da immer an den Schrägstrichen und denke dabei immer an Regexp
Naja, bei regexp kommen Schrägstriche in den allermeisten Fällen erst
nach einem = vor, selten davor.
Insofern hab ich damit überhaupt keine Verwexlungsprobleme.