FHEM Forum

FHEM => Automatisierung => DOIF => Thema gestartet von: ZeitlerW am 09 Februar 2016, 08:30:19

Titel: Befehlssequenz abarbeiten mit warten auf Rückmeldungen
Beitrag von: ZeitlerW am 09 Februar 2016, 08:30:19
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
Titel: Antw:Befehlssequenz abarbeiten mit warten auf Rückmeldungen
Beitrag von: Ellert am 09 Februar 2016, 10:28:07
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
Titel: Antw:Befehlssequenz abarbeiten mit warten auf Rückmeldungen
Beitrag von: ZeitlerW am 09 Februar 2016, 11:24:43
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
Titel: Antw:Befehlssequenz abarbeiten mit warten auf Rückmeldungen
Beitrag 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.
Titel: Antw:Befehlssequenz abarbeiten mit warten auf Rückmeldungen
Beitrag von: ZeitlerW am 10 Februar 2016, 11:24:36
Hallo Ellert,

vielen lieben Dank!
Eigentlich schon cool was man mit DOIF alles so machen kann.

Ich werde testen und berichten.

lG
Wolfgang
Titel: Antw:Befehlssequenz abarbeiten mit warten auf Rückmeldungen
Beitrag von: td am 06 Januar 2017, 11:46:58
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
Titel: Antw:Befehlssequenz abarbeiten mit warten auf Rückmeldungen
Beitrag von: Ellert am 06 Januar 2017, 11:56:06
Für eine leere Befehlssequenz, damit es ein cmd_x_1 gibt.
Titel: Antw:Befehlssequenz abarbeiten mit warten auf Rückmeldungen
Beitrag von: Thorsten Pferdekaemper am 06 Januar 2017, 13:43:17
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
Titel: Antw:Befehlssequenz abarbeiten mit warten auf Rückmeldungen
Beitrag von: td am 06 Januar 2017, 19:19:20
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
Titel: Antw:Befehlssequenz abarbeiten mit warten auf Rückmeldungen
Beitrag 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
Titel: Antw:Befehlssequenz abarbeiten mit warten auf Rückmeldungen
Beitrag von: td am 06 Januar 2017, 20:20:16
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
Titel: Antw:Befehlssequenz abarbeiten mit warten auf Rückmeldungen
Beitrag von: Ellert am 06 Januar 2017, 20:26:37
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) ()
Titel: Antw:Befehlssequenz abarbeiten mit warten auf Rückmeldungen
Beitrag von: td am 06 Januar 2017, 21:33:49
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
Titel: Antw:Befehlssequenz abarbeiten mit warten auf Rückmeldungen
Beitrag von: Ellert am 07 Januar 2017, 08:41:11
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)