DOIF Timer berücksichtigen Zeitumstellung nicht

Begonnen von Waldmensch, 28 Oktober 2019, 00:01:25

Vorheriges Thema - Nächstes Thema

Waldmensch

Ich habe ein DOIF, was eine Lampe über den Tag steuert. Da sind mehrere Zeitfunktionen drin, unter anderem eine [23:55:00]. Diese wurde Heute um 22:55 ausgelöst. Ich vermute, das beim Setzen des Timers, nach der gestrigen Auslösung, die DST Stunde nicht berücksichtigt wurde.

Damian

Zitat von: Waldmensch am 28 Oktober 2019, 00:01:25
Ich habe ein DOIF, was eine Lampe über den Tag steuert. Da sind mehrere Zeitfunktionen drin, unter anderem eine [23:55:00]. Diese wurde Heute um 22:55 ausgelöst. Ich vermute, das beim Setzen des Timers, nach der gestrigen Auslösung, die DST Stunde nicht berücksichtigt wurde.

Normalerweise erkennt das Modul den Umstellungstag und berechnet die korrekte Zeit des nächsten Tages. Bei mir waren alle Zeiten korrekt berechnet worden.

Vielleicht ist bei dir im System etwas nicht korrekt eingestellt gewesen, so dass das Modul von falschen Voraussetzungen ausging, ansonsten würden sich hier mehr Leute melden, wenn es ein grundsätzliches Problem wäre.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

rabehd

Ich habe in einem DOIF einen Timer der mit sunset_abs getriggert wird.
Gestern (am Tag der Zeitumstellung) löste er verspätet nach 18:00 aus, für heute steht er auf 17:00 (das passt).
Auch funktionierende Lösungen kann man hinterfragen.

Damian

Zitat von: rabehd am 28 Oktober 2019, 10:36:55
Ich habe in einem DOIF einen Timer der mit sunset_abs getriggert wird.
Gestern (am Tag der Zeitumstellung) löste er verspätet nach 18:00 aus, für heute steht er auf 17:00 (das passt).

Auf externe Funktionen hat DOIF natürlich keinen Einfluss, wenn die Vorgabe 18:00 Uhr (egal von wem bestimmt) ist, dann sieht das Modul zu, dass es nach der Umstellung auch 18:00 wird, auch wenn es bei sunset_abs dann falsch wäre.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

rabehd

Meine Idee war es gestern, kurz nach der Zeitumstellung alle DOIF neu zu initialisieren und ein Checkall zu machen. Um die Umsetzung habe ich mich am gestrigen Sonntag noch nicht gekümmert.
Auch funktionierende Lösungen kann man hinterfragen.

mackshot

Hallo zusammen,

jedes halbe Jahr scheint das Problem hier im Forum ja aufzukommen, insbesondere gerne in Kombination von sunset/sunrise mit doif für die Rolladensteuerung.

Das Problem liegt darin, dass beim Ausführen des DoIf der nächste Zeitpunkt der Ausführung bestimmt wird. Dieser wird als Timespec bestimmt, der meinem Verständnis nach aus zwei Summanden besteht. Der erste gibt ab, dass die nächste Ausführung am nächsten Tag stattfindet sprich 24:00:00 und der zweite Summand legt dann die Uhrzeit an diesem Tag fest, beispielsweise 18:30:12. In der Summe erhalten wir dann 31:30:12. Wenn nun aber Zeitumstellung ist, ist plötzlich nicht mehr 18:30:12 korrekt sondern 17:30:12 (respektive 30:30:12) oder 19:30:12 (respektive 32:30:12) korrekt. Mit anderen Worten: Um das Problem zu korrigieren muss man eine Stunde abziehen oder addieren, wenn zwischen Bestimmungszeitpunkt und nächstem Ausführungszeitpunkt eine Zeitumstellung liegt.

Ich habe das Problem bei mir wie folgt gelöst:

Ich habe in meiner "99_myUtils.pm" die folgende Methode eingebaut:
sub adjustTime {
  my $val = shift;
  my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);

  my @parts = split(/:/, $val);
  my ($sec2,$min2,$hour2,$mday2,$mon2,$year2,$wday2,$yday2,$isdst2) = localtime(time + ($parts[0] - 24) * 60 * 60 + $parts[1] * 60 + $parts[2]);

  my $h = $parts[0];
  if ($isdst2 == 1 && $isdst == 0) { # CET -> CEST
    $h = $h - 1;
  } elsif ($isdst2 == 0 && $isdst == 1) { # CEST -> CET
    $h = $h + 1;
  }

  return $h . ":" . $parts[1] . ":" . $parts[2];
}


Und nutzen diese dann in einem  DoIf wie folgt:

([{adjustTime(sunset(-900,"17:00","22:30"))}]) ( set Rolladen night )

Ich übergebe also den Zeitpunkt in meine Methode und erhalte dann den (möglicherweise adjustierten) Zeitpunkt.

Ich hoffe ich konnte damit helfen. Gerne kann jemand mit mehr FHEM Wiki/Forum Erfahrung den Tipp bei Interesse an entsprechende Stelle übernehmen.

Markus

Damian

Zitat von: mackshot am 28 Oktober 2019, 21:55:43
Hallo zusammen,

jedes halbe Jahr scheint das Problem hier im Forum ja aufzukommen, insbesondere gerne in Kombination von sunset/sunrise mit doif für die Rolladensteuerung.

Das Problem liegt darin, dass beim Ausführen des DoIf der nächste Zeitpunkt der Ausführung bestimmt wird. Dieser wird als Timespec bestimmt, der meinem Verständnis nach aus zwei Summanden besteht. Der erste gibt ab, dass die nächste Ausführung am nächsten Tag stattfindet sprich 24:00:00 und der zweite Summand legt dann die Uhrzeit an diesem Tag fest, beispielsweise 18:30:12. In der Summe erhalten wir dann 31:30:12. Wenn nun aber Zeitumstellung ist, ist plötzlich nicht mehr 18:30:12 korrekt sondern 17:30:12 (respektive 30:30:12) oder 19:30:12 (respektive 32:30:12) korrekt. Mit anderen Worten: Um das Problem zu korrigieren muss man eine Stunde abziehen oder addieren, wenn zwischen Bestimmungszeitpunkt und nächstem Ausführungszeitpunkt eine Zeitumstellung liegt.

Ich habe das Problem bei mir wie folgt gelöst:

Ich habe in meiner "99_myUtils.pm" die folgende Methode eingebaut:
sub adjustTime {
  my $val = shift;
  my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);

  my @parts = split(/:/, $val);
  my ($sec2,$min2,$hour2,$mday2,$mon2,$year2,$wday2,$yday2,$isdst2) = localtime(time + ($parts[0] - 24) * 60 * 60 + $parts[1] * 60 + $parts[2]);

  my $h = $parts[0];
  if ($isdst2 == 1 && $isdst == 0) { # CET -> CEST
    $h = $h - 1;
  } elsif ($isdst2 == 0 && $isdst == 1) { # CEST -> CET
    $h = $h + 1;
  }

  return $h . ":" . $parts[1] . ":" . $parts[2];
}


Und nutzen diese dann in einem  DoIf wie folgt:

([{adjustTime(sunset(-900,"17:00","22:30"))}]) ( set Rolladen night )

Ich übergebe also den Zeitpunkt in meine Methode und erhalte dann den (möglicherweise adjustierten) Zeitpunkt.

Ich hoffe ich konnte damit helfen. Gerne kann jemand mit mehr FHEM Wiki/Forum Erfahrung den Tipp bei Interesse an entsprechende Stelle übernehmen.

Markus

Eigentlich müsste die Berücksichtigung in die sunset-Funktion - kannst ja mal Rudi vorschlagen :)
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

mackshot

Zitat von: Damian am 28 Oktober 2019, 22:09:13
Eigentlich müsste die Berücksichtigung in die sunset-Funktion - kannst ja mal Rudi vorschlagen :)

Genau das habe ich dank Deines Hinweises nun gemacht.

Damian

#8
Zitat von: mackshot am 28 Oktober 2019, 22:20:35
Genau das habe ich dank Deines Hinweises nun gemacht.

Leider wird es vermutlich nicht reichen. Bei der nächsten Zeitumstellung im Frühjahr werden bereits die Tage immer länger, d. h. der  tagfolgende sunset ist einige Sekunden später (also nicht am nächsten Tag) DOIF merkt es und um nicht zwei mal am Tag zu schalten, verschiebt es den Zeitpunkt um 24 Stunden auf den nächsten Tag, in diesem Fall dürfte der Patch im sunset nicht helfen.

Edit: Kann sein, dass bei sunset bei zunehmenden Tagen die Verschiebung auf den nächsten Tag im sunset stattfindet, das Problem dürfte dann nur bei sunset_abs sein.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

mackshot

Ich habe für eine mögliche Anpassung an 99_SUNRISE_EL einen neuen Thread hier aufgemacht https://forum.fhem.de/index.php/topic,104852.0.html

Danke und gute Nacht
Markus

Nestor

#10
Zitat von: Damian am 28 Oktober 2019, 10:27:18
Normalerweise erkennt das Modul den Umstellungstag und berechnet die korrekte Zeit des nächsten Tages. Bei mir waren alle Zeiten korrekt berechnet worden.

I have a DOIF with time interval in the condition: [23:15-01:00]
The first timer was calculated one hour too early for the day DST changed.

OK

setstate Di_Alarm_Arm_Absence 2019-10-25 23:20:00
setstate Di_Alarm_Arm_Absence 2019-10-26 01:00:00 timer_01_c01 26.10.2019 23:15:00
setstate Di_Alarm_Arm_Absence 2019-10-26 01:00:00 timer_02_c01 27.10.2019 01:00:00


Wrong timer_01

setstate Di_Alarm_Arm_Absence 2019-10-26 23:20:00
setstate Di_Alarm_Arm_Absence 2019-10-27 01:00:03 timer_01_c01 27.10.2019 22:15:00
setstate Di_Alarm_Arm_Absence 2019-10-27 01:00:03 timer_02_c01 28.10.2019 01:00:00


OK

setstate Di_Alarm_Arm_Absence 2019-10-27 22:20:00
setstate Di_Alarm_Arm_Absence 2019-10-28 01:00:00 timer_01_c01 28.10.2019 23:15:00
setstate Di_Alarm_Arm_Absence 2019-10-28 01:00:00 timer_02_c01 29.10.2019 01:00:00


It seems DST change is correctly calculated on my system:

fhem> {$ENV{'TZ'}}
Europe/Brussels
fhem> {my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time_str2num('2019-10-27 01:00:00'));; $isdst}
1
fhem> {my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time_str2num('2019-10-27 02:00:00'));; $isdst}
0
fhem> version DOIF noheader
98_DOIF.pm 20268 2019-09-28 21:00:39Z Damian


Is there a setting in Fhem/DOIF I forgot to set for this to work correctly?

Damian

yes, it's a bug. I have to reproduce it first - that's not easy
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Damian

The bug has been fixed -> new DOIF Version

@mackshot

Da sunset die Zeitumstellung berücksichtigt, sollte mit der korrigierten DOIF-Version adjustTime nicht erforderlich sein.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

swsmily

Bei mir hatten auch am Tag nach der Zeitumstellungen DOIFs eine Stunde zu früh geschaltet, auch wenn z.b. nur [18:00] eingestellt war. Lampe ging dann 17 Uhr an.
Hab einfach den Raspi (obwohl Raspi und FHEM die richtige Zeit hatten) neugestartet und schon ging alles wieder.

Damian

Zitat von: swsmily am 29 Oktober 2019, 20:05:41
Bei mir hatten auch am Tag nach der Zeitumstellungen DOIFs eine Stunde zu früh geschaltet, auch wenn z.b. nur [18:00] eingestellt war. Lampe ging dann 17 Uhr an.
Hab einfach den Raspi (obwohl Raspi und FHEM die richtige Zeit hatten) neugestartet und schon ging alles wieder.

Dürfte jetzt mit der korrigierten Version behoben sein.

PS: Auf die Abschaffung der Zeitumstellung sollten wir erst mal nicht bauen ;)
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF