Hallo Leute,
keine Ahnung, ob das überhaupt irgendwie funktioniert, aber ich habe folgende Anforderung...:
in folgendem definiertem DOIF sind ja 4 Kommandos die ausgeführt wären, die da wären:
set WZ.Tuer.Motorlaeuft inactive
set WZ.Rollo.Tuer pct 20
set WZ.Tuer.Lueftungsmodus.Status on
set WZ.Tuer.Motorlaeuft active
hier der komplette DOIF:
define WZ.Tuer.LueftungsmodusAn DOIF ([WZ.Rollo.Tuer:pct] < 20 and [WZ.Senor.Tuer] eq "open") (set WZ.Tuer.Motorlaeuft inactive, set WZ.Rollo.Tuer pct 20, set WZ.Tuer.Lueftungsmodus.Status on)
Nun möchte ich, dass das letzte Kommando "set WZ.Tuer.Motorlaeuft active" erst nach 10 Sekunden nachdem das Kommando "set WZ.Tuer.Lueftungsmodus.Status on" ausgeführt wurde, ausgeführt wird.
Ist das möglich ?
Sorry, ich weiß etwas kompliziert, aber dafür ist das Forum ja hoffentlich da :) !
Vielen Dank schonmal im Voraus !
attr WZ.Tuer.LueftungsmodusAn wait 0,0,10
Damit sollte das letzte Set nach 10 Sekunden ausgeführt werden, die drei vorher sofort.
Ich meine dafür musst du deinen Ausführungsteil abändern:
(set WZ.Tuer.Motorlaeuft inactive)(set WZ.Rollo.Tuer pct 20)(set WZ.Tuer.Lueftungsmodus.Status on)
Danke!
Nach ein wenig rumprobieren klappt es jetzt.
Allerdings hat es zuerst nicht geklappt.
Erst nachdem ich noch zusätzlich das "attr do always" gesetzt habe.
Kannst du erklären, warum dies gesetzt werden muss und wozu es dar ist ?
Aus dem Wiki Artikel geht das für mich nicht verständlich hervor... :(
Vielen Dank im Voraus.
Was genau ist an dem Wiki-Artikel für Dich unverständlich? Deine Antwort könnte den Artikel verbessern.
Ist die Erklärung in der Befehlsreferenz für Dich verständlicher?
Weiß nicht, wie ich es beschreiben soll, was ich nicht verstehe...
Ich verstehe eigentlich den Grundsatz von dem nicht, was "do always" tut ...
Ich habe andere DOIF's ohne "do always" die auch mehr als 1x funktionieren, also immer wenn die IF Bedingung erfüllt wird.
In der Commandref ist das "do always" für mich genau so unverständlich...
Vielleicht hat ja nochmal einer die Güte mir das kurz etwas näher / verständlicher zu erläutern ! :)
Wenn Du nicht sagen kannst, was Du nicht verstehst ist es schwer Dir zu helfen. Ich halte die Aussage in der Befehlsreferenz für verständlich.
ZitatDas DOIF-Modul arbeitet mit Zuständen. Jeder Ausführungszweig DOIF/DOELSEIF..DOELSEIF/DOELSE stellt einen eigenen Zustand dar (cmd_1, cmd_2, usw.). Das Modul merkt sich den zuletzt ausgeführten Ausführungszweig und wiederholt diesen standardmäßig nicht. Ein Ausführungszweig wird erst dann wieder ausgeführt, wenn zwischenzeitlich ein anderer Ausführungszweig ausgeführt wurde, also ein Zustandswechsel stattgefunden hat.
Also vielleicht bin ich einfach zu doof, aber es ist für mich nicht verständlich... !
Vielleicht können wir das ja nochmal anhand meines Falles von oben als Beispiel aufzeigen...
Also, Beispiel:
Ich habe eine DOIF Bedingung, die erfüllt werden muss.
Wenn diese erfüllt ist, werden 4 Kommandos ausgeführt.
Das 4. Kommando soll erst nach 10 Sekunden ausgeführt werden.
Also habe ich wie oben geschrieben das Attribut "wait 0,0,0,10" gesetzt.
Kannst du erklären, wie sich das ganze verhält, wenn ich kein do always aktiviere und wenn ich es aktiviere.
(Mit aktiviertem Do always) läuft es ja, aber ich verstehe nicht warum !
Vielen Dank für deine Geduld :)
Ich versuche es mal in einfache Worten. Wenn dein DOIF CMD_1 ausgeführt hat, wird es CMD_1 nicht nocheinmal ausführen solange es im Status CMD_1 bleibt, auch wenn die Bedingungen erneut eintreten.
Mit do always wird CMD_1 auch ausgeführt, wenn der Status CMD_1 ist.
Und hier noch einmal mit anderen Worten.
Zitatwenn ich kein do always aktiviere
Das hast Du doch schon selbst beobachtet.
Es wird der Befehlsteil einmal ausgeührt und erst, wenn vorher der Zustand cmd_2 eingetreten ist, dann wird nach Prüfen der Bedingung und erfüllter Bedingung, der Befehlsteil erneut ausgeführt.
Zitatwenn ich es aktiviere
Es wird immer geschaltet, egal ob Zustand cmd_2 zwischendurch eintritt.
Die Worte "do always" stammen aus der englischen Sprache und können mit "tue es immer" übersetzt werden.
Okay, ich danke euch... ! :)
Aber wieso wird das 4. Set-Kommando nicht ausgeführt, wenn ich "do always" deaktiviert habe ?
Es müssten dann doch trotzdem alle 4 Kommandos 1x ausgeführt werden.
Das ist ja genau, was ich möchte !
wait-Timer werden abgebrochen, wenn ein Zustandswechsel stattfindet während sie laufen.
Ah okay, gibt es eine Art "ignore" Modus, dass sie eben nicht abgebrochen werden, den man einstellen kann ?
Du könntest in einem DOELSEIF-Zweig eine Bedingung formulieren, die einen vorzeitigen Statuswechsel verhindert.
Okay, wie würde sowas dann aussehen ? ;)
Also der Status der sich verändert ist bei mir dieser:
[WZ.Rollo.Fenster:pct] < 20
Sobald das Rollo auf 20% ist, was relativ schnell geht, ist die DOIF Bedingung nicht mehr gültig.
Vielen vielen Dank nochmals für eure Hilfe :)
Zitat von: geforce28 am 14 Januar 2018, 19:33:55
Okay, wie würde sowas dann aussehen ? ;)
Also der Status der sich verändert ist bei mir dieser:
[WZ.Rollo.Fenster:pct] < 20
Sobald das Rollo auf 20% ist, was relativ schnell geht, ist die DOIF Bedingung nicht mehr gültig.
Vielen vielen Dank nochmals für eure Hilfe :)
Leg mal was vor, das etwa so aussieht ;)
DOELSEIF (<eine Bedingung die nur dann wahr wird, wenn der letzte Befehl des 1. Zweiges abgearbeitet ist.>)
Bevor du dir da einen abbrichst mit Hilfskonstrukten (wobei ich mir durchaus vorstellen kann, dass ellert oder damian auch eine elegante Lösung finden): Schiess doch dein letztes Kommando mit einem guten, alten AT los...
Edit: und während ich das schreibe kommt ellert mit einem Ansatz :-)
Normalerweise wird die Abarbeitung abgebrochen, wenn ein anderer Zustand (cmd_2) zuschlägt. Das ist der Normalfall, denn mit einem neuen Zustand ist das Vorhaben (hier eine verzögerte Ausführung) passé.
Das lässt sich mit einem einfachen sleep umgehen: (set bla 1, set bla 2,sleep 10;set bla 3)
Hier wird auf jeden Fall set bla 3 ausgeführt. Die Frage ist nur: Will man das wirklich, wenn sich die Bedingung bereits verändert hat, hier >= 20.
Edit: Ich würde überlegen, was im DOELESIF-Fall (>= 20) passieren soll, vielleicht erledigt sich dann dein Vorhaben den letzten Befehl auf jeden Fall ausführen zu wollen, wenn er schon längst nicht mehr aktuell ist.
So, also habe jetzt folgendes Konstrukt gebaut und es scheint zu funktionieren...
Hätte aber trotzdem gerne mal eure Meinung, ob das so jetzt optimal umgesetzt ist ?
([WZ.Rollo.Fenster:pct] < 20 and [WZ.Sensor.Fenster] eq "open") (set WZ.Fenster.Motorlaeuft inactive)(set WZ.Rollo.Fenster pct 20)(set WZ.Fenster.Lueftungsmodus.Status on)
DOELSEIF ([WZ.Rollo.Fenster:pct] == 20 and [WZ.Sensor.Fenster] eq "open") (set WZ.Fenster.Motorlaeuft active)
Und als attr: "wait 0,0,0:20".
Was ich damit wie gesagt bezwecken möchte ist folgendes:
Es sollen die ersten 3 "CMD'S"
(set WZ.Fenster.Motorlaeuft inactive)(set WZ.Rollo.Fenster pct 20)(set WZ.Fenster.Lueftungsmodus.Status on)
abgearbeitet werden ohne pause. Währenddessen ändert sich der Status aber, weil
[WZ.Rollo.Fenster:pct] < 20
nicht mehr gültig ist, sondern [WZ.Rollo.Fenster:pct] == 20
gültig wird.
Wenn dies der fall ist soll nach 20 sekunden Zeitablauf folgendes Kommando ausgeführt werden:
(set WZ.Fenster.Motorlaeuft active)
EDIT:
Wird das DOELSEIF jetzt wirklich nur dann ausgeführt, wenn das erste DOIF ausgeführt wurde und anschließend die Bedingungen des DOIF's ungültig wurde?
Vorsicht: du könntest eine Selbsttriggerung (https://fhem.de/commandref_DE.html#DOIF_selftrigger) benötigen!
Zitat von: geforce28 am 16 Januar 2018, 16:14:46
Und als attr: "wait 0,0,0:20".
Wenn du keine weiteren Attribute vergibst, ist
wait 0,0,0 selten notwendig. Hier z.B. nicht.
([WZ.Rollo.Fenster:pct] < 20 and [WZ.Sensor.Fenster] eq "open") (set WZ.Fenster.Motorlaeuft inactive,set WZ.Rollo.Fenster pct 20,set WZ.Fenster.Lueftungsmodus.Status on)
DOELSEIF ([WZ.Rollo.Fenster:pct] == 20 and [WZ.Sensor.Fenster] eq "open") (set WZ.Fenster.Motorlaeuft active)
wait 0:20
macht das Gleiche mit weniger Last.
Zitat von: geforce28 am 16 Januar 2018, 16:14:46
So, also habe jetzt folgendes Konstrukt gebaut und es scheint zu funktionieren...
Hätte aber trotzdem gerne mal eure Meinung, ob das so jetzt optimal umgesetzt ist ?
([WZ.Rollo.Fenster:pct] < 20 and [WZ.Sensor.Fenster] eq "open") (set WZ.Fenster.Motorlaeuft inactive)(set WZ.Rollo.Fenster pct 20)(set WZ.Fenster.Lueftungsmodus.Status on)
DOELSEIF ([WZ.Rollo.Fenster:pct] == 20 and [WZ.Sensor.Fenster] eq "open") (set WZ.Fenster.Motorlaeuft active)
Und als attr: "wait 0,0,0:20".
Was ich damit wie gesagt bezwecken möchte ist folgendes:
Es sollen die ersten 3 "CMD'S"
(set WZ.Fenster.Motorlaeuft inactive)(set WZ.Rollo.Fenster pct 20)(set WZ.Fenster.Lueftungsmodus.Status on)
abgearbeitet werden ohne pause. Währenddessen ändert sich der Status aber, weil
[WZ.Rollo.Fenster:pct] < 20
nicht mehr gültig ist, sondern [WZ.Rollo.Fenster:pct] == 20
gültig wird.
Wenn dies der fall ist soll nach 20 sekunden Zeitablauf folgendes Kommando ausgeführt werden:
(set WZ.Fenster.Motorlaeuft active)
EDIT:
Wird das DOELSEIF jetzt wirklich nur dann ausgeführt, wenn das erste DOIF ausgeführt wurde und anschließend die Bedingungen des DOIF's ungültig wurde?
Ich würde eher gegen den Status cmd_1 verriegeln, denn der wird erst erreicht, wenn der letzte Befehl abgesetzt wurde, also
DOELSEIF ([WZ.Rollo.Fenster:pct] == 20 and [WZ.Sensor.Fenster] eq "open" and [$SELF] eq "cmd_1")
und nur notwendige Sequenzen erstellen
(set WZ.Fenster.Motorlaeuft inactive, set WZ.Rollo.Fenster pct 20)(set WZ.Fenster.Lueftungsmodus.Status on)
und die Attribute
wait 0,10:1
selftrigger wait
ohne do always
Was heißt "könnte ?
Und wozu ?
Okay, das mit dem wait 0:20 macht sinn. ;)
Was ist denn nun die "bessere" Variante...
Die mit dem DOELSEIF oder den Vorschlag von Demian mit sleep.
(set bla 1, set bla 2,sleep 10;set bla 3)
Hat die Variante mit Sleep irgendwelche vor / Nachteile ?
Zitat von: geforce28 am 16 Januar 2018, 17:18:09
Was heißt "könnte ?
Und wozu ?
Okay, das mit dem wait 0:20 macht sinn. ;)
Was ist denn nun die "bessere" Variante...
Die mit dem DOELSEIF oder den Vorschlag von Demian mit sleep.
(set bla 1, set bla 2,sleep 10;set bla 3)
Hat die Variante mit Sleep irgendwelche vor / Nachteile ?
Mir stellt sich eine ganz andere Frage. Ist es wirklich erforderlich, das [WZ.Rollo.Fenster:pct] < 20 das DOIF triggert, wenn nicht, würde das ursprüngliche wait nicht zurück gesetzt werden und es wäre wahrscheinlich kein DOELSEIF erforderlich.
JA es ist erforderlich.
Aber nochmal bitte zurück zu meiner Frage...
Zitat von: geforce28 am 16 Januar 2018, 17:18:09
Was heißt "könnte ?
Und wozu ?
Okay, das mit dem wait 0:20 macht sinn. ;)
Was ist denn nun die "bessere" Variante...
Die mit dem DOELSEIF oder den Vorschlag von Demian mit sleep.
(set bla 1, set bla 2,sleep 10;set bla 3)
Hat die Variante mit Sleep irgendwelche vor / Nachteile ?
Zitat von: geforce28 am 16 Januar 2018, 19:12:58
JA es ist erforderlich.
Aber nochmal bitte zurück zu meiner Frage...
Wie schon geschrieben wird sleep im Gegensatz zu wait nicht unterbrochen.
Unabhängig davon doktern wir an Symptomen, ohne genau zu wissen, was die ganze Schaltung bezwecken soll.
Als nächstes wird die Frage auftauchen: Was ist mit dem Fall > 20?
Also, sorry, ich möchte das ganze dann mal konkretisieren.
Wenn die Rollade unter 20% ist & das Fenster geöffnet wird (Fenstersensor), soll die Rollade auf 20% fahren.
Dann wird der sog. "Lüftungsmodus" -> Dummy aktiviert.
Wenn anschließend manuell die Rollade gefahren wird, soll der Lüftungsmodus deaktiviert werden.
Wenn die Rollade aber nicht manuell gefahren wird und das Fenster wieder geschlossen wird, soll die Rollade auf 0% fahren.
Zur Prüfung, ob die Rollade gefahren wird, habe ich mir ein Notify gebaut, was prüft, ob der Motor fährt (UP oder Down) und dann den Lüftungsmodus deaktiviert.
define WZ.Fenster.Motorlaeuft notify (WZ.Rollo.Fenster:.*down.*|WZ.Rollo.Fenster:.*up.*) set WZ.Fenster.Lueftungsmodus.Status off