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.
siehe https://forum.fhem.de/index.php/topic,91896.msg844417.html#msg844417
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
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.
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
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.
Sorry, dass ich nochmals nachfragen muss, aber was meinst Du mit ,,strukturierter Programmierung"?
Vielleicht hast Du mir ein Beispiel?
Gruß Chris
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.
D.h. im Umkehrschluss, dass ich das o.a. DOIF besser in einzelne DOIFs aufteilen soll, richtig?
Gruß Chris
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
...
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
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?
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
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
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