repeatcmd verhält sich in Kombination mit wait nicht wie erwartet

Begonnen von weini, 28 Februar 2016, 10:29:32

Vorheriges Thema - Nächstes Thema

weini

Hallo zusammen!

Ich habe bei mir folgendes Problem:

Ein Temperaturfühler im Badezimmer liefert mehrmals in der Minuten die aktuelle Temperatur:
Internals:
   DEF        alecto_ws1700 1478
   ID         1478
   IODev      pili_Daemon
   LASTInputDev pili_Daemon
   MSGCNT     5600
   NAME       tem_Aussenbad
   NR         79
   PROTOCOL   alecto_ws1700
   STATE      T: 18.4
   TYPE       pilight_temp
   pili_Daemon_MSGCNT 5600
   pili_Daemon_TIME 2016-02-28 10:23:32
   Readings:
     2016-02-28 10:23:32   battery         1
     2016-02-28 10:23:32   humidity        20
     2016-02-28 10:23:32   statTemperatureDay Min: 0.3 Avg: 24.9 Max: 26.1
     2016-02-27 23:59:55   statTemperatureDayLast Min: 0.4 Avg: 23.9 Max: 26.4
     2016-02-28 10:23:32   statTemperatureHour Min: 18.4 Avg: 19.8 Max: 20.4
     2016-02-28 09:59:55   statTemperatureHourLast Min: 17.2 Avg: 18.7 Max: 21.4
     2016-02-28 10:23:32   statTemperatureMonth Min: 0.2 Avg: 23.3 Max: 26.9
     2016-01-31 23:59:55   statTemperatureMonthLast Min: 14.9 Avg: 22.7 Max: 25.3 (since: 2016-01-21_08:59:49 )
     2016-02-28 10:23:32   statTemperatureYear Min: 0.2 Avg: 23.2 Max: 26.9 (since: 2016-01-21_08:59:49 )
     2016-02-28 10:23:32   state           18.4
     2016-02-28 10:23:32   temperature     18.4
   Helper:
     _98_statistics sta_Temperatur
Attributes:
   IODev      pili_Daemon
   fp_1OG     77,290,1,,
   group      Temperatur
   room       Außenbad
   stateFormat T: temperature


Mit einem DOIF lasse ich mich per WhatsApp informieren, wenn die Temperatur zu stark absinkt (Hinweis: "Fenster offen?"):

Internals:
   DEF        ([tem_Aussenbad:temperature] < 19) ({sendWhatsApp("prs_ChristianHandy", "Außenbad zu kalt (".ReadingsVal("tem_Aussenbad", "temperature", "?")." C). Fenster offen? | FHEM", 1)}, {sendWhatsApp("prs_PamelaHandy", "Außenbad zu kalt (".ReadingsVal("tem_Aussenbad", "temperature", "?")." C). Fenster offen? | FHEM")})
   NAME       dif_Aussenbad_kalt
   NR         101
   NTFY_ORDER 50-dif_Aussenbad_kalt
   STATE      disabled
   TYPE       DOIF
   Readings:
     2016-02-28 08:51:24   Device          tem_Aussenbad
     2016-02-28 03:56:12   cmd_count       3
     2016-02-28 03:56:12   cmd_event       tem_Aussenbad
     2016-02-28 03:56:12   cmd_nr          1
     2016-02-28 08:51:24   e_tem_Aussenbad_temperature 24.1
     2016-02-28 08:51:38   mode            disabled
     2016-02-28 08:51:38   state           disabled
     2016-02-28 06:15:27   wait_timer      no timer
   Condition:
     0          ReadingValDoIf($hash,'tem_Aussenbad','temperature','','',AttrVal($hash->{NAME},'notexist',undef)) < 19
   Devices:
     0           tem_Aussenbad
     all         tem_Aussenbad
   Do:
     0:
       0          {sendWhatsApp("prs_ChristianHandy", "Außenbad zu kalt (".ReadingsVal("tem_Aussenbad", "temperature", "?")." C). Fenster offen? | FHEM", 1)}, {sendWhatsApp("prs_PamelaHandy", "Außenbad zu kalt (".ReadingsVal("tem_Aussenbad", "temperature", "?")." C). Fenster offen? | FHEM")}
     1:
   Helper:
     event      24.1,temperature: 24.1,humidity: 18,battery: 1
     globalinit 1
     last_timer 0
     sleepdevice tem_Aussenbad
     sleepsubtimer -1
     sleeptimer -1
     timerdev   tem_Aussenbad
     timerevent 0.3,temperature: 0.3,humidity: 24,battery: 1
     triggerDev tem_Aussenbad
     timerevents:
       0.3
       temperature: 0.3
       humidity: 24
       battery: 1
     triggerEvents:
       24.1
       temperature: 24.1
       humidity: 18
       battery: 1
   Internals:
   Itimer:
   Readings:
     0           tem_Aussenbad:temperature
     all         tem_Aussenbad:temperature
   Regexp:
     0:
     All:
   State:
   Trigger:
Attributes:
   cmdState   kalt|normal
   repeatcmd  600
   repeatsame 3
   room       Außenbad
   wait       60


Da der Temperaturfühler sporadisch mal einen falschen Wert liefert (nahe 0), habe ich ein "wait 60" im DOIF eingefügt. Das klappt hervorragend und vermeidet Fehlealarme.

Jetzt versuche ich, den Alarm mit "repeatcmd" und "repeatsame" bis zu 3 mal wiederholen zu lassen. So bald ich aber die Repeat-Attribute setze, ignoriert DOIF das Wait und ich bekomme wieder Fehlalarme.

Frage: Nutze ich DOIF hier "falsch" und müsste etwas anders konfigurieren oder hat das DOIF Modul da ggf. noch eine kleine Unzulänglichkeit für diesen Sonderfall?

Vielen Dank im Voraus für eure Hilfe!

Ellert

Spontane Ausreisser könntest Du vorher im Sensor mit event-aggregator:temperature:60:linear:max abfangen.
Dann kannst Du "wait" weglassen.

repeatcmd wiederholt bei, einmal wahrgewordener Bedingung, den Befehl im angegebenen Zeitinterval, beschränkt in der Anzahl durch repeatsame.



weini

Den event-aggregator hatte ich kurz nach meinem Posting auch entdeckt. Allerdings habe ich es mit "mean" versucht, das hatte noch nicht den gewünschten Effekt. Ich teste nochmal mit "max".

Zitatrepeatcmd wiederholt bei, einmal wahrgewordener Bedingung, den Befehl im angegebenen Zeitinterval, beschränkt in der Anzahl durch repeatsame.
Ich hatte eigentlich angenommen, dass vor jeder Wiederholung geprüft wird, ob die Bedingung noch wahr ist.
Laut Doku sollte das so sein:
ZitatAnwendungsbeispiel: Nach dem Eintreffen des Ereignisses wird die push-Meldung stündlich wiederholt, bis Frost ungleich "on" ist.

define di_push DOIF ([frost] eq "on")(set pushmsg "danger of frost")
attr di_push repeatcmd 3600

Eine Begrenzung der Wiederholungen kann mit dem Attribut repeatsame vorgenommen werden
attr di_push repeatsame 3

Habe ich das richtig verstanden? Ich will nicht, dass wiederholt Nachrichten versendet werden, wenn die Bedingung mittlerweile schon nicht mehr zutrifft.

Ellert

Du hast es richtig verstanden.

Wenn aber der Messwert um den Vergleichswert schwankt, wirst Du immer wieder benachrichtigt. Das kannst Du mit repeatsame nicht verhindern. Dazu müsstest Du eine eine Umschaltschwelle einbauen.

([T] < 5)  (send ...)
DOELSEIF ([T] > 8)

weini

Also so richtig funktioniert das noch nicht...

Problem 1: DOIF wertet die Bedingung nicht neu aus, bevor ein Befehl wiederholt wird. Es verhält sich hier definitiv anders als in der Doku beschrieben

Internals:
   DEF        ([tem_Aussenbad:temperature] < 19) ({sendWhatsApp("prs_ChristianHandy", "Außenbad zu kalt (".ReadingsVal("tem_Aussenbad", "temperature", "?")." C). Fenster offen? | FHEM", 1)}, {sendWhatsApp("prs_PamelaHandy", "Außenbad zu kalt (".ReadingsVal("tem_Aussenbad", "temperature", "?")." C). Fenster offen? | FHEM")})
   NAME       dif_Aussenbad_kalt
   NR         103
   NTFY_ORDER 50-dif_Aussenbad_kalt
   STATE      kalt
   TYPE       DOIF
   Readings:
     2016-02-29 08:24:48   Device          tem_Aussenbad
     2016-02-29 07:03:18   cmd_count       3
     2016-02-29 07:03:18   cmd_event       tem_Aussenbad
     2016-02-29 07:03:18   cmd_nr          1
     2016-02-29 08:24:48   e_tem_Aussenbad_temperature 21.8
     2016-02-29 07:03:18   state           kalt
     2016-02-29 07:13:18   wait_timer      no timer
   Condition:
     0          ReadingValDoIf($hash,'tem_Aussenbad','temperature','','',AttrVal($hash->{NAME},'notexist',undef)) < 19
   Devices:
     0           tem_Aussenbad
     all         tem_Aussenbad
   Do:
     0:
       0          {sendWhatsApp("prs_ChristianHandy", "Außenbad zu kalt (".ReadingsVal("tem_Aussenbad", "temperature", "?")." C). Fenster offen? | FHEM", 1)}, {sendWhatsApp("prs_PamelaHandy", "Außenbad zu kalt (".ReadingsVal("tem_Aussenbad", "temperature", "?")." C). Fenster offen? | FHEM")}
     1:
   Helper:
     event      21.8,humidity: 19,battery: 1
     globalinit 1
     last_timer 0
     sleepdevice tem_Aussenbad
     sleepsubtimer -1
     sleeptimer -1
     timerdev   tem_Aussenbad
     timerevent 19.1,temperature: 18.9,humidity: 20,battery: 1
     triggerDev tem_Aussenbad
     timerevents:
       19.1
       temperature: 18.9
       humidity: 20
       battery: 1
     triggerEvents:
       21.8
       humidity: 19
       battery: 1
   Internals:
   Itimer:
   Readings:
     0           tem_Aussenbad:temperature
     all         tem_Aussenbad:temperature
   Regexp:
     0:
     All:
   State:
   Trigger:
Attributes:
   cmdState   kalt|normal
   repeatcmd  600
   repeatsame 3
   room       Außenbad

Ich bekomme hier immer 3 Nachrichten zugesandt, auch wenn bei der zweiten Nachricht die Temperatur schon wieder über dem Schwellwert liegt. Ich kann das genau nachvollziehen, weil ich mir in der Nachricht den Temperaturwert mitschicken lasse.

Problem 2: event-aggregator verhindert nicht, dass das DOIF auslöst
Internals:
   DEF        alecto_ws1700 1478
   ID         1478
   IODev      pili_Daemon
   LASTInputDev pili_Daemon
   MSGCNT     4508
   NAME       tem_Aussenbad
   NR         81
   PROTOCOL   alecto_ws1700
   STATE      T: 21.8
   TYPE       pilight_temp
   pili_Daemon_MSGCNT 4508
   pili_Daemon_TIME 2016-02-29 08:27:43
   Readings:
     2016-02-29 08:27:43   battery         1
     2016-02-29 08:27:43   humidity        19
     2016-02-29 08:27:43   statTemperatureDay Min: 18.5000000000000 Avg: 24.0208218458711 Max: 25.6000000000000
     2016-02-28 23:59:55   statTemperatureDayLast Min: 0.3000000000000 Avg: 23.3769832450536 Max: 26.1000000000000
     2016-02-29 08:27:43   statTemperatureHour Min: 21.6000000000000 Avg: 21.7553357314149 Max: 21.8000000000000
     2016-02-29 07:59:55   statTemperatureHourLast Min: 20.8000000000000 Avg: 21.1886944444444 Max: 21.6000000000000
     2016-02-29 08:27:43   statTemperatureMonth Min: 0.2000000000000 Avg: 23.3201650843190 Max: 26.9000000000000
     2016-01-31 23:59:55   statTemperatureMonthLast Min: 14.9 Avg: 22.7 Max: 25.3 (since: 2016-01-21_08:59:49 )
     2016-02-29 08:27:43   statTemperatureYear Min: 0.2000000000000 Avg: 23.1599415836786 Max: 26.9000000000000 (since: 2016-01-21_08:59:49 )
     2016-02-29 08:27:43   state           21.8
     2016-02-29 08:27:43   temperature     21.8
   Helper:
     _98_statistics sta_Temperatur
Attributes:
   IODev      pili_Daemon
   event-aggregator temperature:60:linear:max
   fp_1OG     77,290,1,,
   group      Temperatur
   room       Außenbad
   stateFormat T: temperature

Habe den event-aggregator wie vorgeschlagen (Danke!) eingestellt. Im Logfile sehe ich auch keine Werte nahe Null, hier funktioniert es also. Allerdings löst immer noch das DOIF aus, wenn ein solcher falscher Wert gemessen wird. Kann es sein, dass das DOIF den Event erhält, bevor er aggregiert wird?

Damian

Zitat von: weini am 29 Februar 2016, 08:30:50
Also so richtig funktioniert das noch nicht...

Problem 1: DOIF wertet die Bedingung nicht neu aus, bevor ein Befehl wiederholt wird. Es verhält sich hier definitiv anders als in der Doku beschrieben

Internals:
   DEF        ([tem_Aussenbad:temperature] < 19) ({sendWhatsApp("prs_ChristianHandy", "Außenbad zu kalt (".ReadingsVal("tem_Aussenbad", "temperature", "?")." C). Fenster offen? | FHEM", 1)}, {sendWhatsApp("prs_PamelaHandy", "Außenbad zu kalt (".ReadingsVal("tem_Aussenbad", "temperature", "?")." C). Fenster offen? | FHEM")})
   NAME       dif_Aussenbad_kalt
   NR         103
   NTFY_ORDER 50-dif_Aussenbad_kalt
   STATE      kalt
   TYPE       DOIF
   Readings:
     2016-02-29 08:24:48   Device          tem_Aussenbad
     2016-02-29 07:03:18   cmd_count       3
     2016-02-29 07:03:18   cmd_event       tem_Aussenbad
     2016-02-29 07:03:18   cmd_nr          1
     2016-02-29 08:24:48   e_tem_Aussenbad_temperature 21.8
     2016-02-29 07:03:18   state           kalt
     2016-02-29 07:13:18   wait_timer      no timer
   Condition:
     0          ReadingValDoIf($hash,'tem_Aussenbad','temperature','','',AttrVal($hash->{NAME},'notexist',undef)) < 19
   Devices:
     0           tem_Aussenbad
     all         tem_Aussenbad
   Do:
     0:
       0          {sendWhatsApp("prs_ChristianHandy", "Außenbad zu kalt (".ReadingsVal("tem_Aussenbad", "temperature", "?")." C). Fenster offen? | FHEM", 1)}, {sendWhatsApp("prs_PamelaHandy", "Außenbad zu kalt (".ReadingsVal("tem_Aussenbad", "temperature", "?")." C). Fenster offen? | FHEM")}
     1:
   Helper:
     event      21.8,humidity: 19,battery: 1
     globalinit 1
     last_timer 0
     sleepdevice tem_Aussenbad
     sleepsubtimer -1
     sleeptimer -1
     timerdev   tem_Aussenbad
     timerevent 19.1,temperature: 18.9,humidity: 20,battery: 1
     triggerDev tem_Aussenbad
     timerevents:
       19.1
       temperature: 18.9
       humidity: 20
       battery: 1
     triggerEvents:
       21.8
       humidity: 19
       battery: 1
   Internals:
   Itimer:
   Readings:
     0           tem_Aussenbad:temperature
     all         tem_Aussenbad:temperature
   Regexp:
     0:
     All:
   State:
   Trigger:
Attributes:
   cmdState   kalt|normal
   repeatcmd  600
   repeatsame 3
   room       Außenbad

Ich bekomme hier immer 3 Nachrichten zugesandt, auch wenn bei der zweiten Nachricht die Temperatur schon wieder über dem Schwellwert liegt. Ich kann das genau nachvollziehen, weil ich mir in der Nachricht den Temperaturwert mitschicken lasse.

Problem 2: event-aggregator verhindert nicht, dass das DOIF auslöst
Internals:
   DEF        alecto_ws1700 1478
   ID         1478
   IODev      pili_Daemon
   LASTInputDev pili_Daemon
   MSGCNT     4508
   NAME       tem_Aussenbad
   NR         81
   PROTOCOL   alecto_ws1700
   STATE      T: 21.8
   TYPE       pilight_temp
   pili_Daemon_MSGCNT 4508
   pili_Daemon_TIME 2016-02-29 08:27:43
   Readings:
     2016-02-29 08:27:43   battery         1
     2016-02-29 08:27:43   humidity        19
     2016-02-29 08:27:43   statTemperatureDay Min: 18.5000000000000 Avg: 24.0208218458711 Max: 25.6000000000000
     2016-02-28 23:59:55   statTemperatureDayLast Min: 0.3000000000000 Avg: 23.3769832450536 Max: 26.1000000000000
     2016-02-29 08:27:43   statTemperatureHour Min: 21.6000000000000 Avg: 21.7553357314149 Max: 21.8000000000000
     2016-02-29 07:59:55   statTemperatureHourLast Min: 20.8000000000000 Avg: 21.1886944444444 Max: 21.6000000000000
     2016-02-29 08:27:43   statTemperatureMonth Min: 0.2000000000000 Avg: 23.3201650843190 Max: 26.9000000000000
     2016-01-31 23:59:55   statTemperatureMonthLast Min: 14.9 Avg: 22.7 Max: 25.3 (since: 2016-01-21_08:59:49 )
     2016-02-29 08:27:43   statTemperatureYear Min: 0.2000000000000 Avg: 23.1599415836786 Max: 26.9000000000000 (since: 2016-01-21_08:59:49 )
     2016-02-29 08:27:43   state           21.8
     2016-02-29 08:27:43   temperature     21.8
   Helper:
     _98_statistics sta_Temperatur
Attributes:
   IODev      pili_Daemon
   event-aggregator temperature:60:linear:max
   fp_1OG     77,290,1,,
   group      Temperatur
   room       Außenbad
   stateFormat T: temperature

Habe den event-aggregator wie vorgeschlagen (Danke!) eingestellt. Im Logfile sehe ich auch keine Werte nahe Null, hier funktioniert es also. Allerdings löst immer noch das DOIF aus, wenn ein solcher falscher Wert gemessen wird. Kann es sein, dass das DOIF den Event erhält, bevor er aggregiert wird?

repeatsame impliziert do always bei do always gibt es keinen Sonstfall bei Nichterfüllung und damit kann der Zustand nicht wechseln, um die Wiederholung vorzeitig abzubrechen. Du brauchst nur am Ende deiner Definition DOELSE dranzuhängen und schon sollte es wie gewünscht funktionieren.

Gruß

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

weini

Alles klar, ich versuche das so und geb dann nochmal Feedback!

Viele Grüße,
Weini

weini