[gelöst] Mehrere DOIF Zweige zeitnah - nach Möglichkeit gleichzeitig - abarbeiten

Begonnen von Mad-at, 05 September 2023, 22:08:48

Vorheriges Thema - Nächstes Thema

Mad-at

Hallo!

Ich habe ein Monstrum erschaffen. Es ist einfach so passiert. Über die Zeit hinweg wurde das DoIf für unsere Raffstore Steuerung immer komplizierter. Jetzt habe ich in der aktuellen Version mehrere Probleme:
1) ich habe mehrere DoIf Zweige die sehr ähnliche Bedingungen haben - Herunterfahren der Raffstores zur gleichen Zeit und zur gleichen Dämmerstufe aber mit unterschiedlichen Räumen. Ich verstehe nicht so ganz, warum er immer nur den ersten & zweiten Zweig ausführt und die anderen nicht.
2) Ich hätte eigentlich gern dass das alles gleichzeitig herunterfährt und nicht eines nach dem anderen. Da muss ich wohl die komplette Struktur ändern, aber mir ist nicht ganz klar ob das überhaupt geht, es sind ja unterschiedliche Konditionen.

Ich will hier garnicht das ganze DoIf reinstellen, das ist glaube ich sinnlos, kann ich aber gerne nachreichen falls gewünscht. Die entscheidenden Äste sind:

DOIF
        [14:00-23:30] and [Helligkeit_Draussen:state] < "5" and [JalousienEGohneSuedabsolut] eq "0 %")
            (set JalousienEGohneSuedabsolut 18; sleep 20; set JalousienLamellenEGohneSuedabsolut 0; sleep 2; set JalousienLamellenEGohneSuedabsolut 100; sleep 2; set JalousienEGohneSuedabsolut 100)
   
        DOELSEIF
            ([14:00-23:30] and [Helligkeit_Draussen:state] < "5" and [Flur_Jalousie] eq "0 %")
            (set Flur_Jalousie 18; sleep 20; set FlurUG_JalousieLamellen 0; sleep 2; set FlurUG_JalousieLamellen 100; sleep 2; set Flur_Jalousie 100)
       
        DOELSEIF
            ([14:00-23:30] and [Helligkeit_Draussen:state] < "5" and [Kinderzimmer_Jalousie] eq "0 %")
            (set Kinderzimmer_Jalousie 18; sleep 20; set Kinderzimmer_JalousieLamellen 0; sleep 2; set Kinderzimmer_JalousieLamellen 100; sleep 2; set Kinderzimmer_Jalousie 100)
       
        DOELSEIF
            ([14:00-23:30] and [Helligkeit_Draussen:state] < "5" and [Schlafzimmer_Jalousie] eq "0 %")
            (set Schlafzimmer_Jalousie 18; sleep 20; set Schlafzimmer_Jalousie_Lamellen 0; sleep 2; set Schlafzimmer_Jalousie_Lamellen 100; sleep 2; set Schlafzimmer_Jalousie 100)
Der erste Ast und der zweite Ast werden ausgeführt, Ast 3&4 dann nicht mehr.

Ich gehe davon aus, dass es glücklich ist dass cmd2 wahr ist und dann den Baum nicht mehr weiter runtersucht. Da hätte ich gedacht dass ein "do always" das ändert. Das hat aber nichts gebracht. Aber spätestens nach dem kompletten Abarbeiten von cmd2 ist es ja falsch, denn dann ist der state der Flur Jalousie nicht mehr 0%. Aber trotzdem springt er dann nicht mehr weiter.

Ich vermute ein Lösungsvorschlag wird sein mehrere DoIfs zu erstellen. Hatte ich ursprünglich mal so, hat aber den Nachteil dass der Status der Raffstores nicht allen zur Verfügung steht. Teilweise sind das nämlich KNX Gruppen die dann keine Statusrückmeldung geben können, so dass ich den Status in/aus FHEM brauche. Daher hätt ichs gerne weiterhin in einem DoIf

Jemand eine Idee? wie gesagt Listing etc. stell ich auch gerne rein, aber das ist dann doch recht umfangreich

Damian

Für komplexe Steuerungsaufgaben würde ich dir strukturierte Programmierung empfehlen, grob gesagt also eine Hierarchie mit Unterprogrammen erstellen. Dafür ist der FHEM-Modus im DOIF nicht geschaffen, weil er keine tiefere Hierarchie vorsieht.

Komplexe Vorgänge würde ich in Perl programmieren, das kann man auch im DOIF: https://wiki.fhem.de/wiki/DOIF/Perl-Modus
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

RalfRog

... und das es so läuft liegt so wie ich es sehe an den Triggern die Du hast:

1) um 14 Uhr passiert nichts da [Helligkeit_Draussen:state] < "5" nicht wahr
[14:00-23:30] => Getriggert wird das Modul zum Zeitpunkt <begin> und zum Zeitpunkt <end>
2) wenn es dunkel "< 5" wird ist [14:00-23:30] wahr
[Helligkeit_Draussen:state] < "5" => triggert das Modul
Dann wird eben Zweig 1 ausgeführt wenn [Flur_Jalousie] eq "0 %" und die Bearbeitung ist fertig.
Ein "do always" hilft nicht weiter da ja kein Trigger mehr kommt - es ist ja schon Dunkel "< 5"
bzw. aufgrund "Getriggert wird das Modul ...zum Zeitpunkt <end>" ggfs. noch Zweig 2.
FHEM auf Raspi 2B mit nanoCUL, HM-MOD-RPI-PCB und über LAN MAX!Cube mit a-culFW (Stack 868 + 433)
HM- Fensterkontakte, UP-Schalter, Bewegungsmelder und ein Rauchmelder

RalfRog

Zitat von: Damian am 05 September 2023, 23:00:39Komplexe Vorgänge würde ich in Perl programmieren, das kann man auch im DOIF: https://wiki.fhem.de/wiki/DOIF/Perl-Modus
... wenn es jemand wissen muss  ;D


Beim Versuch deine Idee nachzuvollziehen fiel mir ein, dass es vielleicht hilft die Trigger ein wenig anzupassen.
So als Versuch - ob es funktioniert? und wenn ja wie zuverlässig (je nachdem wie der Helligkeitswert sich verändert) kA.
Da 5 kleiner 6,7,8 (und 6 kleiner 7,8 usw.) ist, müssen die Bedingungen im DOIF von oben nach unten der Reihe abgearbeitet werden. Mit 8 wird zuerst Zweig 4 wahr - bei 7 schon Zweig 3 u. 4.

Jeder Zweig mit anderer Schwelle und damit unterschiedlichem Trigger.
[Helligkeit_Draussen:state] < "5"
[Helligkeit_Draussen:state] < "6"
[Helligkeit_Draussen:state] < "7"
[Helligkeit_Draussen:state] < "8"


Aber wie Damian schreibt ist es sauberer und  strukturierter "Komplexe Vorgänge in Perl programmieren".

FHEM auf Raspi 2B mit nanoCUL, HM-MOD-RPI-PCB und über LAN MAX!Cube mit a-culFW (Stack 868 + 433)
HM- Fensterkontakte, UP-Schalter, Bewegungsmelder und ein Rauchmelder

Mad-at

Ihr seid der Wahnsinn! Danke! Das mit dem Trigger ist mir heute nacht auch noch eingefallen - dann muss ich mich aber vom Wunsch der Gleichzeitigkeit verabschieden. Ob das tatsächlich so wichtig ist sei mal dahingestellt.

Perl... puh...  :-\ Ich versuch mich mal reinzulesen.

Damian

Zitat von: Mad-at am 06 September 2023, 11:07:50Ihr seid der Wahnsinn! Danke! Das mit dem Trigger ist mir heute nacht auch noch eingefallen - dann muss ich mich aber vom Wunsch der Gleichzeitigkeit verabschieden. Ob das tatsächlich so wichtig ist sei mal dahingestellt.
 

ja, es sind ja im FHEM-Modus alles ELSE-Fälle, die sich gegenseitig ausschließen, das bedeutet wiederum, dass zum gleichen Zeitpunkt immer nur ein Zweig ausgeführt werden kann und zwar der erste, bei dem der passende Zeittrigger vorkommt und dessen Bedingung wahr ist.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

RalfRog

Danke für den Hinweis, dass es nicht geht ;)

Ich streich dann mal den Vorschlag in #3
FHEM auf Raspi 2B mit nanoCUL, HM-MOD-RPI-PCB und über LAN MAX!Cube mit a-culFW (Stack 868 + 433)
HM- Fensterkontakte, UP-Schalter, Bewegungsmelder und ein Rauchmelder

Mad-at

Zitat von: RalfRog am 06 September 2023, 13:29:02Danke für den Hinweis, dass es nicht geht ;)

Ich streich dann mal den Vorschlag in #3

Nein wieso? Wenn man auf die Gleichzeitigkeit verzichtet müsste es doch gehen, weil Helligkeit 6 dann ja erst nach helligkeit 7 wahr wird. Oder? Ich versuchs mal...

Edit: achso nein, stimmt, es bleibt ja wahr... also doch keine Lösung, ihr habt recht

RalfRog

Zitat von: Mad-at am 06 September 2023, 13:39:16Nein wieso? Wenn man auf die Gleichzeitigkeit verzichtet müsste es doch gehen, weil Helligkeit 6 dann ja erst nach helligkeit 7 wahr wird. Oder? Ich versuchs mal...

Edit: achso nein, stimmt, es bleibt ja wahr... also doch keine Lösung, ihr habt recht

Vielleicht habe ich Damian missinterpretiert.
Ich habe mir gerade mal ein DOIF, dass einen Dummy schaltet gebaut.
Da funktioniert es mit verschiedenen Schwellen  bei gleichem Zeittrigger (Leistung des BKM schwindet gerade mit abnehmender Sonne).

define di_test     DOIF ([15:00-19:00] and [S1PM:power] < "150") (set d_test on1)
               DOELSEIF ([15:00-19:00] and [S1PM:power] < "155") (set d_test on2)
               DOELSEIF ([15:00-19:00] and [S1PM:power] < "160") (set d_test on3)

Meine Dummy wurde beim Unterschreiten der Schwellen auf auf den entsprechenden Wert (on1|2|3) gesetzt. Auch wieder von Zweig1 auf Zweig2 als die Power wieder ein wenig anstieg.
FHEM auf Raspi 2B mit nanoCUL, HM-MOD-RPI-PCB und über LAN MAX!Cube mit a-culFW (Stack 868 + 433)
HM- Fensterkontakte, UP-Schalter, Bewegungsmelder und ein Rauchmelder

xenos1984

Zitat von: RalfRog am 06 September 2023, 15:54:49define di_test     DOIF ([15:00-19:00] and [S1PM:power] < "150") (set d_test on1)
               DOELSEIF ([15:00-19:00] and [S1PM:power] < "155") (set d_test on2)
               DOELSEIF ([15:00-19:00] and [S1PM:power] < "160") (set d_test on3)

Das geht aber nur, wenn die Daten oft genug reinkommen, damit eine Schwelle nach der anderen unterschritten wird. Wenn es einen größeren Sprung z.B. von 170 auf 140 gibt, wird gleich der erste Fall wahr und die anderen werden nie abgearbeitet.

Ich würde es machen wie von Damian vorgeschlagen und stattdessen im Perl-Modus arbeiten. Da kann man die einzelnen Zweige in einen gemeinsamen Block packen, der ausgeführt wird, und gezielt z.B. mit if-Abfragen festlegen, was unter welcher Bedingung geschehen soll, ohne dass sich verschiedene Zweige gegenseitig ausschließen.

Damian

Selbst wenn man von Perl keine Ahnung hat, kann man Definitionen aus dem FHEM-Modus leicht mit geringen Anpassungen in Perl-Modus erstmal übertragen, bevor man sie eleganter ausprogrammiert, bzw. vereinfacht, hier z. B.

DOIF  { if ([14:00-23:30] and [Helligkeit_Draussen:state] < 5 and [JalousienEGohneSuedabsolut] eq "0 %")
{fhem("set JalousienEGohneSuedabsolut 18; sleep 20; set JalousienLamellenEGohneSuedabsolut 0; sleep 2; set JalousienLamellenEGohneSuedabsolut 100; sleep 2; set JalousienEGohneSuedabsolut 100")};
if ([14:00-23:30] and [Helligkeit_Draussen:state] < 5 and [Flur_Jalousie] eq "0 %")
{fhem("set Flur_Jalousie 18; sleep 20; set FlurUG_JalousieLamellen 0; sleep 2; set FlurUG_JalousieLamellen 100; sleep 2; set Flur_Jalousie 100")};
if ([14:00-23:30] and [Helligkeit_Draussen:state] < 5 and [Kinderzimmer_Jalousie] eq "0 %")
{fhem("set Kinderzimmer_Jalousie 18; sleep 20; set Kinderzimmer_JalousieLamellen 0; sleep 2; set Kinderzimmer_JalousieLamellen 100; sleep 2; set Kinderzimmer_Jalousie 100")};
...
}
   
   
Hier sind die if-Abfragen unabhängig voneinander.
   
Die Definition muss im DEF-Editor vorgenommen werden, damit man Semikolons nicht doppeln muss (das ist eine ungünstige Eigenschaft von FHEM)

PS
 größer/kleiner-Vergleiche nicht mit Strings durchführen wie z. B. < "5" sondern mit Zahlen, auch wenn Perl vieles verzeiht.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

RalfRog

Zitat von: xenos1984 am 06 September 2023, 18:08:00Das geht aber nur, wenn die Daten oft genug reinkommen, damit eine Schwelle nach der anderen unterschritten wird. Wenn es einen größeren Sprung z.B. von 170 auf 140 gibt, wird gleich der erste Fall wahr und die anderen werden nie abgearbeitet.

Das ist völlig richtig - ich wollte jetzt einfach nur mal konkret das Ergebnis mit den zwei Bedingungen sehen, weil es überschaubar ist.

Mad-at kann es zwar mal probieren, sollte sich aber auch aufgrund deiner Anmerkungen letztlich für den PerlModus entscheiden. Damians Vorschlag ist ja da.


FHEM auf Raspi 2B mit nanoCUL, HM-MOD-RPI-PCB und über LAN MAX!Cube mit a-culFW (Stack 868 + 433)
HM- Fensterkontakte, UP-Schalter, Bewegungsmelder und ein Rauchmelder

Mad-at

Zitat von: Damian am 06 September 2023, 18:48:54Selbst wenn man von Perl keine Ahnung hat, kann man Definitionen aus dem FHEM-Modus leicht mit geringen Anpassungen in Perl-Modus erstmal übertragen, [...]

Vielen Dank, ich bin endlich dazu gekommen und es funktioniert so fabelhaft! Auch schon mit fhem_set optimiert :)