Schalten, wenn seit einem bestimmten Ereignis ein bestimmte Zeit vergangen ist

3,520 views
Skip to first unread message

Gamsgnack

unread,
May 13, 2012, 9:41:29 AM5/13/12
to fhem-...@googlegroups.com
Hallo zusammen,

mit Erfolg steuert FHEM meine Fußbodenheizung. Im Sommer aber brauche ich sie nicht so oft. Damit es mir die Stellantriebe nicht verkalkt, würde ich gerne spätestens alle 7 Tage die Stellantriebe neu betätigen/schalten.

Jetzt müsste ich irgendwie feststellen, wann dieser besagte Schalter zuletzt betätigt wurde.

Gibts es eine Möglichkeit bei einem Device (Homematic Switch) den letzten Schaltpunkt auszulesen?

Natürlich könnte man mit einem at einmal wöchentlich den Vorgang auslösen. Aber oft spiele ich an der Heizung rum und oft wären dann dieses at überflüssig, da keine 7 Tage vergangen sind.

Über einen Counter habe ich auch schon nachgedacht, aber es muss doch irgendwie über die Logdatei des Devices oder über ein ReadingsVal() funktionieren.

Grüße und danke schonmal


UliM

unread,
May 13, 2012, 1:22:23 PM5/13/12
to fhem-...@googlegroups.com


Am Sonntag, 13. Mai 2012 15:41:29 UTC+2 schrieb Gamsgnack:
Gibts es eine Möglichkeit bei einem Device (Homematic Switch) den letzten Schaltpunkt auszulesen?

Hi Gamsgnack,
jepp, dafür gibt's die Funktion ReadingsTimestamp, siehe http://fhem.de/commandref.html#perl
Ich hab nur FS20, da gibt's nen Zeitstempel auf dem state-Reading, ich vermute dass dieseer Zeitstempel benutzt wird.

Es gibt auch einen Zeitstempel auf dem reading CUL_TIME, ich vermute dass dies der Zeitstempel ist, wann von einem ggf zugehörigen Sensor das letzte Telegramm empfangen wurde. Das ist bei mir ein ganz anderer Zeitpunkt.

Postest Du Dein Ergebnis?

Gruß, Uli

UliM

unread,
May 13, 2012, 1:29:10 PM5/13/12
to fhem-...@googlegroups.com


Am Sonntag, 13. Mai 2012 19:22:23 UTC+2 schrieb UliM:
PS: In der commandref findest Du auch die Funktion time_str2num, mit der Du den Zeitstempel in einen absoluten Wert umrechnen kannst. Das macht den Vergleich von Zeiten wesentlich einfacher.
Hab's nicht probiert, vielleicht funktioniert ja time_str2num(ReadingsTimestamp("<device>","<reading>", 0)).
Ich weiss bloss nicht ob's sowas gibt wie ne Funktion now(), damit Du 'jetzt' als Bezugspunkt nehmen kannst.
Viel Erfolg!
Gruß, Uli

Gamsgnack

unread,
May 14, 2012, 2:11:40 PM5/14/12
to fhem-...@googlegroups.com
Am Sonntag, 13. Mai 2012 19:22:23 UTC+2 schrieb UliM:

Postest Du Dein Ergebnis?

Gruß, Uli


Hallo Uli,

vielen Dank für deine Denkanstöße. Jetzt lauft es so, wie es soll. Mit Hilfe deiner Vorschläge bin ich zu folgendem Ergebnis gekommen:

Mit ReadingsTimestamp(<devicename>,<reading>,<defaultvalue) bekomme ich wie von Dir bereits gesagt den Zeitstempel der letzten Schaltung im Format "YYYY-MM-DD HH:MM:SS".

Einen Zeitstempel von "jetzt" konnte ich dadurch erreichen, dass ich eine Methode in 99_Utils.pl hinterlegt habe welche mittels localtime aus Time::Local einen beliebig formatierten, aktuellen Zeitstempel ausgibt (localtime formatiert per Default folgendermaßen: "DAY MONTH HH:MM:SS YYYY"). Folgende Methode habe ich aus dem Netz kopiert:

sub now {
  
  my $FORMAT=$_[0];

  my $NOW=timelocal(localtime);
  my $y=sprintf("%02d",(localtime($NOW))[5]-100);
  my $Y=sprintf("%04d",(localtime($NOW))[5]+1900);
  my $m=sprintf("%02d",(localtime($NOW))[4]+1);
  my $d=sprintf("%02d",(localtime($NOW))[3]);
  my $H=sprintf("%02d",(localtime($NOW))[2]);
  my $M=sprintf("%02d",(localtime($NOW))[1]);
  my $S=sprintf("%02d",(localtime($NOW))[0]);

  $FORMAT =~ s/%y/$y/;
  $FORMAT =~ s/%Y/$Y/;
  $FORMAT =~ s/%m/$m/;
  $FORMAT =~ s/%d/$d/;
  $FORMAT =~ s/%H/$H/;
  $FORMAT =~ s/%M/$M/;
  $FORMAT =~ s/%S/$S/;

  return $FORMAT;
}

Ebenfalls in 99_Utils.pm kann ich dann mit folgender Methode in einem Define-Abschnitt den aktuellen Zeitstempel FHEM-Konform im Format "YYYY-MM-DD HH:MM:SS" ausgeben:

sub nowdate {
  return now("%Y-%m-%d %H:%M:%S");
}

Nun kommt dein zweiter Hinweis ins Spiel. time_str2num("YYYY-MM-DD HH:MM:SS") wandelt den Zeitstempel in einen "Sekundenzeitstempel" um. Damit kann man wunderbar eine Differenz errechnen. Als Beispiel ein Auszug aus einem notify:

  my $timestamp_now = time_str2num(nowdate());;
  my $timestamp_last = time_str2num(ReadingsTimestamp( "heizung","state",0 ));;
  my $timestamp_diff = $timestamp_now-$timestamp_last;;

  if ($timestamp_diff > 604800) {
    fhem("set heizung on-for-timer 60");;
  }

Alles läuft so, wie ich es mir vorgestellt hab.

Vielen Dank nochmal für deine Hilfestellung.

Grüße
Gamsgnack

UliM

unread,
May 14, 2012, 2:44:22 PM5/14/12
to fhem-...@googlegroups.com
Wow, schick!
Nun mach ich aus meinerAnfrage 'postest Du Dein Ergebnis' ein 'stellst Du's ins Wiki' ;-)
Hilft vmtl auch in Zukunft vielen weiter.
Gruß Uli
Message has been deleted
Message has been deleted

Stefan

unread,
May 30, 2012, 3:44:45 PM5/30/12
to fhem-...@googlegroups.com

Hallo, ich möchte genau dasselbe tun, was Du schon gelöst hast: Steuerung einer Fußbodenheizung mit fhem und HomeMatic. Allerdings: Fußbodenheizung ist noch nicht gelegt und ich bin blutiger fhem-Einsteiger. Kannst Du mir eine Beschreibung deiner Anlage geben (verwendete HomeMatic-Komponenten, Marke der Stellventile, evtl. sogar die entscheidenden Scriptteile)?

Ich habe mich etwas näher mit deinem Code beschäftigt und nun eine Verständnisfrage: Du kannst doch direkt die Ausgabe von time_str2num(ReadingsTimestamp( "heizung","state",0 )) mit dem time von Perl vergleichen; die haben doch dasselbe Format! Oder hab' ich was übersehen? Um das ganze für mich zu verstehen, habe ich alles in eine *.pl gepackt. Schau's Dir mal an.

 

-------schnipp:  zeit.pl-------------

use Time::Local;

use POSIX;

 sub now {

 

  my $FORMAT=$_[0];

 

  my $NOW=timelocal(localtime);

  my $y=sprintf("%02d",(localtime($NOW))[5]-100);

  my $Y=sprintf("%04d",(localtime($NOW))[5]+1900);

  my $m=sprintf("%02d",(localtime($NOW))[4]+1);

  my $d=sprintf("%02d",(localtime($NOW))[3]);

  my $H=sprintf("%02d",(localtime($NOW))[2]);

  my $M=sprintf("%02d",(localtime($NOW))[1]);

  my $S=sprintf("%02d",(localtime($NOW))[0]);

 

  $FORMAT =~ s/%y/$y/;

  $FORMAT =~ s/%Y/$Y/;

  $FORMAT =~ s/%m/$m/;

  $FORMAT =~ s/%d/$d/;

  $FORMAT =~ s/%H/$H/;

  $FORMAT =~ s/%M/$M/;

  $FORMAT =~ s/%S/$S/;

  return $FORMAT;

 

  print s/%y/$y/;

  }

 

sub nowdate {

  return now("%Y-%m-%d %H:%M:%S");

}

 

sub time_str2num($) {

                my ($str) = @_;

                my @a = split("[- :]", $str);

                return mktime($a[5],$a[4],$a[3],$a[2],$a[1]-1,$a[0]-1900,0,0,-1);

}             

 

                print "\ntime: ".time;

                print "\nlocaltime: ".localtime(time);    

                print "\ntimelocal: ".timelocal(localtime(time));             

                print "\ntimelocal: ".timelocal(localtime);

                $jetzt = now;

                print "\n\nnow: ".nowdate;

                print "\ntadaaa: ".time_str2num(nowdate);

               

-------schnapp: zeit.pl-------------

 

D.h.

my $timestamp_last = time_str2num(ReadingsTimestamp( "heizung","state",0 ));;

my $timestamp_diff = time-$timestamp_last;;

 

  if ($timestamp_diff > 604800) {

    fhem("set heizung on-for-timer 60");;

  }

 

sollte ausreichen.

Ich hoffe, Du hilfst mir trotz menem "Klugscheißer-Post" weiter ;-)

 

Vorab vielen Dank

Gruß Stefan




Am Sonntag, 13. Mai 2012 15:41:29 UTC+2 schrieb Gamsgnack:

UliM

unread,
May 31, 2012, 3:37:13 AM5/31/12
to fhem-...@googlegroups.com
Hi,
ich hab nach diesem post auch mal rumprobiert, bei mir geht so was wie
if ( (time - time_str2num(ReadingsTimestamp( "heizung","state",0 )) ) > 3600 ) { #schalten }
Gruß, Uli

Reply all
Reply to author
Forward
0 new messages