Event bei Zeitumstellung

Begonnen von Schlimbo, 31 Juli 2017, 13:28:48

Vorheriges Thema - Nächstes Thema

Schlimbo

Hallo zusammen,
habe ein paar IP Kameras, bei denen der Wechsel von Sommer/Winterzeit nicht automatisch erfolgt.
Aus dem Handbuch:
ZitatDie Sommerzeit muss für die Kamera manuell aktiviert werden - und im Winter dann wieder deaktiviert werden.
Da es mir nicht gefällt 2 mal im Jahr alle Kameras umzustellen habe ich dies jetzt mit FHEM automatisiert.
Die Umstellung an den Kameras kann über CGI Befehle durchführt werden, welche ich über das IPCAM Modul absetze.

Für die Zeitumstellung habe ich mir ein Holiday Device angelegt:
ZEITUMSTELLUNG.holiday
# Siehe auch
# http://www.zeitumstellung.de/regeln-zeitumstellung.html

3 -1 Sun 03 Beginn der Sommerzeit
3 -1 Sun 10 Ende der Sommerzeit


An den Tagen der Zeitumstellung wird dann ein at erstellt das um 2 bzw. 3 Uhr die Kameras umstellt:
define atSommerzeit at 02:00:00 {Log 3, "HomeMode: Anfang der Sommerzeit";; fhem 'set INSTAR raw param.cgi?cmd=setservertime&-dstmode=on'}
define atWinterzeit at 03:00:00 {Log 3, "HomeMode: Ende der Sommerzeit";; fhem 'set INSTAR raw param.cgi?cmd=setservertime&-dstmode=off'}


Die Frage die sich mir jetzt stellt ist:
Umstellung von Winter auf Sommerzeit
Wie erfolgt die Zeitumstellung im Linux system, wird die Zeit von 01:59:59 auf 03:00:00 gestellt?
Somit würde mein "at 02:00:00" ja gar nicht getriggert werden. Oder schaltet die Zeit erst auf 02:00:00 und dann weiter auf 03:00:00?
Umstellung von Sommerzeit auf Winterzeit
Wie erfolgt die Zeitumstellung im Linux system, wird die Zeit von 02:59:59 auf 02:00:00 gestellt?
Somit würde mein "at 03:00:00" eine Stunde zu spät ausgeführt.
Oder schaltet die Zeit erst auf 03:00:00 und dann weiter auf 02:00:00?

Um auf der sicheren Seite zu sein, stelle ich meine at erst mal eine Minute vor:
define atSommerzeit at 01:59:00 {Log 3, "HomeMode: Anfang der Sommerzeit";; fhem 'set INSTAR raw param.cgi?cmd=setservertime&-dstmode=on'}
define atWinterzeit at 02:59:00 {Log 3, "HomeMode: Ende der Sommerzeit";; fhem 'set INSTAR raw param.cgi?cmd=setservertime&-dstmode=off'}

Somit sollte es ja auf jeden Fall funktionieren.
Trotzdem wäre ich über einen Erklärung dankbar.

Gruß Schlimbo

rudolfkoenig

ZitatWie erfolgt die Zeitumstellung im Linux system, wird die Zeit von 01:59:59 auf 03:00:00 gestellt?
Linux/Unix hat einen Zaehler, was die Zeit seit 1970 beinhaltet, natuerlich ohne Zeitumstellung.  Der Zaehler wird nie verstellt, bis auf Schaltsekunden. Es gibt Routinen wie localtime, die aus dieser Zahl und der TZ Umgebungsvariable Monat/Tag/Stunde/etc berechnen.

Wenn man in FHEM per at eine Zeit definiert, dann wird die Zeitspezifikation mit der umgekehrten Routine (mktime) zu einer Sekundeangabe seit 1970 umgerechnet, und InternalTimer wird mit dieser Zahl aufgerufen. Da mktime in 90_at.pm immer mit isdst=-1 aufgerufen wird, wird die Zeit als die fruehere Zeit interpretiert. Du kannst ja mit mktime/localtime experimentieren, und mich korrigieren :)

fhem> { mktime(0, 30, 2, 29, 9, 117, 0,0, -1) }
1509237000
fhem> { localtime(1509237000) }
Sun Oct 29 02:30:00 2017
fhem> { mktime(0, 30, 2, 29, 9, 117, 0,0, 0) }
1509240600
fhem> { localtime(1509240600) }
Sun Oct 29 02:30:00 2017
fhem> { mktime(0, 30, 2, 29, 9, 117, 0,0, 1) }
1509237000
fhem> { localtime(1509237000) }
Sun Oct 29 02:30:00 2017


Schlimbo

Danke für deine Erklärung,
isdst=-1 bedeutet ja, dass das System selber entscheidet ob DST true oder false ist.
Durch ausprobieren habe ich jetzt festgestellt dass für die Sommerzeit bis "Sun Oct 29 02:59:59 2017"
isdst=-1 als DST=true erkannt wird, 3:00 ist dann schon DST=false
{ mktime(59, 59, 2, 29, 9, 117, 0,0, -1) } = { mktime(59, 59, 2, 29, 9, 117, 0,0, 1) } = 1509238799
{ mktime(00, 00, 3, 29, 9, 117, 0,0, -1) } = { mktime(00, 00, 3, 29, 9, 117, 0,0, 0) } = 1509242400


Wenn ich es richtig verstanden habe müsste meine Zeitumstellung so definiert werden:
define atSommerzeit at 02:00:00 {Log 3, "HomeMode: Anfang der Sommerzeit";; fhem 'set INSTAR raw param.cgi?cmd=setservertime&-dstmode=on'}
define atWinterzeit at 02:59:59 {Log 3, "HomeMode: Ende der Sommerzeit";; fhem 'set INSTAR raw param.cgi?cmd=setservertime&-dstmode=off'}

Ist das so korrekt?
Somit wird die Uhr in der Kamera eine Sekunde zu früh auf Winterzeit gestellt.
Der korrekte Timestamp wäre ja "1509238800" aber den bekomme ich ja nicht in das at, oder?
{ localtime(1509238800) }
Sun Oct 29 02:00:00 2017
{ mktime(0, 00, 2, 29, 9, 117, 0,0, -1) }
1509235200


amenomade

ZitatOder schaltet die Zeit erst auf 02:00:00 und dann weiter auf 03:00:00?
Rein von der Logik aus, würdest Du somit 1 Sekunde verlieren (zweimal :00 nacheinander)
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

andies

#4
Ich "kapere" mal diesen Thread, weil mich die Überschrift angelockt hat. Ich möchte gern ein notify triggern, wenn von Sommer- auf Winterzeit und umgedreht umgestellt wird. Hintergrund ist, dass YAAHM dann eine Initialisierungsroutine erneut durchlaufen muss, weil sonst die Zeiten um eine Stunde verschoben sind (siehe Wiki, https://wiki.fhem.de/wiki/Modul_YAAHM#Umstellung_Sommer-_zu_Winterzeit).

Ich würde das jetzt so machen. Ich habe ein dummy Sonne, dass aus Astro diverse Sonnenaufgangszeiten holt. Zudem habe ich in meiner Utils aus localtime den Zähler is_dst geholt,
my ($sec,$min,$hour,$dayn,$month,$year,$wday,$yday,$isdst) = localtime(time);
fhem("setreading Sonne Sommerzeit ".$isdst);

Dann würde ich im dummy Sonne ein event-on-changereading definieren
attr Sonne event-on-change-reading Sommerzeit
und dann weiß ich, wenn das Event Sonne:Sommerzeit ausgelöst wurde, gab es eine Umstellung.

Nun meine Frage. Ich kann das ja blöderweise nur zweimal im Jahr testen. Kann das so klappen?
FHEM 6.3 auf RaspPi4 (Raspbian:  6.6.28+; Perl: v5.36.0)
SIGNALduino (433 MHz) und HM-UART (868 MHz), Sonoff, Blitzwolf, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann

Jamo

Hier eine ein-Zeilen Lösung von Loredo, die hat bei mir schon 2 Zeitumstellungen überstanden.
https://forum.fhem.de/index.php?topic=42181.0
define SommerzeitWinterzeit DOIF(([02:00] or [03:00]) and $isdst) DOELSE
Bullseye auf iNUC, Homematic + HMIP(UART/HMUSB), Debmatic, HUEBridge, Zigbee/Conbee III, FB7690, Alexa (fhem-lazy), Livetracking, LaCrosse JeeLink, LoRaWan / TTN / Chirpstack, Sonos, ESPresence

andies

Die hatte ich beim Lesen auch gesehen, aber nicht verstanden. Ausgelöst wird um zwei oder drei Uhr und wenn isdst gesetzt ist. Aber wieso wird dann bei Änderung der Zeit ausgelöst? Und wieso stehen zwei Uhrzeiten drin, umgestellt wird doch nur bei einer?
FHEM 6.3 auf RaspPi4 (Raspbian:  6.6.28+; Perl: v5.36.0)
SIGNALduino (433 MHz) und HM-UART (868 MHz), Sonoff, Blitzwolf, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann

Frank_Huber

Ich hab eine etwas längere Version im Einsatz:
defmod SommerzeitWinterzeit DOIF (([02:00] or [03:00]) and $isdst == 1) () \
DOELSEIF (([02:00] or [03:00]) and $isdst == 0) ()
attr SommerzeitWinterzeit cmdState summer|normal
attr SommerzeitWinterzeit event-on-change-reading .*
attr SommerzeitWinterzeit eventMap summer:Sommer normal:Normal_(Winter) initialized:---
attr SommerzeitWinterzeit icon time_clock

andies

Ich glaube, langsam kapiere ich das. Das DOIF simuliert eine Auslösung, es wird aber nur der jeweilige Befehlszweig angesprochen. Durch cmdState wird dafür gesorgt, dass statt des Befehlskommandos summer oder normal im state steht. Durch event-on-change-reading wird ein event nur dann generiert, wenn sich der state und damit die Zeitrechnung ändert. Fertig.
FHEM 6.3 auf RaspPi4 (Raspbian:  6.6.28+; Perl: v5.36.0)
SIGNALduino (433 MHz) und HM-UART (868 MHz), Sonoff, Blitzwolf, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann