Schwierigkeit beim Schalten komplexer Strukturen mit DOIF

Begonnen von duke-f, 15 Mai 2015, 20:24:53

Vorheriges Thema - Nächstes Thema

duke-f

Ich habe hier ein etwas schwierig zu beschreibendes Phänomen, das in dieser Konstellation sicherlich einmalig ist. Da ich es mir aber nicht erklären kann, will ich es dennoch an dieser Stelle versuchen zu beschreiben (auch wenn ich nicht wirklich auf eine Lösung zu hoffen wage ;)).

Vorab: Ich habe versucht, den Code etwas zu anonymisieren und etwas zu vereinfachen, hoffe aber, nichts wichtiges dabei verfälscht zu haben.
Das Vorhaben ist folgendes. Ich habe einen FS20-2/4-Kanal-Wandsender auf vier Kanäle konfiguriert. Zwei Tasten davon sind für zwei Personen des Haushaltes eingerichtet, um die Anwesenheit zu registrieren. Sie sind in FHEM als
FS20_Taster_1 und FS20_Taster_2
eingerichtet. Weiter sind beiden Personen jeweils ein Dummy zugeordnet, entsprechend
zuhause_1 und zuhause_2
Das folgende Skript ist zweimal angelegt, im nicht hier angegebenen Fall sind die beiden Taster und Dummies einfach vertauscht.

Vielleicht noch soviel: Ich habe schon einige unterschiedliche Varianten versucht, beispielsweise auch unter Verwendung von "UntoggleIndirekt".

Soweit funktioniert das ganze. Kommt eine der beiden Personen nach Hause und drückt seine Taste, wird er begrüßt und seine Anwesenheit wird per Icon im Webinterface angezeigt. Geht eine Person und drückt seine Taste, wird auch seine Abwesenheit per entsprechendes Icon im Webinterface gekennzeichnet und er wird verabschiedet. Hier gibt es aber drei mögliche unterschiedliche Zustände:
1. Die zweite Person ist noch zu Hause, es passiert außer dem Verabschieden nichts weiter.
2. Die zweite Person ist nicht anwesend und mindestens irgendein Fenster ist noch offen -> Warnmeldung und alle Heizungen sowie die Hifi-Anlage werden ausgeschaltet.
2. Die zweite Person ist nicht anwesend und alle Fenster sind zu -> Entwarnung und alle Heizungen sowie die Hifi-Anlage werden ausgeschaltet.


define DI_Komme_heim DOIF([FS20_Taster_1] eq "toggle" and [?zuhause_1] eq "off") (set display ttsSay Hallo. Willkommen zu Hause.,set zuhause_1 on)
DOELSEIF ([FS20_Taster_1] eq "toggle" and [?zuhause_1] eq "on" and [?zuhause_2] eq "on") (set display ttsSay Auf Wiedersehen.,set zuhause_1 off)
DOELSEIF ([FS20_Taster_1] eq "toggle" and [?zuhause_1] eq "on" and [?zuhause_2] eq "off" and [?Alle_Fenster] ne "Closed") (set display ttsSay Es sind nicht alle Fenster geschlossen. Ich schalte jetzt alle Heizungen aus.,set Alle_Hz off,set Hifi off,set zuhause_1 off)
DOELSEIF ([FS20_Taster_1] eq "toggle" and [?zuhause_1] eq "on" and [?zuhause_2] eq "off" and [?Alle_Fenster] eq "Closed") (set display ttsSay Die Fenster sind geschlossen. Ich schalte jetzt alle Heizungen aus.,set Alle_Hz off,set Hifi off,set zuhause_1 off)


Soweit die Vorgeschichte. Nun zum Problem. Es gibt eine zweite Stereoanlage, die auch ausgeschaltet werden soll. Diese Stereoanlage ist allerdings etwas komplexer eingebunden, weil sie auch als Wecker dient. Es ist aber ausgeschlossen, dass diese Anlage in irgendeiner Weise mit FS20_Taster_1 oder FS20_Taster_2 anderweitig verknüpft ist. Sie ist über ELRO-Schaltsteckdosen gesteuert. Aber jetzt das Problem:

Ergänze ich die letzten beiden Zeilen der beiden DOIFs um den Befehl:
...,set Hifi2 off,...
kommt es zu einer Wiederholung derart, dass in dem Falle, dass die zweite Person das Haus verlässt und seine entsprechende Taste drückt, sofort nach dem Abmelden (Symbol: Abwesend, Abschiedsfloskel) wieder das Anmelden erfolgt. Setze ich hingegen das "Abwesend-Signal" für die zweite Person per Webinterface (set FS20_Taster_2 off), funktioniert es wiederum - allerdings wohlbemerkt nicht in der jetzt oben angegeben Form natürlich, da ich "UntoggleIndirekt" im Rahmen der Fehlersuche entnommen habe und jetzt ausschließlich auf "toggle" reagiert wird.

Es ist mir schon klar, dass der Fehler irgendwo wahrscheinlich in meinem Code liegen muss - den kann ich hier aber nicht komplett angeben.
Cubietruck, 3 Raspberry Pis,
CUL868, RFXtrx433, CUL433, SCC868, HM-USB,
IRTrans, EZcontrol XS1, IguanaWorks USB IR Transceiver
ESPEasy, Fritz!Box, Samsung TV+BD, LMS, Squeezelite

duke-f

Ich muss mich hier wohl korrigieren. Dazu muss ich nochmal das Problem neu umschreiben, da mein alter Titel jetzt irreführend klingt.
Ich schaffe es nicht, dass durch das Verwenden eines FS20-2/4-Kanal-Wandsenders im 4-Kanal-Betrieb eine Befehlsfolge zuverlässig reproduzierbar abgearbeitet wird. Es werden immer wieder mal Schleifen durchlaufen, die eigentlich nicht maßgebend sein sollten. Dies aber nicht jedes Mal.

Leider lässt sich das Problem nur sehr unregelmäßig reproduzieren und tritt nicht immer auf, aber die Ergänzung um den einen Befehl (letzter Post) war natürlich nicht die eigentliche Ursache. Auch ohne diesen trat es irgendwann wieder auf. Weiter habe ich die Struktur probeweise komplett umgeschrieben mittels notify anstelle von DOIF und das Problem besteht weiter.

Man verzeihe mir die vielleicht unprofessionelle Beschreibung aber der eigentliche Grund muss die Verwendung des FS20-2/4-Kanal-Wandsenders im 4-Kanal-Betrieb sein. Es erscheint mir so, als ob der "toggle"-Befehl (das einzige, was der 4-Kanal-Betrieb sendet) mehrfach notifys oder DOIFS anstoßen würde.

Heute morgen habe ich mit dem folgenden Code geschafft, dass einmal alles korrekt ablief. Als ich schließlich wirklich das Haus verlassen wollte und die Taste entsprechend gedrückt habe, wurde ich erst begrüßt und gleich anschließend wieder verabschiedet.

Wie gesagt, ich erwarte nicht, dass jemsd dem wirklich folgen kann oder es sogar löst - berichten wollte ich es dennoch.

Dies ist aktuelle Code.
Heizungen und Alle_Fenster sind Structures. Durch das Anfügen von
fhem "set FS20_Taster_2 off
bzw.
fhem "set FS20_Taster_1 off
konnte ich einmal zumindest erreichen, dass Verabschiedung und Begrüßung mehrfach hintereinander ablaufen. Allerdings fürchte ich, das wird nächstes Mal wieder so sein - im Log tauchen nämlich mehr Schaltbefehle auf als ich erwartet hätte.


define FS20_Taster_2 FS20 632d c3
attr FS20_Taster_2 IODev CUL_0
attr FS20_Taster_2 webCmd toggle

define FS20_Taster_1 FS20 632d c2
attr FS20_Taster_1 IODev CUL_0
attr FS20_Taster_1 webCmd toggle

define zuhause_2 dummy
define zuhause_1 dummy

define FS20_Taster_1_PAIR notify FS20_Taster_1 {UntoggleIndirect("FS20_Taster_1","zuhause_1","dim12%%")}
define FS20_Taster_2_PAIR notify FS20_Taster_2 {UntoggleIndirect("FS20_Taster_2","zuhause_2","dim12%%")}

define Haus dummy
attr Haus setList state:0,1,2,3

define NF_Haus_nYnH notify FS20_Taster_2:toggle { \
   if (Value("zuhause_2") eq "off" && Value("zuhause_1") eq "off") { fhem "set Haus 0";;fhem "set FS20_Taster_2 off" } \
   if (Value("zuhause_2") eq "off" && Value("zuhause_1") eq "on") { \
       fhem "set Haus 1";;fhem "set FS20_Taster_2 off";; \
       fhem "set alabama ttsSay Auf Wiedersehen Person_2." \
       } \
   if (Value("zuhause_2") eq "on" && Value("zuhause_1") eq "off") { \
       fhem "set Haus 2";;fhem "set FS20_Taster_2 on";; \
       fhem "set alabama ttsSay Hallo Person_2." \
       } \
   if (Value("zuhause_2") eq "on" && Value("zuhause_1") eq "on") { \
       fhem "set Haus 3";;fhem "set FS20_Taster_2 on";; \
       fhem "set alabama ttsSay Hallo Person_2. Person_1 ist schon da." \
       } \
}

define NF_Haus_nHnY notify FS20_Taster_1:toggle { \
   if (Value("zuhause_2") eq "off" && Value("zuhause_1") eq "off") { fhem "set Haus 0";;fhem "set FS20_Taster_1 off" } \
   if (Value("zuhause_2") eq "off" && Value("zuhause_1") eq "on") { \
       fhem "set Haus 1";;fhem "set FS20_Taster_1 on";; \
       fhem "set alabama ttsSay Hallo Person_1. Willkommen zu Hause." \
       } \
   if (Value("zuhause_2") eq "on" && Value("zuhause_1") eq "off") { \
       fhem "set Haus 2";;fhem "set FS20_Taster_1 off";; \
       fhem "set alabama ttsSay Auf Wiedersehen Person_1." \
       } \
   if (Value("zuhause_2") eq "on" && Value("zuhause_1") eq "on") { \
       fhem "set Haus 3";;fhem "set FS20_Taster_1 on";; \
       fhem "set alabama ttsSay Hallo Person_1. Person_2 ist schon da." \
       } \
}

define NF_Leer notify Haus { \
   if (Value("Haus") eq "0" && Value("Alle_Fenster") ne "Closed") {\
   fhem "set alabama ttsSay Es sind nicht alle Fenster geschlossen. Bitte kontrolliere das nochmal bevor Du weg gehst. Ich schalte jetzt alle Heizungen aus.";; \
   fhem "set Hifi off";;\
   fhem "set Hifi2 off";;\
   fhem "set FS20_Taster_1 off";;fhem "set FS20_Taster_2 off"\
   } \
   if (Value("Haus") eq "0" && Value("Alle_Fenster") eq "Closed") {\
   fhem "set alabama ttsSay Die Fenster sind geschlossen. Ich schalte jetzt alle Heizungen aus.";; \
   fhem "set Hifi off";; \
   fhem "set Hifi2 off";;\
   fhem "set FS20_Taster_1 off";;fhem "set FS20_Taster_2 off"\
   } \
   if (Value("Haus") eq "0" && Value("Heizungen") ne "6.0") {\
   fhem "set Heizungen desired-temp 6" \
   } \
}
Cubietruck, 3 Raspberry Pis,
CUL868, RFXtrx433, CUL433, SCC868, HM-USB,
IRTrans, EZcontrol XS1, IguanaWorks USB IR Transceiver
ESPEasy, Fritz!Box, Samsung TV+BD, LMS, Squeezelite

flurin

Hallo duke-f

Ich würde das DOIF "entlasten" und das Problem einkreisen. Zudem die Dummies mit DOIF's ersetzen:


define di_zuhause_1 DOIF ([FS20_Taster_1] and [?di_zuhause_1] eq "off")
attr di_zuhause_1 cmdState on|off



define di_zuhause_2 DOIF ([FS20_Taster_2] and [?di_zuhause_2] eq "off")
attr di_zuhause_2 cmdState on|off



define DI_Komme_heim DOIF([di_zuhause_1:?on] or [di_zuhause_2:?on])
  (set display ttsSay Hallo. Willkommen zu Hause.)
DOELSEIF ([di_zuhause_1:?off] or [di_zuhause_2:?off])
  (set display ttsSay Auf Wiedersehen.)
...


Gruss
flurin

duke-f

Ich glaube, ich habe die DOIFs unterschätzt - oder sie mich überwältigt. Werde Deinen Ansatz mal verfolgen. Bin ehrlich gesagt noch nicht so weit mit den Möglichkeiten dabei, vor allem die Attribute betreffend.

Besten Dank für den Tipp.
Cubietruck, 3 Raspberry Pis,
CUL868, RFXtrx433, CUL433, SCC868, HM-USB,
IRTrans, EZcontrol XS1, IguanaWorks USB IR Transceiver
ESPEasy, Fritz!Box, Samsung TV+BD, LMS, Squeezelite

duke-f

Zitat von: flurin am 19 Mai 2015, 13:41:09
Ich würde das DOIF "entlasten" und das Problem einkreisen. Zudem die Dummies mit DOIF's ersetzen:

Dein Tipp war der Richtige: Entlasten. Bin jetzt zwar bei notify geblieben, hab aber die gesprochenen Texte herausgenommen. Offensichtlich wurde in der Zeit, in der dieser gesprochen wurde, die manchmal Abfrage wieder durchlaufen. Vielleicht kann es jemand besser erklären. Jetzt setze ich statt des Textes eine Hilfsvariable und lasse abhängig von der erst in einem zweiten notify den richtigen Text sprechen. Hoffe, so geht es jetzt dauerhaft.
Cubietruck, 3 Raspberry Pis,
CUL868, RFXtrx433, CUL433, SCC868, HM-USB,
IRTrans, EZcontrol XS1, IguanaWorks USB IR Transceiver
ESPEasy, Fritz!Box, Samsung TV+BD, LMS, Squeezelite