(gelöst) DOIF: Aktionen klappen manchmal, manchmal nicht

Begonnen von heikoh81, 30 November 2015, 17:19:02

Vorheriges Thema - Nächstes Thema

heikoh81

Hallo zusammen,

ich verwende ein DOIF, um zu überwachen, ob ein Fenster zum Lüften noch geöffnet ist.
Wenn es eine gewisse Zeit offen war, werden zwei Aktoren betätigt, die ein Status-Licht einschalten, damit ich mich erinnere, das Fenster wieder zuzumachen.


([Fenster03Zustand_GaesteWC:state] eq "offen" and [?GaesteWC_Benachrichtigen_wenn_Fenster_offen] eq "on")
({if (Value("PollinWohnTVSim") eq "off") {fhem("set PollinWohnTVSim on")}})
({if (Value("PollinSchlaf3TVSim") eq "off") {fhem("set PollinSchlaf3TVSim on")}})
    DOELSEIF ([Fenster03Zustand_GaesteWC] eq "geschlossen" and [?GaesteWC_Benachrichtigen_wenn_Fenster_offen] eq "on")
({if (Value("PollinWohnTVSim") eq "on") {fhem("set PollinWohnTVSim off")}})
({if (Value("PollinSchlaf3TVSim") eq "on") {fhem("set PollinSchlaf3TVSim off")}})



  • Fenster03Zustand_GaesteWC = Dummy, der über ein notify durch einen Fenstersensor auf offen/geschlossen gesetzt wird
  • PollinWohnTVSim = Dummy für Aktor1
  • PollinSchlaf3TVSim = Dummy für Aktor2


Die {perl-if-Bedingungen} habe ich eingefügt, weil ich nur dann einen Befehl an den Aktor senden will, wenn dieser den gegenteiligen Zustand hat.
Dadurch will ich unnötige Funkbefehle & Systemlast vermeiden.
Dies habe ich in notifies schon immer so abgefragt und habe es hier das erste Mal in ein DOIF gepackt.
Ich wüßte nicht, wie ich diese Abfolge sonst in einem einzigen DOIF unterbringen kann, zumal ich zwischen den Befehlen eine DOIF-Verzögerung von 5 Sekunden eingebaut habe mit der WAIT-Funktion.

list di_Fenster03_GaesteWC_benachrichtigen

Internals:
   DEF        ([Fenster03Zustand_GaesteWC:state] eq "offen" and [?GaesteWC_Benachrichtigen_wenn_Fenster_offen] eq "on")
({if (Value("PollinWohnTVSim") eq "off") {fhem("set PollinWohnTVSim on")}})
({if (Value("PollinSchlaf3TVSim") eq "off") {fhem("set PollinSchlaf3TVSim on")}})
    DOELSEIF ([Fenster03Zustand_GaesteWC] eq "geschlossen" and [?GaesteWC_Benachrichtigen_wenn_Fenster_offen] eq "on")
({if (Value("PollinWohnTVSim") eq "on") {fhem("set PollinWohnTVSim off")}})
({if (Value("PollinSchlaf3TVSim") eq "on") {fhem("set PollinSchlaf3TVSim off")}})
   NAME       di_Fenster03_GaesteWC_benachrichtigen
   NR         2738
   NTFY_ORDER 50-di_Fenster03_GaesteWC_benachrichtigen
   STATE      cmd_2
   TYPE       DOIF
   Readings:
     2015-11-30 16:48:22   Device          Fenster03Zustand_GaesteWC
     2015-11-30 16:48:32   cmd_event       Fenster03Zustand_GaesteWC
     2015-11-30 16:48:32   cmd_nr          2
     2015-11-30 16:48:32   cmd_seqnr       2
     2015-11-30 16:48:22   e_Fenster03Zustand_GaesteWC_STATE geschlossen
     2015-11-30 16:48:22   e_Fenster03Zustand_GaesteWC_state geschlossen
     2015-11-30 16:48:32   state           cmd_2
     2015-11-30 16:48:32   wait_timer      no timer
   Condition:
     0          ReadingValDoIf('Fenster03Zustand_GaesteWC','state','') eq "offen" and InternalDoIf('GaesteWC_Benachrichtigen_wenn_Fenster_offen','STATE','') eq "on"
     1          InternalDoIf('Fenster03Zustand_GaesteWC','STATE','') eq "geschlossen" and InternalDoIf('GaesteWC_Benachrichtigen_wenn_Fenster_offen','STATE','') eq "on"
   Devices:
     0           Fenster03Zustand_GaesteWC
     1           Fenster03Zustand_GaesteWC
     all         Fenster03Zustand_GaesteWC
   Do:
     0:
       0          {if (Value("PollinWohnTVSim") eq "off") {fhem("set PollinWohnTVSim on")}}
       1          {if (Value("PollinSchlaf3TVSim") eq "off") {fhem("set PollinSchlaf3TVSim on")}}
     1:
       0          {if (Value("PollinWohnTVSim") eq "on") {fhem("set PollinWohnTVSim off")}}
       1          {if (Value("PollinSchlaf3TVSim") eq "on") {fhem("set PollinSchlaf3TVSim off")}}
   Helper:
     globalinit 1
     last_timer 0
     sleepdevice Fenster03Zustand_GaesteWC
     sleepsubtimer -1
     sleeptimer -1
   Internals:
     1           Fenster03Zustand_GaesteWC:STATE
     all         Fenster03Zustand_GaesteWC:STATE
   Itimer:
   Readings:
     0           Fenster03Zustand_GaesteWC:state
     all         Fenster03Zustand_GaesteWC:state
   State:
   Timerfunc:
   Trigger:
Attributes:
   room       Fenster
   wait       120,125:5,10


Nun werden die Dummies völlig willkürlich geschaltet.
Manchmal klappt es, dass beide wie gewünscht schalten.
Gerade eben wurde nur PollinWohnTVSim = on gesetzt, aber nicht mehr auf off.

Ich verstehe nicht, wieso es nicht funktioniert.

Vielen Dank für eure Hilfe,
viele Grüße,

Heiko

Bennemannc

Hallo,

aus der commandref
ZitatMehrere Perlbefehle hintereinander werden im DEF-Editor mit zwei Semikolons angegeben: .
zwischen die beiden if muss etwas stehen.
{if (Value ....) {fehm("set ...)} ;; if (Value ...) {fhem("set ...)}} oder es mit dem fhem IF machen - dann kannst Du Dir die geschweiften Klammern sparen.

Gruß Christoph
Cubietruck, Fhem 5.8
CC-RT-DN|LC-SW2-FM|RC-12|RC-19|LC-SW4-BA-PCB|LCp-SW1-BA-PCB|ES-PMSw1-Pl|LC-Bl1PBU-FM|PBI-4-FM|CC-VD|CC-TC|SEC-SC(2)|RC-KEY3-B|LC-Sw1PBU-FM|PB-2-FM|WDS100-C6-O|WDC7000|LC-Bl1-FM
Module: Dewpoint,FB_Callmonitor,HCS,Panstamp,at,notify,THRESHOLD,average,DOIF

heikoh81

#2
    Ok, das kenne ich.

    Aber:

    • Ich will eben nicht 2 ifs direkt in Perl miteinander verketten, sondern ich möchte 2 DOIF-Befehle, die ich dann mit einem wait-timer trennen kann.
    • Deshalb in 2 Zeilen 2x (), das sollen die beiden DOIF-Befehle sein, die bei Eintreten der Bedingung nacheinander abgearbeitet werden
    • Diese 2 DOIF-Befehle enthalten dann 2 verschiedene PERL-ifs

Ellert

Du kannst Dir die If sparen indem Du Filter einsetzt:
set NAME=PollinWohnTVSim:FILTER=STATE=on off

siehe: http://fhem.de/commandref_DE.html#devspec

Es klappt auch mit dem exakten Gerätenamen, dieser Aussage zum trotz:
Zitatfalls ein Gerätename exakt dem Spezifikation entspricht, dann werden keine reguläre Ausdrücke oder Filter ausgewertet.
Ich habe es ausprobiert.

Ich würde auch zum FHEM IF raten, weil die Syntax einfacher ist:
IF ([PollinWohnTVSim] eq "on") (set PollinWohnTVSim off)

Schliesst Du das Fenster vor Ablauf der Timer? Dann wird der noch nicht ausgeführte Befehl nicht mehr ausgeführt.

heikoh81

Zitat von: Ellert am 30 November 2015, 18:51:10
Du kannst Dir die If sparen indem Du Filter einsetzt:
set NAME=PollinWohnTVSim:FILTER=STATE=on off

Cool, das kannte ich noch nicht.
Verstehe ich das jetzt so, dass ich einfach statt
set PollinWohnTVSim off
zukünftig
set NAME=PollinWohnTVSim:FILTER=STATE=on off
als fhem-Befehl absetzen kann, und der Befehl nur dann ausgeführt wird, wenn PollinWohnTVSim=off ist?

Zitat
Ich würde auch zum FHEM IF raten, weil die Syntax einfacher ist:
IF ([PollinWohnTVSim] eq "on") (set PollinWohnTVSim off)
Auch das kannte ich noch nicht. Sachen gibst nach 1,75 Jahren fhem :-)

Zitat
Schliesst Du das Fenster vor Ablauf der Timer? Dann wird der noch nicht ausgeführte Befehl nicht mehr ausgeführt.
Nein, bei den Tests garantiert nicht.
Ich stehe meist mit dem Tablet im GästeWC und beobachte, was sich im DOIF so tut :-)

Viele Grüße,
Heiko

Ellert

ZitatVerstehe ich das jetzt so, dass ich einfach statt
Code: [Auswählen]

set PollinWohnTVSim off

zukünftig
Code: [Auswählen]

set NAME=PollinWohnTVSim:FILTER=STATE=on off

als fhem-Befehl absetzen kann, und der Befehl nur dann ausgeführt wird, wenn PollinWohnTVSim=off ist?

Ja.

heikoh81

Super, ich habe den fhem-Code ersetzt.
Ich bin gespannt...

Damian

ZitatIF ([PollinWohnTVSim] eq "on") (set PollinWohnTVSim off)

Auch das kannte ich noch nicht. Sachen gibst nach 1,75 Jahren fhem :-)

Dabei ist IF älter als DOIF ;)

Gruß

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

heikoh81

Ich habe noch irgendein Problem, und zwar wird der 2. DOIF-Befehl exakt nach 125 Sekunden ausgeführt, also der Zeitdauer meines Wait-Timers:
attr wait: 120,125:5,10
Aus dem Log:

2015.12.01 07:21:27 3: Befehl on wurde an Pollin 26-1 (PollinWohnTVSim) gesendet. (Wiederholungen: 5, Funktion SchaltePollinMitForSchleife)
2015.12.01 07:23:33 3: Befehl on wurde an Pollin 7-4 (PollinSchlaf3TVSim) gesendet. (Wiederholungen: 3, Funktion SchaltePollinMitForSchleife)


Vermutlich muss es richtig heißen:
wait: 120,125;5,5
wenn der erste Befehl nach 120s, der zweite nach 125s Gesamt-Dauer seit dem Event ausgeführt werden soll.
Und beim DOELSE genauso.
==> D.h. die Zeitdauern vor dem ; addieren sich in Bezug auf das Event?

Mein aktuelles DOIF:

([Fenster03Zustand_GaesteWC:state] eq "offen" and [?GaesteWC_Benachrichtigen_wenn_Fenster_offen] eq "on")
(set NAME=PollinWohnTVSim:FILTER=STATE=off on)
(set NAME=PollinSchlaf3TVSim:FILTER=STATE=off on)
    DOELSEIF ([Fenster03Zustand_GaesteWC] eq "geschlossen" and [?GaesteWC_Benachrichtigen_wenn_Fenster_offen] eq "on")
(set NAME=PollinWohnTVSim:FILTER=STATE=on off)
(set NAME=PollinSchlaf3TVSim:FILTER=STATE=on off)


Aktuelles list:

Internals:
   DEF        ([Fenster03Zustand_GaesteWC:state] eq "offen" and [?GaesteWC_Benachrichtigen_wenn_Fenster_offen] eq "on")
(set NAME=PollinWohnTVSim:FILTER=STATE=off on)
(set NAME=PollinSchlaf3TVSim:FILTER=STATE=off on)
    DOELSEIF ([Fenster03Zustand_GaesteWC] eq "geschlossen" and [?GaesteWC_Benachrichtigen_wenn_Fenster_offen] eq "on")
(set NAME=PollinWohnTVSim:FILTER=STATE=on off)
(set NAME=PollinSchlaf3TVSim:FILTER=STATE=on off)
   NAME       di_Fenster03_GaesteWC_benachrichtigen
   NR         2738
   NTFY_ORDER 50-di_Fenster03_GaesteWC_benachrichtigen
   STATE      cmd_1_1
   TYPE       DOIF
   Readings:
     2015-12-01 07:19:25   Device          Fenster03Zustand_GaesteWC
     2015-12-01 07:21:27   cmd_event       Fenster03Zustand_GaesteWC
     2015-12-01 07:21:27   cmd_nr          1
     2015-12-01 07:21:27   cmd_seqnr       1
     2015-12-01 07:19:25   e_Fenster03Zustand_GaesteWC_STATE offen
     2015-12-01 07:19:25   e_Fenster03Zustand_GaesteWC_state offen
     2015-12-01 07:21:27   state           cmd_1_1
     2015-12-01 07:21:27   wait_timer      01.12.2015 07:23:32 cmd_1_2 Fenster03Zustand_GaesteWC
   Condition:
     0          ReadingValDoIf('Fenster03Zustand_GaesteWC','state','') eq "offen" and InternalDoIf('GaesteWC_Benachrichtigen_wenn_Fenster_offen','STATE','') eq "on"
     1          InternalDoIf('Fenster03Zustand_GaesteWC','STATE','') eq "geschlossen" and InternalDoIf('GaesteWC_Benachrichtigen_wenn_Fenster_offen','STATE','') eq "on"
   Devices:
     0           Fenster03Zustand_GaesteWC
     1           Fenster03Zustand_GaesteWC
     all         Fenster03Zustand_GaesteWC
   Do:
     0:
       0          set NAME=PollinWohnTVSim:FILTER=STATE=off on
       1          set NAME=PollinSchlaf3TVSim:FILTER=STATE=off on
     1:
       0          set NAME=PollinWohnTVSim:FILTER=STATE=on off
       1          set NAME=PollinSchlaf3TVSim:FILTER=STATE=on off
   Helper:
     globalinit 1
     last_timer 0
     sleepdevice Fenster03Zustand_GaesteWC
     sleepsubtimer 1
     sleeptimer 0
   Internals:
     1           Fenster03Zustand_GaesteWC:STATE
     all         Fenster03Zustand_GaesteWC:STATE
   Itimer:
   Readings:
     0           Fenster03Zustand_GaesteWC:state
     all         Fenster03Zustand_GaesteWC:state
   State:
   Trigger:
Attributes:
   room       Fenster
   wait       120,125:5,10

Ellert

ZitatD.h. die Zeitdauern vor dem ; addieren sich in Bezug auf das Event?

Wo hast Du gelesen, dass ";" die Zeitangaben zwischen den Bedingungszweigen trennt?

heikoh81

Mein Fehler.
Sollte ein : sein.

D.h. wenn ich möchte, dass die beiden DOIF-Befehle nach Auslösen des Events nach 120 und 125 Sekunden ausgeführt werden, muss das wait-attr lauten:
120,5:5,5
?

Ellert

Zitat von: heikoh81 am 01 Dezember 2015, 18:20:44
Mein Fehler.
Sollte ein : sein.

D.h. wenn ich möchte, dass die beiden DOIF-Befehle nach Auslösen des Events nach 120 und 125 Sekunden ausgeführt werden, muss das wait-attr lauten:
120,5:5,5
?
Nein nur 125,5

heikoh81

Moment, ich habe doch 4 Befehle, also brauche ich auch 4 Zeitangaben.
Siehe Listing:
   Do:
     0:
       0          set NAME=PollinWohnTVSim:FILTER=STATE=off on
       1          set NAME=PollinSchlaf3TVSim:FILTER=STATE=off on
     1:
       0          set NAME=PollinWohnTVSim:FILTER=STATE=on off
       1          set NAME=PollinSchlaf3TVSim:FILTER=STATE=on off

Ellert

ZitatD.h. wenn ich möchte, dass die beiden DOIF-Befehle

Hier sprichst Du von 2 Befehlen.

heikoh81

Ich meine:

  • 2 Befehle im DOIF
  • 2 weitere Befehle im DOELSE

Somit benötige ich - sollen alle 4 Befehle verzögert werden - auch 4 Timerangaben.
Meine Frage ist noch unbeantwortet:

Addieren sich die Timer vor dem : ?
D.h. wenn ich 0-0 um 120s verzögern möchte seit dem Trigger-Event und 0-1 um 125,
muss ich dann schreiben:
120,5:5,5
?

Viele Grüße,
Heiko