Hallo zusammen,
ich möchte mit (KNX-) Aktoren eine Befehlssequenz abarbeiten. Dabei bei jedem Schritt auf das Rückmeldeobjekt das Aktors gewartet werden. Ich stelle mir da folgenden pseudo -code vor:
set Relais1 on
warte auf Rückmeldung Relais1 = on, timeout mit Abbruch 3 sec
set Relais1 off
warte auf Rückmeldung Relais1 = off, timeout mit Abbruch 3 sec
set Relais2 on
warte auf Rückmeldung Relais2 = on, timeout mit Abbruch 3 sec
set Relais2 off
warte auf Rückmeldung Relais2 = off, timeout mit Abbruch 3 sec
Das Ganze sollte natürlich NonBlocking sein :)
lG
Wolfgang
Das kannst Du mit DOIF realisieren etwa so:
di DOIF ([TriggerA]) (set A on) (IF ([RückmeldungA] eq "on") (mach dies) ELSE (mach das), ...)
Attribute
wait 0,3, ...
s. http://fhem.de/commandref_DE.html#DOIF
Hallo Ellert,
vielen Dank für die Anregung. Das Problem ist ja hier, daß er fest 3 Sekunden wartet bis die Rückmeldung ausgewertet wird. Die Sequenz soll weiter laufen sobald der Rückmeldungs - Event kommt.
Damit müßte man es mit event - getriggert mit kaskadierten DOIFs machen.
Vielleicht gibts da ja was mit notify und Sleep mit Abbruchbedingung.
lG
Wolfgang
di DOIF ([Trigger]) (set A on) ()
DOELSEIF ([Aquit] eq "on" and [?di] eq "cmd_1_1") (set A off) ()
DOELSEIF ([Aquit] eq "off" and [?di] eq "cmd_2_1") (set B on) ()
DOELSEIF ([Bquit] eq "on" and [?di] eq "cmd_3_1") (set B off) ()
DOELSEIF ([Bquit] eq "off" and [?di] eq "cmd_4_1")
wait 0,3:0,3:0,3:0,3:0
Das DOIF bewegt sich nach unten, wenn innerhalb von 3 s die Quittung erfolgt, sonst steigt es nach rechts aus.
Hallo Ellert,
vielen lieben Dank!
Eigentlich schon cool was man mit DOIF alles so machen kann.
Ich werde testen und berichten.
lG
Wolfgang
Zitat von: Ellert am 09 Februar 2016, 14:59:30
di DOIF ([Trigger]) (set A on) ()
DOELSEIF ([Aquit] eq "on" and [?di] eq "cmd_1_1") (set A off) ()
DOELSEIF ([Aquit] eq "off" and [?di] eq "cmd_2_1") (set B on) ()
DOELSEIF ([Bquit] eq "on" and [?di] eq "cmd_3_1") (set B off) ()
DOELSEIF ([Bquit] eq "off" and [?di] eq "cmd_4_1")
wait 0,3:0,3:0,3:0,3:0
Das DOIF bewegt sich nach unten, wenn innerhalb von 3 s die Quittung erfolgt, sonst steigt es nach rechts aus.
Wofür steht das Paar leerer runder Klammern?
Gruß,
td
Für eine leere Befehlssequenz, damit es ein cmd_x_1 gibt.
Hi,
ich habe mir mal überlegt, sowas wie ein "FhemScript"-Modul zu bauen. Einen sehr eingeschränkten Prototypen habe ich auch schon. Ein "FhemScript"-"Gerät" hätte dann ein Attribut (oder so), in dem ein Programm gespeichert ist. Das Programm sähe in dem Fall in etwa so aus:
set Relais1 on
wait until Relais1:state.on or 3
if not Relais1:state.on
exit
end
set Relais1 off
wait until Relais1:state.off or 3
if not Relais1:state.off
exit
end
set Relais2 on
wait until Relais2:state.on or 3
if not Relais2:state.on
exit
end
set Relais2 off
wait until Relais2:state.off or 3
if not Relais2:state.off
exit
end
Das ist zwar länger als mit DOIF, aber weniger kryptisch. Es wären auch Kommentarzeilen dazwischen erlaubt. Das ganze könnte dann mittels "set <script-device> run" gestartet werden. ...oder wenn es z.B. irgend ein bestimmtes Start-Event gibt, dann kann das ins Programm integriert werden:
loop
wait for device:reading.value
set Relais1 on
wait until Relais1:state.on or 3
if not Relais1:state.on
exit
end
set Relais1 off
wait until Relais1:state.off or 3
if not Relais1:state.off
exit
end
set Relais2 on
wait until Relais2:state.on or 3
if not Relais2:state.on
exit
end
set Relais2 off
wait until Relais2:state.off or 3
if not Relais2:state.off
exit
end
end
Zwischen den einzelnen Zeilen erhält FHEM die Kontrolle zurück. Die wait-Zeilen sind über interne notifies bzw. interne ats abgebildet. D.h. da blockiert nichts.
Wie gesagt, momentan ist das nur so eine Idee, aber falls das auf großes Interesse stößt...
Gruß,
Thorsten
Zitat von: Ellert am 06 Januar 2017, 11:56:06
Für eine leere Befehlssequenz, damit es ein cmd_x_1 gibt.
Danke.
Ich habe tatsächlich einige Minuten benötigt, incl. erneutem Lesen von DOIF-Dokumentation und Beispielen, um es nachvollziehen zu können. Das Klammernpaar ist also cmd_1_2, das erst nach 3 s ausgeführt wird. Zuvor ist der aktuelle cmd-Befehl cmd_1_1. Solange dieses der Fall ist und noch nicht cmd_1_2 ausgeführt ist, triggert bei "[Aquit] eq "on"" das erste DOELSEIF.
Bin wahrlich beeindruckt!
td
Kleine Korrektur, der letzte Status enthält keine Sequenznr. mehr
()
cmd_1
() ()
cmd_1_1 cmd_1
() () ()
cmd_1_1 cmd_1_2 cmd_1
Zitat von: Ellert am 06 Januar 2017, 20:06:36
Kleine Korrektur, der letzte Status enthält keine Sequenznr. mehr
()
cmd_1
() ()
cmd_1_1 cmd_1
() () ()
cmd_1_1 cmd_1_2 cmd_1
Der letzte Befehl einer Befehlssequenz erhält also keinen zweiten Index. Ist dieser denn optional oder ist er nicht korrekt, sprich kann ich, der Leserlichkeit halber, trotzdem cmd_1_3 (im letzten Beispiel) verwenden. Die Dokumentation schweigt sich über das Detail leider aus.
td
Nein, per Default ist der letzte Status (Reading state/Internal STATE) immer ohne Sequenznummer. Das aus Kopatibilität zu früheren DOIF Versionen so, als es noch keine Sequenzen gab.
Du kannst aber die Status mit dem Attribut "cmdState" umdefinieren.
Alternativ kannst Du auch das Reading cmd nehmen oder die Perl-Variable $cmd, da gibt es dann auch $cmd == 1.2 für die letzte Sequenz
DOELSEIF ([Aquit] eq "on" and $cmd == 1.1) (set A off) ()
Danke für Deine hilfreichen Ausführungen.
Ich habe nur noch ein Verständnisproblem, bzw. nun, da ich auch getestet habe, ein technisches:
Ich hatte erwartet, daß bei
di DOIF ([Trigger]) (set A on) ()
DOELSEIF ([Aquit] eq "on" and [?di] eq "cmd_1_1") (set A off)
DOELSE (cmd_2)
wait 0,3:0:0
im Falle eines Timeouts der DOELSE-Zweig durchlaufen wird. Bei meinem Test ist das aber nicht der Fall.
Mache ich da einen Denkfehler?
td
ZitatMache ich da einen Denkfehler?
Ich weiss leider nicht, was Du Dir dabei gedacht hast. Auf jeden Fall ist "DOELSE (cmd_2)" keine gültige Syntax. Ansonsten könntest Du dein Denken mit dieser Erläuterung abgleichen Struktur_und_Verhalten_des_DOIF (https://wiki.fhem.de/wiki/DOIF/Einsteigerleitfaden,_Grundfunktionen_und_Erl%C3%A4uterungen#Struktur_und_Verhalten_des_DOIF)