DOIF-Selbsttriggerung falsch verstanden?

Begonnen von ManOki, 12 Juli 2017, 19:04:22

Vorheriges Thema - Nächstes Thema

ManOki

Hallo,

ich habe 2 PIs, die ich gelegentlich an und aus schalte. Dabei macht es nur Sinn, dass RPi2 nur dann angeschaltet ist, wenn auch RPi1 eingeschaltet ist. Falls RPi1 bereits eingeschaltet ist, soll RPi2 direkt starten, ansonsten reicht es aus, RPi1 kurz vorher einzuschalten. Das möchte ich so in einem DOIF ablegen. Leider scheitere ich an der Selbsttriggerung, sodass immer beide gleichzeitig eingeschaltet werden. Zur Steuerung der PIs habe ich 2 WOL Definitionen sowie Funksteckdosen, um diese komplett ein bzw. auszuschalten.

Ich habe ein zweites DOIF, welches die Steckdose von RPi1 schaltet, dies funktioniert einwandfrei. Hier geht es nur um RPi2 und Steckdose2.

Das Problem: Sobald ich RPi2 anschalte und RPi1 noch ausgeschaltet ist, geht das DOIF erst in Zweig 2 und direkt danach in Zweig 1 (da ja in Zweig 2 als erster Befehl RPi1 eingeschaltet wird). In diesem Fall werde PIs nahezu gleichzeitig eingeschaltet. Idee ist aber, dass für den Fall, dass beide aus sind, eine Verzögerung von 10 Sekunden beim Einschalten von RPi2 auftritt.

Meinem Verständnis nach ist das ein Fall von Selbsttriggerung und sollte eigentlich nicht passieren. Sehe ich das so richtig? Wo liegt mein Fehler?

Internals:
   CFGFN
   DEF        ([RPi2:active] eq "on" and [RPi1:active] eq "on")
  (set Steckdose2 on)
DOELSEIF ([RPi2:active] eq "on" and [RPi1:active] eq "off")
  (set RPi1 on)
  (set Steckdose2 on)
DOELSEIF ([RPi2.presence] eq "absent" and [WohnzimmerPC.presence] eq "absent" and [Steckdose2] ne "off")
  (set Pushbullet message RPi2 ausgeschaltet | Fhem | User)
  (set Steckdose2 off)
DOELSE
  ##nothing
   NAME       Steckdose2.state
   NR         140
   NTFY_ORDER 50-Steckdose2.state
   STATE      initialized
   TYPE       DOIF
   READINGS:
     2017-07-12 18:50:11   cmd             0
     2017-07-12 18:50:11   state           initialized
   condition:
     0          ReadingValDoIf($hash,'RPi2','active') eq "on" and ReadingValDoIf($hash,'RPi1','active') eq "on"
     1          ReadingValDoIf($hash,'RPi2','active') eq "on" and ReadingValDoIf($hash,'RPi1','active') eq "off"
     2          InternalDoIf($hash,'RPi2.presence','STATE') eq "absent" and InternalDoIf($hash,'WohnzimmerPC.presence','STATE') eq "absent" and InternalDoIf($hash,'Steckdose2','STATE') ne "off"
   devices:
     0           RPi2 RPi1
     1           RPi2 RPi1
     2           RPi2.presence WohnzimmerPC.presence Steckdose2
     all         RPi2 RPi1 RPi2.presence WohnzimmerPC.presence Steckdose2
   do:
     0:
       0          set Steckdose2 on
     1:
       0          set RPi1 on
       1          set Steckdose2 on
     2:
       0          set Pushbullet message RPi2 ausgeschaltet | Fhem | User
       1          set Steckdose2 off
     3:
       0
   helper:
     globalinit 1
     last_timer 0
     sleeptimer -1
   internals:
     2           RPi2.presence:STATE WohnzimmerPC.presence:STATE Steckdose2:STATE
     all         RPi2.presence:STATE WohnzimmerPC.presence:STATE Steckdose2:STATE
   itimer:
   readings:
     0           RPi2:active RPi1:active
     1           RPi2:active RPi1:active
     all         RPi2:active RPi1:active
   regexp:
     all:
   state:
     STATE:
Attributes:
   DbLogExclude .*
   cmdState   on|on_waiting,on|off_waiting,off|waiting
   group      Steckdose
   room       9.3 Regeln
   wait       0:0,10:0,600:0


Vielen Dank für eure Hilfe
ManOki

PS: Ich will auch nicht warten, bis RPi1 komplett hochgefahren ist. Es ist eben nicht notwendig, dass RPi1 läuft, sondern nur "sinnvoll".

Ellert

Du könntest Zweig 1 gegen 2 verriegeln.
Mit
([RPi2:active] eq "on" and [RPi1:active] eq "on" and [$SELF] !~ "^(on_waiting|on)\$")
wird Zweig 1 nur ausgelöst, wenn nicht Zweig 2 aktiv ist.

ManOki

Danke für die Antwort. Ich habe den Lösungsvorschlag nicht ausprobiert, denke aber, er würde funktionieren.

Mein Problem ist, dass ich Readings verwende und keine Events. Selbsttriggerung wird nur bei Events verhindert, das Reading von WOL wird natürlich direkt im Zweig 2 durch den Set Befehl geändert, womit dann alle Readings für Zweig 1 erfüllt sind.

Ellert

Welche Selbsttriggerung im DOIF verhindert wird kannst Du hier nachlesen: https://forum.fhem.de/index.php/topic,41859.0.html

Die Schleifen werden nicht in jedem Fall verhindert, z.B. dann nicht, wenn die Zeit zwischen dem Setzen eines Readings und dem Auslösen einer Bedingung dadurch lang genug ist.

Z.B. kann das Reading playing im Modul Text2Speech zum Triggern genutzt werden ohne das Attribut Selftrigger zu setzen.

([07:00]) (set TTS tts <Text1>)
DOELSEIF (![TTS:playing] and $cmd == 1) (set TTS tts <Text2>)


Nach dem Text1 abgespielt wurde ändert sich playing auf 0 und triggert den 2. Zweig.