FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: Elektrolurch am 01 Oktober 2013, 20:51:46

Titel: Vordefinierte Zeitwerte in Perl
Beitrag von: Elektrolurch am 01 Oktober 2013, 20:51:46
Hallo,

in der CommandRef steht:

Um die Verwendung von Datum und Zeitangaben zu vereinfachen, wurden die Variablen $sec, $min, $hour, $mday, $month, $year, $wday, $yday, $isdst für die Verwendung in PERL-"oneliners" eingeführt

Tippt man in die Kommandozeile bspw.:{$hour;;} ein, so bekommt man im fhem-Fenster "20" angezeigt.

Verwendet man allerdings $hour in einem perl-Skript, so bekommt man beim Abspeichern eine Fehlermeldung, dass $hour nicht definiert ist. Klar.
$main::hour kann man zwar im Perl-Skript adressieren, zur Laufzeit steht dann aber im Logfile aber, dass man auf eine nicht initialisierte Variable zugreifen wollte.

Frage: Wie kann ich in Perl die o.g. Zeitvariablen benutzen?

Elektrolurch
Titel: Aw: Vordefinierte Zeitwerte in Perl
Beitrag von: Zrrronggg! am 01 Oktober 2013, 21:13:40
Beispiel aus meiner cfg:

define badbenutzung_on notify zk_pumpe:on.*  { if($hour < 2 || $hour >= 6) { fhem ("delete reset_hzg_bad_e ;; set hzg_bad_e desired-temp 24 ;; define reset_hzg_bad_e at +00:08:01 set hzg_bad_e desired-temp 17") } }

(zk_pumpe ist in Wirklichkeit der Bewegungsmelder im Bad)
Titel: Aw: Vordefinierte Zeitwerte in Perl
Beitrag von: Elektrolurch am 01 Oktober 2013, 21:20:41
Hallo,

ich hatte ja geschrieben, dass es über die Kommandozeile, also auch über den in der fhem.cfg eingefügten Perl-Code funktioniert.
Nicht aber in einer Perl-Subroutine in der 99_myutils.pm. Wenn  Du dden PerlCode aus Deinem Beispiel in eine Subroutine auslagerst, dann wird er nicht mehr funktionieren, da dort $hour nicht bekannt ist.
Ich habe noch nicht herausgefunden,, in welchem Modul $hour defniert wurde.
Der Zugriff müsste dann so lauten: $modul::hor. Mit main funktioniert es jedenfalls nicht.
Also, meine Frage ist nicht ganz so simpel, wie sie zunächst aussieht.
Trotzdem: Danke für den Versuch.

Elektrolurch
Titel: Aw: Vordefinierte Zeitwerte in Perl
Beitrag von: Zrrronggg! am 01 Oktober 2013, 21:27:29
Entschuldige bitte, dass du von Perl-Subroutine in der 99_myutils.pm gesprochen hast, ist für mich nicht ersichtlich gewesen.
Genau genommen auch nach 2x durchlesen jetzt immer noch nicht.

So oder so: dann kann ich dir leider auch nicht weiterhelfen. Sorry.
Titel: Aw: Vordefinierte Zeitwerte in Perl
Beitrag von: Elektrolurch am 01 Oktober 2013, 21:46:02
ok. Wenn ich mehr als sechs Zeilen Code habe, mache ich daraus eine Sub in der 99_myutils.
Werde es zukünftig präziser beschreiben.
Aber ich hatte ja auch den Auszug aus der CommandRef reinkopiert. Daraus war ja eigentlich auch ersichtlich, dass es sich um die fhem-Laufzeit handelt. In der fhem.pl finde ich keine globale Definietion der in der CommandRef aufgeführten Variablen, so dass ich sie mit $<modul>::hor usw. benutzen könnte.
Was natürlich in einer Perl-Routine geht, ist folgendes:

if ($meinWert > fhem("{$hour;;}")) { Code...

Aber das kanns ja nicht sein, 2x Mal das durch den Parser zu schicken, um den Wert der akt. Stunde abzufragen....

Elektrolurch
Titel: Antw:Vordefinierte Zeitwerte in Perl
Beitrag von: Samsi am 12 Januar 2014, 23:19:54
Hallo,

hast Du zufällig herausgefunden wie man die $hour variable direkt aus dem Modul aufrufen kann? Ich stehe nämlich vor dem gleichen Problem ;)

Grüße
Titel: Antw:Vordefinierte Zeitwerte in Perl
Beitrag von: Dietmar63 am 12 Januar 2014, 23:25:11
...

my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime($now);

anders geht es nicht.

Sogenannte Oneliner werden in

sub
AnalyzePerlCommand($$)
{
  my ($cl, $cmd) = @_;

  $cmd =~ s/\\ *\n/ /g;               # Multi-line

  # Make life easier for oneliners:
  %value = ();
  foreach my $d (keys %defs) {
    $value{$d} = $defs{$d}{STATE}
  }
  my ($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime;
  my $hms = sprintf("%02d:%02d:%02d", $hour, $min, $sec);
  my $we = (($wday==0 || $wday==6) ? 1 : 0);
  if(!$we) {
    my $h2we = $attr{global}{holiday2we};
    $we = 1 if($h2we && $value{$h2we} && $value{$h2we} ne "none");
  }
  $month++;
  $year+=1900;

  if($evalSpecials) {
    $cmd = join("", map { my $n = substr($_,1);
                          my $v = $evalSpecials->{$_};
                          $v =~ s/(['\\])/\\$1/g;
                          "my \$$n='$v';";
                        } keys %{$evalSpecials})
           . $cmd;
    # Normally this is deleted in AnalyzeCommandChain, but ECMDDevice calls us
    # directly, and combining perl with something else isnt allowed anyway.
    $evalSpecials = undef;
  }

  my $ret = eval $cmd;
  $ret = $@ if($@);
  return $ret;
}

und speziell in der Zeile   my $ret = eval $cmd; zur Ausführung gebracht.
Alle lokalen Varialben, die zu diesem Zeitpunkt bekannt sind, könne angesprochen werden. $hms müste sogar funktionieren.