FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: Det20 am 19 Februar 2017, 16:29:52

Titel: $data in MyUtils
Beitrag von: Det20 am 19 Februar 2017, 16:29:52
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();
Titel: Antw:$data in MyUtils
Beitrag von: Thorsten Pferdekaemper am 19 Februar 2017, 16:35:07
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
Titel: Antw:$data in MyUtils
Beitrag von: Det20 am 19 Februar 2017, 16:41:14
Soweit ich das verstanden habe, ist es ein globaler Variablenstack.
Titel: Antw:$data in MyUtils
Beitrag von: Markus Bloch am 19 Februar 2017, 17:13:26
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
Titel: Antw:$data in MyUtils
Beitrag von: Det20 am 19 Februar 2017, 17:22:19
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();

...
Titel: Antw:$data in MyUtils
Beitrag von: Markus Bloch am 19 Februar 2017, 17:26:51
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
Titel: Antw:$data in MyUtils
Beitrag von: Markus Bloch am 19 Februar 2017, 17:29:57
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();
Titel: Antw:$data in MyUtils
Beitrag von: betateilchen am 19 Februar 2017, 17:32:27
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.
Titel: Antw:$data in MyUtils
Beitrag von: Thorsten Pferdekaemper am 19 Februar 2017, 17:34:24
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
Titel: Antw:$data in MyUtils
Beitrag von: Det20 am 19 Februar 2017, 17:37:04
$data{LastRainMsg} = 0 unless(defined($data{LastRainMsg}));

Sehr geil, den kannte ich noch nicht. Vielen Dank!
Titel: Antw:$data in MyUtils
Beitrag von: betateilchen am 19 Februar 2017, 17:38:24
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)
Titel: Antw:$data in MyUtils
Beitrag von: Markus Bloch am 19 Februar 2017, 17:40:01
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  :-\ 
Titel: Antw:$data in MyUtils
Beitrag von: betateilchen am 19 Februar 2017, 17:42:43
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.