Hallo,
ich habe ein DOIF GEN_RolloTimerHoch mit folgender DEF definiert:
([{time_num2str(timespan2seconds(sunrise_abs(+900,"06:00","08:00"))-int(rand(120)))}|8] or [{time_num2str(timespan2seconds(sunrise_abs(+900,"07:30","08:30"))-int(rand(120)))}|7]) ({GenRolloSet("on")})
Die Perlfunktionen funktionieren einwandfrei - hier wird von der von sunrise_abs errechneten Zeit nochmal ein Zufallswert von 0-120 Sekunden abgezogen. An Wochentagen zwischen 6 und 8 Uhr, an Wochenenden zwischen 7.30 und 8.30 Uhr.
Die Perlfunktion GenRolloSet steuert Rolladenaktoren und definiert ein at +00:02:00 mit einer Überprüfung. Klappt auch.
Was mich erstaunt, ist die Tatsache, dass die tatsächlichen Ausführungszeiten von DOIF irgendwie nicht so richtig nachvollziehbar sind. Beispielsweise wurde heute morgen gemäß den Readings um 05:59:52 Uhr das cmd_1 ausgeführt und die Timer wurden neu gesetzt. Aber laut Logfile wurde auch bereits um 05:58:02 Uhr und um 05:58:30 Uhr die Funktion bereits aufgerufen - und das kann nur durch das DOIF passiert sein. Warum ist das so?
fhem-Log:
2015.04.29 05:58:05 3: GenRolloSet ("on")
2015.04.29 05:58:05 3: CUL_HM set GWC_Rollo on
2015.04.29 05:58:05 3: GenRolloSet GWC_Rollo Check set
2015.04.29 05:58:05 3: CUL_HM set ASR_Rollo_Links on
2015.04.29 05:58:05 3: GenRolloSet ASR_Rollo_Links Check set
2015.04.29 05:58:05 3: CUL_HM set ASR_Rollo_Rechts on
2015.04.29 05:58:05 3: GenRolloSet ASR_Rollo_Rechts Check set
2015.04.29 05:58:05 3: GenRolloSet CheckGenRolloSet with GenRolloSet ("on") defined
2015.04.29 05:58:30 3: GenRolloSet ("on")
2015.04.29 05:58:30 3: CUL_HM set GWC_Rollo on
2015.04.29 05:58:30 3: GenRolloSet GWC_Rollo Check set
2015.04.29 05:58:30 3: CUL_HM set ASR_Rollo_Links on
2015.04.29 05:58:30 3: GenRolloSet ASR_Rollo_Links Check set
2015.04.29 05:58:30 3: CUL_HM set ASR_Rollo_Rechts on
2015.04.29 05:58:30 3: GenRolloSet ASR_Rollo_Rechts Check set
2015.04.29 05:58:31 3: GenRolloSet CheckGenRolloSet with GenRolloSet ("on") defined
2015.04.29 05:59:52 3: GenRolloSet ("on")
2015.04.29 05:59:52 3: GenRolloSet Nothing to do, already at on
DOIF-Log:
2015-04-29 05:58:05 GEN_RolloTimerHoch DOIF cmd_nr: 1 cmd_nr 1
2015-04-29 05:58:05 GEN_RolloTimerHoch DOIF cmd_event: timer_1 cmd_event timer_1
2015-04-29 05:58:05 GEN_RolloTimerHoch DOIF cmd_1 state cmd_1
2015-04-29 05:58:31 GEN_RolloTimerHoch DOIF cmd_nr: 1 cmd_nr 1
2015-04-29 05:58:31 GEN_RolloTimerHoch DOIF cmd_event: timer_1 cmd_event timer_1
2015-04-29 05:58:31 GEN_RolloTimerHoch DOIF cmd_1 state cmd_1
2015-04-29 05:59:52 GEN_RolloTimerHoch DOIF cmd_nr: 1 cmd_nr 1
2015-04-29 05:59:52 GEN_RolloTimerHoch DOIF cmd_event: timer_1 cmd_event timer_1
2015-04-29 05:59:52 GEN_RolloTimerHoch DOIF cmd_1 state cmd_1
DOIF-list:
Internals:
DEF ([{time_num2str(timespan2seconds(sunrise_abs(+900,"06:00","08:00"))-int(rand(120)))}|8] or [{time_num2str(timespan2seconds(sunrise_abs(+900,"07:30","08:30"))-int(rand(120)))}|7]) ({GenRolloSet("on")})
NAME GEN_RolloTimerHoch
NR 502
NTFY_ORDER 50-GEN_RolloTimerHoch
STATE cmd_1
TYPE DOIF
CHANGETIME:
Helper:
Dblog:
Cmd_event:
Eventlog:
TIME 1430279992.28974
VALUE timer_1
Cmd_nr:
Eventlog:
TIME 1430279992.28974
VALUE 1
State:
Eventlog:
TIME 1430279992.28974
VALUE cmd_1
Readings:
2015-04-29 05:59:52 cmd_event timer_1
2015-04-29 05:59:52 cmd_nr 1
2015-04-29 05:59:52 state cmd_1
2015-04-29 05:59:52 timer_1_c1 30.04.2015 05:58:02|8
2015-04-29 07:29:38 timer_2_c1 30.04.2015 07:29:07|7
Condition:
0 DOIF_time_once($hash->{timer}{0},$wday,"8") or DOIF_time_once($hash->{timer}{1},$wday,"7")
Days:
0 8
1 7
Devices:
Do:
0 {GenRolloSet("on")}
Helper:
last_timer 2
sleeptimer -1
Internals:
Itimer:
Readings:
Realtime:
0 05:58:02
1 07:29:07
State:
Time:
0 {time_num2str(timespan2seconds(sunrise_abs(+900,"06:00","08:00"))-int(rand(120)))}
1 {time_num2str(timespan2seconds(sunrise_abs(+900,"07:30","08:30"))-int(rand(120)))}
Timecond:
0 0
1 0
Timer:
0 0
1 0
Timerfunc:
Timers:
0 0 1
Attributes:
do always
group Timer
room System
Zitat von: Ralli am 29 April 2015, 08:28:14
Hallo,
ich habe ein DOIF GEN_RolloTimerHoch mit folgender DEF definiert:
([{time_num2str(timespan2seconds(sunrise_abs(+900,"06:00","08:00"))-int(rand(120)))}|8] or [{time_num2str(timespan2seconds(sunrise_abs(+900,"07:30","08:30"))-int(rand(120)))}|7]) ({GenRolloSet("on")})
Die Perlfunktionen funktionieren einwandfrei - hier wird von der von sunrise_abs errechneten Zeit nochmal ein Zufallswert von 0-120 Sekunden abgezogen. An Wochentagen zwischen 6 und 8 Uhr, an Wochenenden zwischen 7.30 und 8.30 Uhr.
Die Perlfunktion GenRolloSet steuert Rolladenaktoren und definiert ein at +00:02:00 mit einer Überprüfung. Klappt auch.
Was mich erstaunt, ist die Tatsache, dass die tatsächlichen Ausführungszeiten von DOIF irgendwie nicht so richtig nachvollziehbar sind. Beispielsweise wurde heute morgen gemäß den Readings um 05:59:52 Uhr das cmd_1 ausgeführt und die Timer wurden neu gesetzt. Aber laut Logfile wurde auch bereits um 05:58:02 Uhr und um 05:58:30 Uhr die Funktion bereits aufgerufen - und das kann nur durch das DOIF passiert sein. Warum ist das so?
1. Das kannst du auch entsprechend einfacher definieren, siehe Beispiele in der Commanderf zu Berechnung von Zeiten, hier:
DOIF ([({sunrise_abs(+900,"06:00","08:00")}-int(rand(120)))|8] or [({sunrise_abs(+900,"07:30","08:30")}-int(rand(120)))|7]) ({GenRolloSet("on")})
2. Die Vorgehensweise ist die folgende:
Das Modul wird zum errechneten Zeitpunkt (Realtime) immer getriggert, daraufhin wird die Bedingung überprüft und falls sie wahr ist wird der Befehl ausgeführt. Gleichzeitig wird die Zeit durch die angegebene Funktion neu berechnet und für den nächsten Trigger gesetzt.
Da du eine Zufallszahl abziehst, sollte der nächste Zeitpunkt in der Tagszeit zurückliegen und erst am nächsten Tag zuschlagen. Wenn die Tage kürzer werden könnte es durchaus passieren, dass der nächste Trigger ein paar Minuten später zuschlägt, weil der Sonnenaufgang später ist. Hier kann ich mir das allerdings nicht erklären. Du musst genauer die Realtimer beobachten (kurz vor und nach dem Ausführen).
Wegen der Problematik im Herbst wenn die Tage kürzer werden, würde ich immer für die gegenteilige Aktion (z. b. runter) einen DOELSE-Fall definieren und ohne do always arbeiten. Dann wird ein Befehl nur dann wiederholt ausgeführt, hier: hochgefahren, wenn zwischendurch durch den DOELSE-Fall runter gefahren wurde.
Edit: lt. Log kommt der wiederholte Trigger immer vom ersten Timer, ich würde hier evtl. auf irgendwelche Zeitdifferenzen bedingt durch "time_num2str(timespan2seconds(..." tippen. Ich würde meinen obigen Lösungsvorschlag ohne das unnötige Hin- und Herrechnen ausprobieren.
Gruß
Damian
Danke, Damian. Ich werde das DOIF entsprechend Deinem Vorschlag ändern und beobachten bzw. rückmelden.
Edit: Nach der Änderung gemäß Deinem Hinweis ist das DOIF heute morgen wie erwartet gelaufen :). Danke.
Hallo Damian,
leider ist das Problem doch nicht nicht wirklich gelöst. Heute ist das Phänomen wieder aufgetreten, das cmd_1 wurde zweimal getriggert:
Das DOIF ist nun gemäß Deiner Empfehlung wie folgt definiert:
define GEN_RolloTimerHoch DOIF ([({sunrise_abs(+900,"06:00","08:00")}-int(rand(120)))|8] or [({sunrise_abs(+900,"07:30","08:30")}-int(rand(120)))|7]) ({GenRolloSet("on")})
Das DOIF-List:
Internals:
DEF ([({sunrise_abs(+900,"06:00","08:00")}-int(rand(120)))|8] or [({sunrise_abs(+900,"07:30","08:30")}-int(rand(120)))|7]) ({GenRolloSet("on")})
NAME GEN_RolloTimerHoch
NR 502
NTFY_ORDER 50-GEN_RolloTimerHoch
STATE cmd_1
TYPE DOIF
CHANGETIME:
Helper:
Dblog:
Cmd_event:
Eventlog:
TIME 1430630991.17495
VALUE timer_2
Cmd_nr:
Eventlog:
TIME 1430630991.17495
VALUE 1
State:
Eventlog:
TIME 1430630991.17495
VALUE cmd_1
Readings:
2015-05-03 07:29:51 cmd_event timer_2
2015-05-03 07:29:51 cmd_nr 1
2015-05-03 07:29:51 state cmd_1
2015-05-03 05:59:17 timer_1_c1 04.05.2015 05:58:36|8
2015-05-03 07:29:51 timer_2_c1 04.05.2015 07:29:02|7
Condition:
0 DOIF_time_once($hash->{timer}{0},$wday,"8") or DOIF_time_once($hash->{timer}{1},$wday,"7")
Days:
0 8
1 7
Devices:
Do:
0 {GenRolloSet("on")}
Helper:
last_timer 2
sleeptimer -1
Internals:
Itimer:
Readings:
Realtime:
0 05:58:36
1 07:29:02
State:
Time:
0 ({sunrise_abs(+900,"06:00","08:00")}-int(rand(120)))
1 ({sunrise_abs(+900,"07:30","08:30")}-int(rand(120)))
Timecond:
0 0
1 0
Timer:
0 0
1 0
Timerfunc:
Timers:
0 0 1
Attributes:
do always
group Timer
room System
Das DOIF-Log:
2015-05-03 07:29:51 GEN_RolloTimerHoch DOIF cmd_nr: 1 cmd_nr 1
2015-05-03 07:29:51 GEN_RolloTimerHoch DOIF cmd_event: timer_2 cmd_event timer_2
2015-05-03 07:29:51 GEN_RolloTimerHoch DOIF cmd_1 state cmd_1
2015-05-03 07:28:10 GEN_RolloTimerHoch DOIF cmd_nr: 1 cmd_nr 1
2015-05-03 07:28:10 GEN_RolloTimerHoch DOIF cmd_event: timer_2 cmd_event timer_2
2015-05-03 07:28:10 GEN_RolloTimerHoch DOIF cmd_1 state cmd_1
Zitat von: Ralli am 03 Mai 2015, 07:39:06
Hallo Damian,
leider ist das Problem doch nicht nicht wirklich gelöst. Heute ist das Phänomen wieder aufgetreten, das cmd_1 wurde zweimal getriggert:
Das DOIF ist nun gemäß Deiner Empfehlung wie folgt definiert:
define GEN_RolloTimerHoch DOIF ([({sunrise_abs(+900,"06:00","08:00")}-int(rand(120)))|8] or [({sunrise_abs(+900,"07:30","08:30")}-int(rand(120)))|7]) ({GenRolloSet("on")})
Das DOIF-List:
Internals:
DEF ([({sunrise_abs(+900,"06:00","08:00")}-int(rand(120)))|8] or [({sunrise_abs(+900,"07:30","08:30")}-int(rand(120)))|7]) ({GenRolloSet("on")})
NAME GEN_RolloTimerHoch
NR 502
NTFY_ORDER 50-GEN_RolloTimerHoch
STATE cmd_1
TYPE DOIF
CHANGETIME:
Helper:
Dblog:
Cmd_event:
Eventlog:
TIME 1430630991.17495
VALUE timer_2
Cmd_nr:
Eventlog:
TIME 1430630991.17495
VALUE 1
State:
Eventlog:
TIME 1430630991.17495
VALUE cmd_1
Readings:
2015-05-03 07:29:51 cmd_event timer_2
2015-05-03 07:29:51 cmd_nr 1
2015-05-03 07:29:51 state cmd_1
2015-05-03 05:59:17 timer_1_c1 04.05.2015 05:58:36|8
2015-05-03 07:29:51 timer_2_c1 04.05.2015 07:29:02|7
Condition:
0 DOIF_time_once($hash->{timer}{0},$wday,"8") or DOIF_time_once($hash->{timer}{1},$wday,"7")
Days:
0 8
1 7
Devices:
Do:
0 {GenRolloSet("on")}
Helper:
last_timer 2
sleeptimer -1
Internals:
Itimer:
Readings:
Realtime:
0 05:58:36
1 07:29:02
State:
Time:
0 ({sunrise_abs(+900,"06:00","08:00")}-int(rand(120)))
1 ({sunrise_abs(+900,"07:30","08:30")}-int(rand(120)))
Timecond:
0 0
1 0
Timer:
0 0
1 0
Timerfunc:
Timers:
0 0 1
Attributes:
do always
group Timer
room System
Das DOIF-Log:
2015-05-03 07:29:51 GEN_RolloTimerHoch DOIF cmd_nr: 1 cmd_nr 1
2015-05-03 07:29:51 GEN_RolloTimerHoch DOIF cmd_event: timer_2 cmd_event timer_2
2015-05-03 07:29:51 GEN_RolloTimerHoch DOIF cmd_1 state cmd_1
2015-05-03 07:28:10 GEN_RolloTimerHoch DOIF cmd_nr: 1 cmd_nr 1
2015-05-03 07:28:10 GEN_RolloTimerHoch DOIF cmd_event: timer_2 cmd_event timer_2
2015-05-03 07:28:10 GEN_RolloTimerHoch DOIF cmd_1 state cmd_1
ja, es liegt tatsächlich an der Zufallsberechnung. Denn auch wenn man eine zufällige Zahl abzieht, kann es passieren, dass man zuerst etwas mehr abzieht und dann etwas weniger, dadurch ist die zweite Zeit etwas später als die erste - das Modul schaltet zwei mal.
Wenn man mit Zeitintervallen ohne do always arbeitet sollte es nicht passieren können, z. B.
([({sunrise_abs(+900,"06:00","08:00")}-int(rand(120)))-10:00|8] or [({sunrise_abs(+900,"07:30","08:30")}-int(rand(120)))-10:00|7])
ohne do always wird eine Wiederholung unterdrückt, das nächste Schalten wird erst um 10:00 Uhr möglich und damit erst am nächsten Tag, weil dann das Modul in den Zustand cmd_2 wechselt, weil dann die Bedingung nicht mehr wahr ist.
Statt 10:00 Uhr könntest du auch gleich die Zeit für das Herunterfahren definieren, falls du es automatisieren wolltest.
Gruß
Damian
Evtl. geht es so:
define GEN_RolloTimerHoch DOIF ([({sunrise_abs(int(780+rand(120)),"06:00","08:00")})|8] or [({sunrise_abs(int(780+rand(120)),"07:30","08:30")})|7]) ({GenRolloSet("on")})
Offset = zwischen 780 und 900
Gruss
flurin
Zitat von: flurin am 03 Mai 2015, 12:37:10
Evtl. geht es so:
define GEN_RolloTimerHoch DOIF ([({sunrise_abs(int(780+rand(120)),"06:00","08:00")})|8] or [({sunrise_abs(int(780+rand(120)),"07:30","08:30")})|7]) ({GenRolloSet("on")})
Offset = zwischen 780 und 900
Gruss
flurin
Ändert nichts am Problem.
Annahme:
Bei erster Berechnung: rand(120)=0
Bei zweiter Berechnung rand(120)=10
Zuerst wird Verzögerung von 780 berechnet danach 790, damit schaltet das Modul zwei mal im Abstand von 10 Sekunden.
Gruß
Damian
Zitat von: Damian am 03 Mai 2015, 12:45:34
Ändert nichts am Problem.
Annahme:
Bei erster Berechnung: rand(120)=0
Bei zweiter Berechnung rand(120)=10
Zuerst wird Verzögerung von 780 berechnet danach 790, damit schaltet das Modul zwei mal im Abstand von 10 Sekunden.
Gruß
Damian
Dann würde ich offset nur einmal berechnen:
define di_sunrise_time DOIF ([{sunrise_abs()}]) ({my $var = int(780+rand(120));; fhem("setreading di_sunrise_time offset $var")})
attr di_sunrise_time do always
define GEN_RolloTimerHoch DOIF ([({sunrise_abs([di_sunrise_time:offset],"06:00","08:00")})|8] or [({sunrise_abs([di_sunrise_time:offset],"07:30","08:30")})|7]) ({GenRolloSet("on")})
Gruss
flurin
Und wenn ich noch ein
attr GEN_RolloTimerHoch repeatsame 1
attr GEN_RolloTimerHoch cmdpause 120
verbunden mit dem do always setze?
Zitat von: Ralli am 03 Mai 2015, 13:31:47
Und wenn ich noch ein
attr GEN_RolloTimerHoch repeatsame 1
attr GEN_RolloTimerHoch cmdpause 120
verbunden mit dem do always setze?
repeatsame ist schlecht - du hast nur einen Fall und damit keinen Zustandswechsel, der repeatsame zurücksetzen würde.
cmdpause könnte dagegen helfen.
Gruß
Damian
Zitat von: flurin am 03 Mai 2015, 13:19:09
Dann würde ich offset nur einmal berechnen:
define di_sunrise_time DOIF ([{sunrise_abs()}]) ({my $var = int(780+rand(120));; fhem("setreading di_sunrise_time offset $var")})
attr di_sunrise_time do always
define GEN_RolloTimerHoch DOIF ([({sunrise_abs([di_sunrise_time:offset],"06:00","08:00")})|8] or [({sunrise_abs([di_sunrise_time:offset],"07:30","08:30")})|7]) ({GenRolloSet("on")})
Gruss
flurin
ja. Damit braucht man allerdings schon zwei Module - macht die Sache nicht gerade einfacher. Man bräuchte (wenn es das noch nicht gibt) eine sunrise-Funktion, die eine Unix-Zeit des nächsten Sonnenaufgangs liefert.
Dann würde schon ausreichen:
DOIF ([+(sunrise()-time())|8])...
Allerdings werden die Lösungen nicht verständlicher. Ich würde es als Intervall angeben, wie in der Commandef vorgeschlagen. Denn das Problem hat man grundsätzlich auch bei abnehmender Tagesdauer und bei zunehmender Tagesdauer bei sunset.
Langfristig will ich DOIF um Datumsangaben erweitern, dann würde auch vernünftig sunset und sunrise mit kompletter Zeit und Datumsangabe funktionieren.
Gruß
Damian
Zitat von: Damian am 03 Mai 2015, 14:08:08
ja. Damit braucht man allerdings schon zwei Module - macht die Sache nicht gerade einfacher. Man bräuchte (wenn es das noch nicht gibt) eine sunrise-Funktion, die eine Unix-Zeit des nächsten Sonnenaufgangs liefert.
Dann würde schon ausreichen:
DOIF ([+(sunrise()-time())|8])...
Allerdings werden die Lösungen nicht verständlicher. Ich würde es als Intervall angeben, wie in der Commandef vorgeschlagen. Denn das Problem hat man grundsätzlich auch bei abnehmender Tagesdauer und bei zunehmender Tagesdauer bei sunset.
Langfristig will ich DOIF um Datumsangaben erweitern, dann würde auch vernünftig sunset und sunrise mit kompletter Zeit und Datumsangabe funktionieren.
Gruß
Damian
Und noch ein Lösungsvorschlag:
DOIF ([+({sunrise_rel()}+int(rand(120)))])....
hier wird auf jeden Fall erst der morgige Zeitpunkt gesetzt.
Gruß
Damian
Zitat von: Damian am 03 Mai 2015, 14:23:03
Und noch ein Lösungsvorschlag:
DOIF ([+({sunrise_rel()}+int(rand(120)))])....
hier wird auf jeden Fall erst der morgige Zeitpunkt gesetzt.
Gruß
Damian
oder mit sleep:
define GEN_RolloTimerHoch DOIF ([({sunrise_abs(0,"06:00","08:00")})|8] or [({sunrise_abs(0,"07:30","08:30")})|7])
(my $offset = int(780+rand(120));;fhem("sleep $offset");;GenRolloSet("on")})
Gruss
flurin
Zitat von: flurin am 03 Mai 2015, 15:42:04
oder mit sleep:
define GEN_RolloTimerHoch DOIF ([({sunrise_abs(0,"06:00","08:00")})|8] or [({sunrise_abs(0,"07:30","08:30")})|7])
(my $offset = int(780+rand(120));;fhem("sleep $offset");;GenRolloSet("on")})
Gruss
flurin
Hilft nur nichts, wenn die Tage kürzer werden ;)
Gruß
Damian
Zitat von: Damian am 03 Mai 2015, 16:59:43
Hilft nur nichts, wenn die Tage kürzer werden ;)
Ja, einfach ist das Problem nicht zu lösen. Einen Vorschlag habe ich noch:
define du_sunrise dummy
define GEN_RolloTimerHoch DOIF ([01:00])
({my $sr8 = sunrise_abs(int(780+rand(120)),"06:00","08:00");;
fhem("setreading du_sunrise sr8 $sr8");;
my $sr7 = sunrise_abs(int(780+rand(120)),"07:30","08:30");;
fhem("setreading du_sunrise sr7 $sr7")})
DOELSEIF ([[du_sunrise:sr8]|8] or [[du_sunrise:sr7]|7])
({GenRolloSet("on")})
attr GEN_RolloTimerHoch do always
Gruss
flurin
Zitat von: flurin am 03 Mai 2015, 20:07:42
Ja, einfach ist das Problem nicht zu lösen. Einen Vorschlag habe ich noch:
define du_sunrise dummy
define GEN_RolloTimerHoch DOIF ([01:00])
({my $sr8 = sunrise_abs(int(780+rand(120)),"06:00","08:00");;
fhem("setreading du_sunrise sr8 $sr8");;
my $sr7 = sunrise_abs(int(780+rand(120)),"07:30","08:30");;
fhem("setreading du_sunrise sr7 $sr7")})
DOELSEIF ([[du_sunrise:sr8]|8] or [[du_sunrise:sr7]|7])
({GenRolloSet("on")})
attr GEN_RolloTimerHoch do always
Gruss
flurin
Klar. Alles, was mehr ist als ein Einzeiler, ist schon zu viel für dieses simple Vorhaben.
Gruß
Damian
Zitat von: Damian am 03 Mai 2015, 20:39:35
Klar. Alles, was mehr ist als ein Einzeiler, ist schon zu viel für dieses simple Vorhaben.
Gruß
Damian
Ich finde diese Version gar nicht so schlimm:
define GEN_RolloTimerHoch DOIF ([+({sunrise_rel(+900,"06:00","08:00")}-int(rand(120)))|8] or [+({sunrise_rel(+900,"07:30","08:30")}-int(rand(120)))|7]) ({GenRolloSet("on")})
Es sind ja nur zwei (Plus-)Zeichen mehr gegenüber der ursprüngliche Version ;)
Gruß
Damian
Danke danke danke für Eure rege Beteiligung :).
Ich werde berichten.
Zitat von: Damian am 03 Mai 2015, 20:47:06
Ich finde diese Version gar nicht so schlimm:
define GEN_RolloTimerHoch DOIF ([+({sunrise_rel(+900,"06:00","08:00")}-int(rand(120)))|8] or [+({sunrise_rel(+900,"07:30","08:30")}-int(rand(120)))|7]) ({GenRolloSet("on")})
Es sind ja nur zwei (Plus-)Zeichen mehr gegenüber der ursprüngliche Version ;)
Gruß
Damian
Ein echter Einzeiler ist für mich eine Zeile mit max 80-100 Zeichen :)
Grundsätzlich versuche ich fhem.cfg zu "entlasten".
Der Perl-Code oberer Variante lässt sich einfach auslagern:
sub set_time($)
{
my ($du_sunrise) = @_;
my $offset = int(780+rand(120));
my $sr_time;
my @now = localtime;
if ($now[6] == 0 or $now[6] == 6) {
$sr_time = sunrise_abs($offset,"06:00","08:00");
} else {
$sr_time = sunrise_abs($offset,"07:30","08:30");
}
fhem("setreading $du_sunrise state $sr_time");
}
und dann kann man einen echten Einzeiler definieren:
define GEN_RolloTimerHoch DOIF ([01:00]) ({set_time("du_sunrise")}) DOELSEIF ([[du_sunrise]]) ({GenRolloSet("on")})
Gruss
flurin
Hallo,
jetzt ist ein anderes Problem aufgetreten: error: null is not allowed on a relative time bei timer2 - und das, obwohl das ganze jetzt schon zwei Tage lief. Und wenn ich die Definition ohne eine Änderung neu abspeichere, wird der Timer auch wieder korrekt berechnet.
Internals:
DEF ([+{sunrise_rel(+900)}]) ({FlRolloSet("on")}) DOELSEIF ([+({sunset_rel(-600,"18:00","22:00")}-int(rand(120)))]) ({FlRolloSet("off")})
NAME FL_RolloTimer
NR 538
NTFY_ORDER 50-FL_RolloTimer
STATE cmd_1
TYPE DOIF
CHANGETIME:
Helper:
Dblog:
Cmd_event:
Eventlog:
TIME 1430969517.38112
VALUE timer_1
Cmd_nr:
Eventlog:
TIME 1430969517.38112
VALUE 1
State:
Eventlog:
TIME 1430969517.38112
VALUE cmd_1
Readings:
2015-05-07 05:31:57 cmd_event timer_1
2015-05-07 05:31:57 cmd_nr 1
2015-05-07 05:31:57 state cmd_1
2015-05-07 05:31:57 timer_1_c1 08.05.2015 05:30:05
2015-05-06 21:22:51 timer_2_c2 error: null is not allowed on a relative time
Condition:
0 DOIF_time_once($hash->{timer}{0},$wday,"")
1 DOIF_time_once($hash->{timer}{1},$wday,"")
Days:
Devices:
Do:
0 {FlRolloSet("on")}
1 {FlRolloSet("off")}
Helper:
last_timer 2
sleeptimer -1
Internals:
Itimer:
Readings:
Realtime:
0 05:30:05
1 00:00:00
State:
Time:
0 +{sunrise_rel(+900)}
1 +({sunset_rel(-600,"18:00","22:00")}-int(rand(120)))
Timecond:
0 0
1 1
Timer:
0 0
1 0
Timerfunc:
Timers:
0 0
1 1
Attributes:
group Timer
room System
Diese Fehlermeldung ist bei all meinen DOIF-Timern mit sunset_rel so aufgetreten und genau so nach Neu-Abspeichern auch nicht mehr da.
Edit:
Ich bin jetzt wieder von den relativen Timern zu absoluten Timern gewechselt und setze cmdpause 120 ein. Nach meinem Verständnis dürfte so vermieden werden, dass innerhalb von 2 Minuten das cmd mehr als einmal ausgeführt wird, wenn der Timer durch Neuberechnung erneut triggern sollte.
Zitat von: Ralli am 07 Mai 2015, 06:01:24
Hallo,
jetzt ist ein anderes Problem aufgetreten: error: null is not allowed on a relative time bei timer2 - und das, obwohl das ganze jetzt schon zwei Tage lief. Und wenn ich die Definition ohne eine Änderung neu abspeichere, wird der Timer auch wieder korrekt berechnet.
Internals:
DEF ([+{sunrise_rel(+900)}]) ({FlRolloSet("on")}) DOELSEIF ([+({sunset_rel(-600,"18:00","22:00")}-int(rand(120)))]) ({FlRolloSet("off")})
NAME FL_RolloTimer
NR 538
NTFY_ORDER 50-FL_RolloTimer
STATE cmd_1
TYPE DOIF
CHANGETIME:
Helper:
Dblog:
Cmd_event:
Eventlog:
TIME 1430969517.38112
VALUE timer_1
Cmd_nr:
Eventlog:
TIME 1430969517.38112
VALUE 1
State:
Eventlog:
TIME 1430969517.38112
VALUE cmd_1
Readings:
2015-05-07 05:31:57 cmd_event timer_1
2015-05-07 05:31:57 cmd_nr 1
2015-05-07 05:31:57 state cmd_1
2015-05-07 05:31:57 timer_1_c1 08.05.2015 05:30:05
2015-05-06 21:22:51 timer_2_c2 error: null is not allowed on a relative time
Condition:
0 DOIF_time_once($hash->{timer}{0},$wday,"")
1 DOIF_time_once($hash->{timer}{1},$wday,"")
Days:
Devices:
Do:
0 {FlRolloSet("on")}
1 {FlRolloSet("off")}
Helper:
last_timer 2
sleeptimer -1
Internals:
Itimer:
Readings:
Realtime:
0 05:30:05
1 00:00:00
State:
Time:
0 +{sunrise_rel(+900)}
1 +({sunset_rel(-600,"18:00","22:00")}-int(rand(120)))
Timecond:
0 0
1 1
Timer:
0 0
1 0
Timerfunc:
Timers:
0 0
1 1
Attributes:
group Timer
room System
Diese Fehlermeldung ist bei all meinen DOIF-Timern mit sunset_rel so aufgetreten und genau so nach Neu-Abspeichern auch nicht mehr da.
Edit:
Ich bin jetzt wieder von den relativen Timern zu absoluten Timern gewechselt und setze cmdpause 120 ein. Nach meinem Verständnis dürfte so vermieden werden, dass innerhalb von 2 Minuten das cmd mehr als einmal ausgeführt wird, wenn der Timer durch Neuberechnung erneut triggern sollte.
Ja, auch bei rel-Angaben gibt es das gleiche Problem. Jetzt werden die Tage länger, damit wird täglich der Sonnenuntergang einige Sekunden später berechnet. Bei rel-Angaben wird offenbar, wenn der nächste Zeitpunkt auch nur paar Sekunden später liegt nicht der nächste Tag (wie ich vermutet hatte) bestimmt, sondern offenbar wie bei abs der gleiche. Zusätzlich kann bei DOIF bei relativen Angaben 0 Sekunden durch die Berechnung herauskommen und das führt zur Meldung.
Da du jetzt aber sunrise und sunset in einem Modul hast, kannst du mit _abs-Funktionen arbeiten und do always, wie ich schon geschrieben habe, rausnehmen. Damit wird das doppelte Schalten automatisch vom DOIF-Modul unterbunden.
Gruß
Damian
Danke für Deine Rückmeldung.
Gibt es einen Unterschied zwischen sunset und sunset_abs bzw. sunrise und sunrise_abs?
Zitat von: Ralli am 07 Mai 2015, 12:09:45
Danke für Deine Rückmeldung.
Gibt es einen Unterschied zwischen sunset und sunset_abs bzw. sunrise und sunrise_abs?
Genaue Details zu den einzelnen Funktionen kenne ich auch nicht (nur das, was in der Commandref steht). Der Maintainer ist Rudolf König.
Gruß
Damian