FHEM Forum

FHEM => Automatisierung => DOIF => Thema gestartet von: Pfriemler am 15 Juni 2020, 12:12:23

Titel: [gelöst] Bedingte Verzögerung im DOIF - elegante Lösung?
Beitrag von: Pfriemler am 15 Juni 2020, 12:12:23
Wie kann ich im Ausführungsteil eines DOIF die Abarbeitung von Befehlen fallabhängig wirksam verzögern?
- Wenn ewas ist, mach A und warte,
- mach B
Also im Falle "es ist", wäre die Ausführung dann "A,warten,B", sonst "sofort B"

Hintergrund:
Ich habe hier eine schaltdimmbare Lampe: War sie länger aus, startet sie mit 100% Helligkeit, schaltet man sie kurz aus und wieder, reduziert sich ihre Helligkeit auf 30, dann auf 10%, dann wieder voll ...
Um sie also auf 10% zu bekommen:
- (ein)(aus)(ein)(aus)(ein)
War sie bereits eingeschaltet, dann muss die Folge lauten:
- (aus)(5s warten)(ein)(aus)(ein)(aus)(ein)
Die erste Schaltaktion ist natürlich nur erforderlich, wenn die Lampe zuvor eingeschaltet war. Also fragt man ab:
(IF ([OGWLicht] eq "on")(set OGWLicht off, sleep 5 quiet), set OGWLicht on, set OGWLicht off, set OGWLicht on, set OGWLicht off, set OGWLicht on)

und schickt damit FHEM in die ewigen Jagdgründe: kein Befehl nach sleep = Freeze.
Ergänze ich nach der Klammer einen Einschaltbefehl,
(IF ([OGWLicht] eq "on")(set OGWLicht off, sleep 5 quiet, set OGWLicht on), set OGWLicht on, set OGWLicht off, set OGWLicht on, set OGWLicht off, set OGWLicht on)
erfolgt der dann doppelt hintereinander, das macht nichts - aber es funktioniert trotzdem nicht, weil beide Befehlsketten parallel abgearbeitet werden:
off (aus der IF-Klammer), on,off,on,off,on (aus dem Teil nach dem IF) - und nach 5s Verzögerung on (aus der IF-Klammer).

Natürlich kann ich die Befehlsketten auch ausführlich je nach Fall ausschreiben, aber das finde ich unelegant.
Bessere Lösung?

Titel: Antw:Bedingte Verzögerug im DOIF - elegante Lösung?
Beitrag von: KernSani am 15 Juni 2020, 12:30:15
sollte das nicht mit dem wait Attribut funktionieren (und ein bisschen umschreiben des DOIF), also etwa so:

("Trigger" and "Lampe ist an")
(mache A)
(führe CMD2 aus)
DOELSIF ("Trigger" and "Lampe ist aus")
(mache B)
[/code}
und 5 Sekunden wait auf CMD1_1
Ob das jetzt eleganter ist sei mal dahingestellt, aber vielleicht eine Idee ;-)
Titel: Antw:Bedingte Verzögerug im DOIF - elegante Lösung?
Beitrag von: Pfriemler am 15 Juni 2020, 12:51:34
Ja, dammich. Auf die Idee einen anderen command-Ausführungszweig zu triggern um so Code zu sparen war ich noch nicht gekommen.
edit: (Klartextentwurf durch funktionierende DEF ersetzt)

defmod di_LichtOGW_Dimmstufen DOIF ([$SELF:level] eq "AUS") (set OGWLicht off) \
DOELSEIF ([$SELF:level] ne "AUS" and [?OGWLicht] eq "on") ## ausschalten, wenn an, und nach Verzögerung\
(set OGWLicht off)\
(set $SELF cmd_3) ## Zweig 3 ausführen\
DOELSEIF ([$SELF:level] ne "AUS" and [?OGWLicht] eq "off")\
(set OGWLicht on, ## erst mal an\
IF ([$SELF:level] ne "HELL") (set OGWLicht off, set OGWLicht on), ## also DUNKEL oder MITTEL\
IF ([$SELF:level] eq "DUNKEL") (set OGWLicht off, set OGWLicht on)) ## bei DUNKEL zusätzlich\

attr di_LichtOGW_Dimmstufen do always
attr di_LichtOGW_Dimmstufen readingList level
attr di_LichtOGW_Dimmstufen setList level:uzsuSelectRadio,AUS,DUNKEL,MITTEL,HELL
attr di_LichtOGW_Dimmstufen wait 0:0,5:0
attr di_LichtOGW_Dimmstufen webCmd level


Läuft super, vielen Dank.

Danke auch an den Vorschlag von Damian mit dem perl-DOIF, aber ich komme nicht über die Schwelle ... ich liebe gerade diesen selbstsprechenden Code. Bin ja deswegen von notify etc weg...
Titel: Antw:Bedingte Verzögerug im DOIF - elegante Lösung?
Beitrag von: Damian am 15 Juni 2020, 13:34:57
Besonders "elegant" ist so etwas im Perlmodus, da man dort direkt die Verzögerungszeit angeben kann

DOIF {
my $delay;
if (...) {$delay=0} elsif {$delay=10};
set_Exec ("mytimer",$delay,'fhem_set("bla on")');
}