DOIF schaltet per selftrigger nicht weiter

Begonnen von chq, 11 Oktober 2018, 12:37:35

Vorheriges Thema - Nächstes Thema

chq

Hallo,

hab hier ein etwas "vertracktes" DOIF namens "doif_rolloEZhandler", dass sich nicht ganz so verhält, wie ich es erwarten würde.

(#1) (setreading $SELF doifState fhemCmd) ## Wird bei Sonneneinstrahlung von doif_Sonnenstand aufgerufen

DOELSEIF ([$SELF:doifState] eq "fhemCmd") (setreading $SELF doifState idle) ## Nach "wait" Übergang nach "idle"

DOELSEIF ([HM_rolloEsszimmer:""] and [$SELF:doifState] eq "idle") (set doif_Sonnenstand disable) ## Wenn Event von Rollo Esszimmer: doif_Sonnenstand deaktivieren

DOELSEIF ([00:00]) (set doif_Sonnenstand enable) (set doif_Sonnenstand cmd_1) ## Wenn 0:00 Uhr: doif_Sonnenstand aktivieren


wait 0:40:0:0
cmdState fhemCmd|idle|sonnenstandDisabled|idle
startup set $SELF cmd_2
selftrigger all


Wenn ich von einem anderen DOIF aus "set doif_rolloEZhandler cmd_1" mache, schaltet das DOIF nicht bis einschließlich cmd_2 weiter.

Das DOIF bleibt bei doifState "fhemCmd" stehen und nimmt nicht den Wert "idle" an, obwohl dies aus meiner Sicht so sein sollte.

Ist das hier (laut Commandref) mein Problem (siehe nächster Satz)?

Bei der Verwendung des Attributes selftrigger all sollte beachtet werden, dass bereits in der zweiten Rekursion, wenn ein Befehl nicht durch wait verzögert wird, FHEM eine weitere Triggerung unterbindet, um Endlosschleifen zu verhindern.

Falls ja, wie könnte ich das alternativ lösen?

Eigentlich war ich der Meinung, dass es funktionieren müsste, weil ich bei cmd_2 ein wait verwende.

Ich verwende in einem anderen Objekt bereits auch ein Reading namens "doifState". Auch hier gehe ich davon aus, dass dies eigentlich nichts ausmachen sollte.

Gruß Chris

Edit: Fragestellung wurde editiert, sorry.
So einfach wie möglich, so kompliziert wie nötig

Damian

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

chq

Wäre Deine Empfehlung also, dass ich mich (endlich mal) mit dem Perl-Modus (schauder!) beschäftigen, oder es mit "wait 1:40:0:0" versuchen sollte?

Gruß Chris
So einfach wie möglich, so kompliziert wie nötig

Damian

Zitat von: chq am 11 Oktober 2018, 13:10:25
Wäre Deine Empfehlung also, dass ich mich (endlich mal) mit dem Perl-Modus (schauder!) beschäftigen, oder es mit "wait 1:40:0:0" versuchen sollte?

Gruß Chris
Nicht nur da, du hast auch noch Befehls-Sequenzen definiert, wo set ... cmd vorkommt, die müsstest du auch einzeln verzögern. Der set-cmd-Befehl war eigentlich nicht dafür gedacht ihn im eigenen DOIF, sondern nur von außerhalb zu verwenden.

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

chq

Wie soll man am Besten innerhalb eines DOIFs in einen anderen "Zustand" wechseln, wenn nicht über ein Reading in Kombination mit selftrigger?

Ich möchte DOIFs praktisch gerne als FSMs nutzen.

Gruß Chris
So einfach wie möglich, so kompliziert wie nötig

Damian

Zitat von: chq am 11 Oktober 2018, 13:24:04
Wie soll man am Besten innerhalb eines DOIFs in einen anderen "Zustand" wechseln, wenn nicht über ein Reading in Kombination mit selftrigger?

Ich möchte DOIFs praktisch gerne als FSMs nutzen.

Gruß Chris

Gar nicht. Damit produzierst du einen goto-Spagetti-Code, den du bald selbst nicht mehr verstehst. Benutze lieber strukturierte Programmierung als FSM.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

chq

Sorry, dass ich nochmals nachfragen muss, aber was meinst Du mit ,,strukturierter Programmierung"?

Vielleicht hast Du mir ein Beispiel?

Gruß Chris
So einfach wie möglich, so kompliziert wie nötig

Damian

Da muss man nicht lange suchen :)

https://de.wikipedia.org/wiki/Strukturierte_Programmierung

Dort steht:

ZitatDie bekannteste Konsequenz dieses Prinzips ist die Vermeidung oder – abhängig von der Programmiersprache – der eingeschränkte und standardisierte Einsatz der Sprunganweisung, des GOTO. Das Ergebnis der häufigen Verwendung dieser Anweisungen wird häufig abfällig als Spaghetticode bezeichnet.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

chq

D.h. im Umkehrschluss, dass ich das o.a. DOIF besser in einzelne DOIFs aufteilen soll, richtig?

Gruß Chris
So einfach wie möglich, so kompliziert wie nötig

Damian

Zitat von: chq am 11 Oktober 2018, 13:53:20
D.h. im Umkehrschluss, dass ich das o.a. DOIF besser in einzelne DOIFs aufteilen soll, richtig?

Gruß Chris

z. B. , allerdings hast du ein Problem auf mehrere Definitionen verteilt - das ist auch suboptimal. Größere Code-Segmente lassen sich in Perl-Funktionen in myutils auslagern.

Das hat mir aber alles nicht gefallen, deswegen habe ich ja den neuen Perl-Modus eingeführt, damit kannst du:

1. lokale Perl-Funktionen im DOIF-Device definieren, diese sind gekapselt und stören sich nicht mit bestehenden in der restlichen FHEM-Welt
2. beliebig viele Blöcke in einem DOIF-Device definieren, die unabhängig voneinander sind (im FHEM-Modus nur einer)
3. Perl-Instanzvariablen nutzen, die ihren Wert bis zum nächsten Trigger behalten, die du noch nicht mal definieren musst
4. beliebig viele benannte Timer nutzen, deren Laufzeit du abfragen oder auch vorzeitig beenden kannst (im FHEM-Modus nur einer, ohne Laufzeitabfrage)
5. sehr performant arbeiten, da weitgehend ohne FHEM-Parser gearbeitet wird und die gesamte Definition in Perl übersetzt wird, selbst für den häufig genutzten FHEM-set-Befehl gibt es eine Perl-Funktion
5. vereinfachte Perl-Funktionen zum Setzen oder Abfragen des Status, Readings, usw. nutzen
...
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

chq

Hallo,

mein erster Schritt in Richtung Perl-Modus.. leider fährt der Rolladen nicht und ich weiss nicht warum.

Internals:
   CFGFN     
   DEF        {if([09:02]) {fhem_set"HM_rolloEsszimmer pct 90"}}
   MODEL      Perl
   NAME       doif_rolloEZhandlerPerl
   NR         6146
   NTFY_ORDER 50-doif_rolloEZhandlerPerl
   STATE      initialized
   TYPE       DOIF
   READINGS:
     2018-10-13 09:02:42   mode            enabled
     2018-10-13 09:02:42   state           initialized
     2018-10-13 09:02:42   timer_01_c01    14.10.2018 09:02:00
   Regex:
   condition:
     0          if(DOIF_time_once($hash,0,$wday)) {fhem_set"HM_rolloEsszimmer pct 90"}
   days:
   devices:
   helper:
     globalinit 1
     last_timer 1
     sleeptimer -1
   intervalfunc:
   itimer:
   localtime:
     0          1539500520
   perlblock:
     0         
   realtime:
     0          09:02:00
   time:
     0          09:02:00
   timeCond:
     0          0
   timer:
     0          0
   timers:
     0           0
   triggertime:
     1539500520:
       localtime  1539500520
       hash:
   uiState:
   uiTable:
Attributes:


Gruß Chris
So einfach wie möglich, so kompliziert wie nötig

Ellert

Du hast zu spät initialisiert, 09:02:42 liegt nach 09:02, daher klappt es erst morgen.

Hast Du Dir das Listing selbst nicht angesehen?

chq

Nein, das Problem war nicht, dass ich zu spät initialisiert habe.

Was ist ein Listing?

So funktioniert es jetzt (DEF):

{if([09:19]) {fhem("set HM_rolloEsszimmer pct 100")}}

Trotzdem danke.

Gruß Chris
So einfach wie möglich, so kompliziert wie nötig

Damian

Zitat von: chq am 13 Oktober 2018, 09:50:06
Nein, das Problem war nicht, dass ich zu spät initialisiert habe.

Was ist ein Listing?

So funktioniert es jetzt (DEF):

{if([09:19]) {fhem("set HM_rolloEsszimmer pct 100")}}

Trotzdem danke.

Gruß Chris

Ich nehme an, dass HM_rolloEsszimmer ein Homematic-Rollladenaktor ist - den habe ich auch.

und es funktioniert sowohl  fhem("set HM_rolloEsszimmer pct 100") als auch fhem_set("HM_rolloEsszimmer pct 100")

Alles andere wäre nicht nachvollziehbar, weil beides den gleichen internen Befehl ausführt.

Also, daran kann es nicht gelegen haben.

Abgesehen davon hast uns im Listing das hier gepostet:

   READINGS:
     2018-10-13 09:02:42   mode            enabled
     2018-10-13 09:02:42   state           initialized
     2018-10-13 09:02:42   timer_01_c01    14.10.2018 09:02:00


Die Definition hat am 13.10 um 9:02:42 stattgefunden, dann kann man nicht erwarten, dass das Modul am  13.10 um 9:02:00 schaltet, sondern   timer_01_c01    14.10.2018 09:02:00
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

chq

Hallo,

ich habe es eben noch einmal ausprobiert und kann bestätigen, dass ihr Recht habt.

Es funktionieren beide Schreibvarianten. Es war wohl ein Fehler meinerseits.

Danke auch für die Erklärungen bzgl. des Listings.

Gruß Chris
So einfach wie möglich, so kompliziert wie nötig