DOIF: (Verständnis?-) Problem mit wait-timer

Begonnen von Michi240281, 13 März 2015, 14:51:39

Vorheriges Thema - Nächstes Thema

Damian

Zitat von: Michi240281 am 22 März 2015, 11:26:38
Ja offensichtlich kann man das echt nicht sehn!

Hier ein list von gerade:

Internals:
   DEF        ([Abwesend:state] eq "nein" and [Urlaub:state] eq "nein" and [Status_Warmwasser:state] eq "an")
(set Zirkulationspumpe_WW on-for-timer 600)
   NAME       Zirku_Pumpe_auto_neu
   NR         949
   NTFY_ORDER 50-Zirku_Pumpe_auto_neu
   STATE      cmd_1
   TYPE       DOIF
   Readings:
     2015-03-22 10:28:09   cmd_event       Abwesend
     2015-03-22 10:28:09   cmd_nr          1
     2015-03-22 10:58:09   e_Abwesend_state nein
     2015-03-22 09:30:00   e_Status_Warmwasser_state an
     2015-03-19 23:33:43   e_Urlaub_state  nein
     2015-03-22 10:28:09   state           cmd_1
   Condition:
     0          ReadingValDoIf('Abwesend','state','') eq "nein" and ReadingValDoIf('Urlaub','state','') eq "nein" and ReadingValDoIf('Status_Warmwasser','state','') eq "an"
   Devices:
     0           Abwesend Urlaub Status_Warmwasser
     all         Abwesend Urlaub Status_Warmwasser
   Do:
     0          set Zirkulationspumpe_WW on-for-timer 600
   Helper:
     last_timer 0
     sleeptimer -1
   Internals:
   Itimer:
   Readings:
     0           Abwesend:state Urlaub:state Status_Warmwasser:state
     all         Abwesend:state Urlaub:state Status_Warmwasser:state
   State:
   Timerfunc:
   Trigger:
Attributes:
   cmdpause   3600:0
   do         always
   room       Garage,Haus


Nun steht er auf "cmd_1", so wie es sein soll! Offensichtlich ist intern da wirklich noch die cmdPause aktiv!

@Damian:Kannst du helfen?

cmdpause ist im Normalfall nur bei zyklisch sendenden Sensoren sinnvoll, weil in der Pause Trigger einfach ignoriert werden. Für deinen Anwendungsfall also eher ungeeignet.

Gruß

Damian
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Michi240281

FHEM auf QNAP per VM / HM LAN Adapter / diverse HM-Devices
QNAP TVS 463
VU+ Duo4kSE
Sony 75ZD9

Brockmann

Zitat von: Damian am 22 März 2015, 12:38:13
cmdpause ist im Normalfall nur bei zyklisch sendenden Sensoren sinnvoll, weil in der Pause Trigger einfach ignoriert werden. Für deinen Anwendungsfall also eher ungeeignet.

Die Frage ist, warum überhaupt eine Pause auftritt?
Um 09:28:09 ist cmd_2 eingetreten. Das Attribut cmdpause 3600:0 sollte dafür sorgen, dass in diesem Fall KEINE Pause auftritt, oder?

Michi240281

"Cmd_2" tritt ja immer auf, wenn eine der Bedingungen nicht erfüllt ist.

Um 9:30 Uhr wechselte der Status_Warmwasser auf "an", damit wurden dann alle Bedingungen wahr. Der state hätte nun auf "Cmd_1" wechseln müssen. Ist er aber nicht, weil die CmdPause im Hintergrund noch aktiv war vom Abend zuvor, als das letzte Mal "Cmd_1" eingetreten ist. Also ich habe das jetzt nachvollzogen. Abends um 23:28 Uhr waren alle Bedingungen erfüllt. State wechselte auf "Cmd_1". Um 23:30 Uhr ging dann Status_Warmwasser auf "aus". Nun läuft jedoch im Hintergrund die CmdPause von 60 Minuten leider nicht weiter und damit komplett runter, sondern die verbleibenden 58 Minuten, die noch "fehlen", werden morgens, wenn wieder alle Bedingungen wahr sind, noch an das "Cmd_1" drangehängt! Also genau wie ich eingangs vermutete: Die CmdPause wird eingefroren, wenn Cmd_1 nicht anliegt! Das ist die Ursache!

Nun die Frage an Damian: Was kann ich da machen? Eigentlich hatte ich erwartet, dass die timer im Hintergrund einfach ablaufen, aber leider werden sie eingefroren! Kannst du da was am Model ändern oder ein andere Attribut einfügen?
FHEM auf QNAP per VM / HM LAN Adapter / diverse HM-Devices
QNAP TVS 463
VU+ Duo4kSE
Sony 75ZD9

Damian

Zitat von: Michi240281 am 22 März 2015, 14:45:23
"Cmd_2" tritt ja immer auf, wenn eine der Bedingungen nicht erfüllt ist.

Um 9:30 Uhr wechselte der Status_Warmwasser auf "an", damit wurden dann alle Bedingungen wahr. Der state hätte nun auf "Cmd_1" wechseln müssen. Ist er aber nicht, weil die CmdPause im Hintergrund noch aktiv war vom Abend zuvor, als das letzte Mal "Cmd_1" eingetreten ist. Also ich habe das jetzt nachvollzogen. Abends um 23:28 Uhr waren alle Bedingungen erfüllt. State wechselte auf "Cmd_1". Um 23:30 Uhr ging dann Status_Warmwasser auf "aus". Nun läuft jedoch im Hintergrund die CmdPause von 60 Minuten leider nicht weiter und damit komplett runter, sondern die verbleibenden 58 Minuten, die noch "fehlen", werden morgens, wenn wieder alle Bedingungen wahr sind, noch an das "Cmd_1" drangehängt! Also genau wie ich eingangs vermutete: Die CmdPause wird eingefroren, wenn Cmd_1 nicht anliegt! Das ist die Ursache!

Nun die Frage an Damian: Was kann ich da machen? Eigentlich hatte ich erwartet, dass die timer im Hintergrund einfach ablaufen, aber leider werden sie eingefroren! Kannst du da was am Model ändern oder ein andere Attribut einfügen?

Nochmal zum Verständnis: Im Gegensatz zu einem wait ist cmdpause kein Timer. Beim Eintreffen eines Triggers wird die jeweilige Bedingung überprüft. Geschaltet wird allerdings nur, wenn der Zeitstempel des Status von DOIF (also die letzte Änderung) mehr als die Zeitspanne, die bei cmdpause angegeben wurde, zurückliegt - mehr steckt da nicht dahinter. Deswegen ist es für deinen Anwendungsfall ungeeignet, weil deine Trigger keine zyklische Wiederholung haben und daher verloren gehen können, bei Temperatursensoren dagegen, die zyklisch senden, ist das egal.

Gruß

Damian
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Michi240281

Hi Damian,

ok, verstehe! Nur hast du einen Alternativvorschlag? Mit dem Wait Attribut hatte ich genau das gleiche Resultat! :'(
FHEM auf QNAP per VM / HM LAN Adapter / diverse HM-Devices
QNAP TVS 463
VU+ Duo4kSE
Sony 75ZD9

Damian

Zitat von: Michi240281 am 22 März 2015, 22:33:52
Hi Damian,

ok, verstehe! Nur hast du einen Alternativvorschlag? Mit dem Wait Attribut hatte ich genau das gleiche Resultat! :'(

ok, na dann so:

define Zirku_Pumpe_auto DOIF ([Abwesend:state] eq "nein" and [Urlaub:state] eq "nein" and [Status_Warmwasser:state] eq "an")
(set Zirkulationspumpe_WW on-for-timer 300, sleep 3600;trigger Abwesend)
attr zirku_Pumpe_auto do always


Gruß

Damian
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Michi240281

#22
Ok vielen Dank, werde ich testen!

Was bewirkt denn das "trigger Abwesend"? Wäre nämlich ungünstig, wenn er dann nur noch auf "Abwesend" triggered!
FHEM auf QNAP per VM / HM LAN Adapter / diverse HM-Devices
QNAP TVS 463
VU+ Duo4kSE
Sony 75ZD9

flurin

#23
Hallo,

Vorschlag: bei ähnlichen Fällen habe ich es so gelöst:


define Zirku_Pumpe_auto DOIF ([Abwesend:state] eq "ja" or [Urlaub:state] eq "ja") ()
DOELSIF ([Status_Warmwasserpumpe:state:?an] or ([+01:00] and [Status_Warmwasser:state] eq "an"))
(set Zirkulationspumpe_WW on-for-timer 300)
attr Zirku_Pumpe_auto do always


Bei Abwesenheit oder Urlaub wird kein Befehl ausgeführt (leere Klammer), sonst beim Einschalten der "Status_Warmwasserpumpe" wird der Befehl sofort ausgeführt und dann im Stundentakt.

Diese Lösung hat jedoch einen Schönheitsfehler:

Die erste Zeitspanne kann kleiner als eine Stunde sein, danach jedoch regelmässig im Stundentakt.
Bei diesem Fall ist es vermutlich nicht so schlimm, wenn die Pumpe für 5 Min früher eingeschaltet wird.

Gruss
flurin

Michi240281

#24
Zitat von: Damian am 22 März 2015, 22:56:18
ok, na dann so:

define Zirku_Pumpe_auto DOIF ([Abwesend:state] eq "nein" and [Urlaub:state] eq "nein" and [Status_Warmwasser:state] eq "an")
(set Zirkulationspumpe_WW on-for-timer 300, sleep 3600;trigger Abwesend)
attr zirku_Pumpe_auto do always


Moin,

also grundsätzlich hat das heute Morgen funktioniert. Allerdings war die Pause viel zu kurz. Beim ersten Schalten ca. 3,5 Minuten, beim 2. Mal 20 Minuten und dann war die nächste volle Stunde da und es ging wieder mit 3,5 Minuten weiter. Hier mal ein Auszug aus dem log:

2015-03-24_04:14:07 Zirkulationspumpe_WW Status: 0   << addLog
2015-03-24_05:00:00 Zirkulationspumpe_WW set_on-for-timer 600
2015-03-24_05:00:00 Zirkulationspumpe_WW Status: 1
2015-03-24_05:00:00 Zirkulationspumpe_WW level: 100
2015-03-24_05:00:00 Zirkulationspumpe_WW pct: 100
2015-03-24_05:00:00 Zirkulationspumpe_WW deviceMsg: an (to HMLAN1)
2015-03-24_05:00:00 Zirkulationspumpe_WW an
2015-03-24_05:00:00 Zirkulationspumpe_WW timedOn: running
2015-03-24_05:10:04 Zirkulationspumpe_WW level: 0
2015-03-24_05:10:04 Zirkulationspumpe_WW pct: 0
2015-03-24_05:10:04 Zirkulationspumpe_WW deviceMsg: aus (to broadcast)
2015-03-24_05:10:04 Zirkulationspumpe_WW aus
2015-03-24_05:10:04 Zirkulationspumpe_WW timedOn: aus
2015-03-24_05:10:04 Zirkulationspumpe_WW Status: 0
2015-03-24_05:13:55 Zirkulationspumpe_WW set_on-for-timer 600
2015-03-24_05:13:55 Zirkulationspumpe_WW Status: 1
2015-03-24_05:13:55 Zirkulationspumpe_WW level: 100
2015-03-24_05:13:55 Zirkulationspumpe_WW pct: 100
2015-03-24_05:13:55 Zirkulationspumpe_WW deviceMsg: an (to HMLAN1)
2015-03-24_05:13:55 Zirkulationspumpe_WW an
2015-03-24_05:13:55 Zirkulationspumpe_WW timedOn: running
2015-03-24_05:14:07 Zirkulationspumpe_WW Status: 1   << addLog
2015-03-24_05:23:59 Zirkulationspumpe_WW level: 0
2015-03-24_05:23:59 Zirkulationspumpe_WW pct: 0
2015-03-24_05:23:59 Zirkulationspumpe_WW deviceMsg: aus (to broadcast)
2015-03-24_05:23:59 Zirkulationspumpe_WW aus
2015-03-24_05:23:59 Zirkulationspumpe_WW timedOn: aus
2015-03-24_05:23:59 Zirkulationspumpe_WW Status: 0
2015-03-24_05:43:55 Zirkulationspumpe_WW set_on-for-timer 600
2015-03-24_05:43:55 Zirkulationspumpe_WW Status: 1
2015-03-24_05:43:55 Zirkulationspumpe_WW level: 100
2015-03-24_05:43:55 Zirkulationspumpe_WW pct: 100
2015-03-24_05:43:55 Zirkulationspumpe_WW deviceMsg: an (to HMLAN1)
2015-03-24_05:43:55 Zirkulationspumpe_WW an
2015-03-24_05:43:55 Zirkulationspumpe_WW timedOn: running
2015-03-24_05:53:58 Zirkulationspumpe_WW level: 0
2015-03-24_05:53:58 Zirkulationspumpe_WW pct: 0
2015-03-24_05:53:58 Zirkulationspumpe_WW deviceMsg: aus (to broadcast)
2015-03-24_05:53:58 Zirkulationspumpe_WW aus
2015-03-24_05:53:58 Zirkulationspumpe_WW timedOn: aus
2015-03-24_05:53:58 Zirkulationspumpe_WW Status: 0
2015-03-24_06:00:00 Zirkulationspumpe_WW set_on-for-timer 600
2015-03-24_06:00:00 Zirkulationspumpe_WW Status: 1
2015-03-24_06:00:00 Zirkulationspumpe_WW level: 100
2015-03-24_06:00:00 Zirkulationspumpe_WW pct: 100
2015-03-24_06:00:00 Zirkulationspumpe_WW deviceMsg: an (to HMLAN1)
2015-03-24_06:00:00 Zirkulationspumpe_WW an
2015-03-24_06:00:00 Zirkulationspumpe_WW timedOn: running
2015-03-24_06:10:04 Zirkulationspumpe_WW level: 0
2015-03-24_06:10:04 Zirkulationspumpe_WW pct: 0
2015-03-24_06:10:04 Zirkulationspumpe_WW deviceMsg: aus (to broadcast)
2015-03-24_06:10:04 Zirkulationspumpe_WW aus
2015-03-24_06:10:04 Zirkulationspumpe_WW timedOn: aus
2015-03-24_06:10:04 Zirkulationspumpe_WW Status: 0
2015-03-24_06:13:55 Zirkulationspumpe_WW set_on-for-timer 600
2015-03-24_06:13:55 Zirkulationspumpe_WW Status: 1
2015-03-24_06:13:56 Zirkulationspumpe_WW level: 100
2015-03-24_06:13:56 Zirkulationspumpe_WW pct: 100
2015-03-24_06:13:56 Zirkulationspumpe_WW deviceMsg: an (to HMLAN1)
2015-03-24_06:13:56 Zirkulationspumpe_WW an
2015-03-24_06:13:56 Zirkulationspumpe_WW timedOn: running
2015-03-24_06:14:07 Zirkulationspumpe_WW Status: 1   << addLog
2015-03-24_06:23:59 Zirkulationspumpe_WW level: 0
2015-03-24_06:23:59 Zirkulationspumpe_WW pct: 0
2015-03-24_06:23:59 Zirkulationspumpe_WW deviceMsg: aus (to broadcast)
2015-03-24_06:23:59 Zirkulationspumpe_WW aus
2015-03-24_06:23:59 Zirkulationspumpe_WW timedOn: aus
2015-03-24_06:23:59 Zirkulationspumpe_WW Status: 0
2015-03-24_06:43:55 Zirkulationspumpe_WW set_on-for-timer 600
2015-03-24_06:43:55 Zirkulationspumpe_WW Status: 1
2015-03-24_06:43:55 Zirkulationspumpe_WW level: 100
2015-03-24_06:43:55 Zirkulationspumpe_WW pct: 100
2015-03-24_06:43:55 Zirkulationspumpe_WW deviceMsg: an (to HMLAN1)
2015-03-24_06:43:55 Zirkulationspumpe_WW an
2015-03-24_06:43:55 Zirkulationspumpe_WW timedOn: running
2015-03-24_06:53:59 Zirkulationspumpe_WW level: 0
2015-03-24_06:53:59 Zirkulationspumpe_WW pct: 0
2015-03-24_06:53:59 Zirkulationspumpe_WW deviceMsg: aus (to broadcast)
2015-03-24_06:53:59 Zirkulationspumpe_WW aus
2015-03-24_06:53:59 Zirkulationspumpe_WW timedOn: aus
2015-03-24_06:53:59 Zirkulationspumpe_WW Status: 0
2015-03-24_07:00:00 Zirkulationspumpe_WW set_on-for-timer 600
2015-03-24_07:00:00 Zirkulationspumpe_WW Status: 1
2015-03-24_07:00:00 Zirkulationspumpe_WW level: 100
2015-03-24_07:00:00 Zirkulationspumpe_WW pct: 100
2015-03-24_07:00:00 Zirkulationspumpe_WW deviceMsg: an (to HMLAN1)
2015-03-24_07:00:00 Zirkulationspumpe_WW an
2015-03-24_07:00:00 Zirkulationspumpe_WW timedOn: running
2015-03-24_07:10:02 Zirkulationspumpe_WW level: 0
2015-03-24_07:10:02 Zirkulationspumpe_WW pct: 0
2015-03-24_07:10:02 Zirkulationspumpe_WW deviceMsg: aus (to broadcast)
2015-03-24_07:10:02 Zirkulationspumpe_WW aus
2015-03-24_07:10:02 Zirkulationspumpe_WW timedOn: aus
2015-03-24_07:10:02 Zirkulationspumpe_WW Status: 0


Irgendwas scheint mit dem sleep Kommando noch nicht zu stimmen! In der commandref steht, das seien Millisekunden?!?

Zitat von: flurin am 23 März 2015, 22:28:28
Hallo,

Vorschlag: bei ähnlichen Fällen habe ich es so gelöst:


define Zirku_Pumpe_auto DOIF ([Abwesend:state] eq "ja" or [Urlaub:state] eq "ja") ()
DOELSIF ([Status_Warmwasserpumpe:state:?an] or ([+01:00] and [Status_Warmwasser:state] eq "an"))
(set Zirkulationspumpe_WW on-for-timer 300)
attr Zirku_Pumpe_auto do always


Bei Abwesenheit oder Urlaub wird kein Befehl ausgeführt (leere Klammer), sonst beim Einschalten der "Status_Warmwasserpumpe" wird der Befehl sofort ausgeführt und dann im Stundentakt.

Diese Lösung hat jedoch einen Schönheitsfehler:

Die erste Zeitspanne kann kleiner als eine Stunde sein, danach jedoch regelmässig im Stundentakt.
Bei diesem Fall ist es vermutlich nicht so schlimm, wenn die Pumpe für 5 Min früher eingeschaltet wird.

Gruss
flurin

Danke für den Lösungsvorschlag! Habe dazu 2 Fragen:

Was bewirkt denn dann die erste Bedingung? Garnichts, oder? Dann kann man sie doch auch weglassen! Und die 2. Bedingung fragt ja dann nur noch den Status_Warmwasser ab! Aber es soll ja auch nicht geschaltet werden, wenn wir abwesend oder im Urlaub sind?!?
FHEM auf QNAP per VM / HM LAN Adapter / diverse HM-Devices
QNAP TVS 463
VU+ Duo4kSE
Sony 75ZD9

Brockmann

Zitat von: Michi240281 am 24 März 2015, 08:17:09
also grundsätzlich hat das heute Morgen funktioniert. Allerdings war die Pause viel zu kurz. Beim ersten Schalten ca. 3,5 Minuten, beim 2. Mal 20 Minuten und dann war die nächste volle Stunde da und es ging wieder mit 3,5 Minuten weiter.
Der Vorschlag von Damian geht davon aus, dass Abwesend zwischendurch nicht anderweitig getriggert wird. Das scheint mir bei Dir aber der Fall zu sein.
Das Log legt nahe, dass alle 30 Minuten, nämlich jeweils um **:13:55 und **:43:55 der Abwesend-Status gesetzt wird.
Dadurch wird jedes Mal das DOIF getriggert und schaltet die Pumpe ein.

flurin

#26
Zitat von: Michi240281 am 24 März 2015, 08:17:09
Was bewirkt denn dann die erste Bedingung? Garnichts, oder? Dann kann man sie doch auch weglassen! Und die 2. Bedingung fragt ja dann nur noch den Status_Warmwasser ab! Aber es soll ja auch nicht geschaltet werden, wenn wir abwesend oder im Urlaub sind?!?

Nicht ganz, die erste Bedingung (wenn wahr) führt einen leeren Befehl aus und bewirkt, dass das DOELSIF nicht ausgeführt wird.
Somit wird indirekt die Bedingung erfüllt, bei Abwesenheit oder Urlaub die Pumpe nicht zu schalten. Beachte die Abfrage auf "ja" sowie "or". Das ist wie "if, elsif und else" in Perl. Siehe auch die DOIF Dokumentation:

Zitat
Es wird immer nur ein Kommando ausgeführt, und zwar das erste, für das die dazugehörige Bedingung in der abgearbeiteten Reihenfolge wahr ist

Edit: es geht doch nicht! ... work-in-progress

Brockmann

Zitat von: flurin am 24 März 2015, 09:05:45
Nicht ganz, die erste Bedingung (wenn wahr) führt einen leeren Befehl aus und bewirkt, dass das DOELSIF nicht ausgeführt wird.
Somit wird indirekt die Bedingung erfüllt, bei Abwesenheit oder Urlaub die Pumpe nicht zu schalten. Beachte die Abfrage auf "ja" sowie "or". Das ist wie "if, elsif und else" in Perl. Siehe auch die DOIF Dokumentation:

Wenn Du bei Deinem Zitat der Commandref den anschließenden Satz nicht abgeschnitten hättest, würdest Du das Problem erkennen:
Zitat von: CommanrefHinzu kommt, dass nur die Bedingungen überprüft werden, die zum ausgelösten Event auch das Device beinhalten.

Wenn morgens um 5:00 Uhr (oder wann auch immer) Status_Warmwasserpumpe auf "an" geht, würde bei Deinem DOIF gar nicht geprüft werden, wie Abwesenheit und Urlaub gerade belegt sind, weil die erste Bedingung gar nicht getriggert wird. Man müsste zumindest [Status_Warmwasserpumpe] schon noch mit in die Bedingung einfügen, damit diese auch getriggert wird.

flurin

Zitat von: Brockmann am 24 März 2015, 11:08:56
Wenn Du bei Deinem Zitat der Commandref den anschließenden Satz nicht abgeschnitten hättest, würdest Du das Problem erkennen:
Wenn morgens um 5:00 Uhr (oder wann auch immer) Status_Warmwasserpumpe auf "an" geht, würde bei Deinem DOIF gar nicht geprüft werden, wie Abwesenheit und Urlaub gerade belegt sind, weil die erste Bedingung gar nicht getriggert wird. Man müsste zumindest [Status_Warmwasserpumpe] schon noch mit in die Bedingung einfügen, damit diese auch getriggert wird.

Richtig! ich arbeite daran.

Damian

Zitat von: Brockmann am 24 März 2015, 08:53:10
Der Vorschlag von Damian geht davon aus, dass Abwesend zwischendurch nicht anderweitig getriggert wird. Das scheint mir bei Dir aber der Fall zu sein.
Das Log legt nahe, dass alle 30 Minuten, nämlich jeweils um **:13:55 und **:43:55 der Abwesend-Status gesetzt wird.
Dadurch wird jedes Mal das DOIF getriggert und schaltet die Pumpe ein.
Dann muss man es entkoppeln:

define Zirku_Pumpe_auto DOIF ([Abwesend:state] eq "nein" and [Urlaub:state] eq "nein" and [Status_Warmwasser:state] eq "an")
attr zirku_Pumpe_auto state on|off


und

define di_Zirku_Pumpe_on DOIF ([Zirku_Pumpe_auto] eq "on") (set Zirkulationspumpe_WW on-for-timer 300, sleep 3600;trigger di_Zirku_Pumpe_on)
attr di_Zirku_Pumpe_on do always


Gruß

Damian
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF