Hallo zusammen,
ich tüftel an einer Lösung, die eigentlich ein zweites DOIF benötigt, was natürlich nicht funktioniert. Mit DOELSEIF komme ich nicht weiter, da bei Beginn ein Befehl (update) stattfindet und die folgenden Bedingungen in Abhängigkeit des Befehls (update) abgearbeitet werden sollen. Mit IF hat das Ganze zwar funktioniert, aber hier habe ich das Problem, dass wait ignoriert wird. Zudem wird es sehr wahrscheinlich eine elegantere Lösung geben. Evtl. einen vorab getriggerten Dummy, der das Update ausführt und je nach Rückgabe die entsprechende Bedingung ausführt? Oder die Rückgabe des update in einer Variablen speichern und diese auswerten?
defmod gimmeHotWater DOIF ([HotWater:"trigger"]) (set Heizung update) (IF ([Heizung:state] =~ "last") ((set Heizung WW-Haupttemperatur 60)(set Heizung WW-einmaliges_Aufladen activate)(set BOSE_7C3866CE97B8 on-for-timer 60)(set BOSE_7C3866CE97B8 volume 25)(set BOSE_7C3866CE97B8 playTrack warmwasser)(set Heizung WW-einmaliges_Aufladen deactivate)(set Heizung WW-Haupttemperatur 50)) ELSE ((set BOSE_7C3866CE97B8 on-for-timer 60)(set BOSE_7C3866CE97B8 volume 25)(set BOSE_7C3866CE97B8 playTrack keineVerbindungHeizung)))
attr gimmeHotWater cmdState 1
attr gimmeHotWater do always
attr gimmeHotWater wait 0:0,2,4,6,10,1798,1800:4,6,10
Könnt ihr mich in die richtige Richtung schubsen?
Natürlich wird das wait in der Form ignoriert. Dein DOIF kann man so strukturieren:
defmod gimmeHotWater DOIF
([HotWater:"trigger"])
# Befehl 1
(set Heizung update)
# Befehl 2
(IF ([Heizung:state] =~ "last") ((set Heizung WW-Haupttemperatur 60)(set Heizung WW-einmaliges_Aufladen activate)(set BOSE_7C3866CE97B8 on-for-timer 60)(set BOSE_7C3866CE97B8 volume 25)(set BOSE_7C3866CE97B8 playTrack warmwasser)(set Heizung WW-einmaliges_Aufladen deactivate)(set Heizung WW-Haupttemperatur 50)) ELSE ((set BOSE_7C3866CE97B8 on-for-timer 60)(set BOSE_7C3866CE97B8 volume 25)(set BOSE_7C3866CE97B8 playTrack keineVerbindungHeizung)))
Daher kann nur ein wait der Form sein: wait <Wartezeit für Befehl 1>,<Wartezeit für Befehl 2>
Du kannst mehrere set Befehle im IF so schreiben:
set xxx, sleep 2; set yyy, sleep 2; set zzz.....
oder auf DOIF-Perl Modus schalten, und set_Exec benutzen https://fhem.de/commandref_DE.html#DOIF_set_Exec
Hi & vielen Dank für Deinen Post.
ZitatDein DOIF kann man so strukturieren:
So habe ich es gemacht, oder?
ZitatDaher kann nur ein wait der Form sein: wait <Wartezeit für Befehl 1>,<Wartezeit für Befehl 2>
Wenn ich nun z.B.
wait 0,2,4,6 verwende, welcher Befehl ist der erste?
(set Heizung update) oder
(set Heizung WW-Haupttemperatur 60)?
Wird bei der Verwendung von sleep FHEM nicht blockiert?
Das wäre bei sleep 1800 ungünstig.
Viele Grüße,
Hendrik
Zitat von: twinFHEM am 26 November 2020, 12:01:57
Wird bei der Verwendung von sleep FHEM nicht blockiert?
Das wäre bei sleep 1800 ungünstig.
NICHT, wenn es sich um ein
fhem sleep handelt.
https://fhem.de/commandref_DE.html#sleep
Das wird dann intern als "at" umgesetzt...
Hingegen ein
perl sleep würde blockieren.
Gruß, Joachim
Zitat von: twinFHEM am 26 November 2020, 12:01:57
Hi & vielen Dank für Deinen Post.
So habe ich es gemacht, oder?
Wenn ich nun z.B. wait 0,2,4,6 verwende, welcher Befehl ist der erste? (set Heizung update) oder (set Heizung WW-Haupttemperatur 60)?
Wird bei der Verwendung von sleep FHEM nicht blockiert?
Das wäre bei sleep 1800 ungünstig.
Viele Grüße,
Hendrik
Im Ausführungsteil entspricht der erste Befehl nach der Bedingung auch dem ersten Eintrag im Wait-Attribut usw.
Im DOIF braucht man selten einen Sleep-Befehl, im FHEM-Modus kann man den aber einsetzen, wenn man weiß was man tut.
Danke für euer Feedback!
ZitatIm Ausführungsteil entspricht der erste Befehl nach der Bedingung auch dem ersten Eintrag im Wait-Attribut usw.
In diesem Fall also
(set Heizung update). Erreiche ich dann
(set Heizung WW-Haupttemperatur 60) mit der 2?
Wie sieht das Ganze im ELSE-Zweig aus?
Wird dieser ausgeführt, gibt es mehr waits als Befehle.
sleep würde ich tatsächlich ungern nutzen.
Zitat von: twinFHEM am 26 November 2020, 12:40:28
Danke für euer Feedback!
In diesem Fall also (set Heizung update). Erreiche ich dann (set Heizung WW-Haupttemperatur 60) mit der 2?
sleep würde ich tatsächlich ungern nutzen.
Genau.
Sleep bräuchtest du tatsächlich, wenn du innerhalb einer IF-Anweisung noch mal mehrere Befehle nacheinander verzögern wolltest.
ZitatSleep bräuchtest du tatsächlich, wenn du innerhalb einer IF-Anweisung noch mal mehrere Befehle nacheinander verzögern wolltest.
Darum geht es ja! :)
Dann muss sleep also her.
Ich habe ein wenig ausprobiert:
Zitat
([HotWater:"trigger"]) (set Heizung update)(sleep 4)() (IF ([Heizung:state] =~ "last") ((set Heizung WW-Solltemperatur 60)(set Heizung WW-Haupttemperatur 60)(set Heizung WW-einmaliges_Aufladen activate)(sleep 2)(set BOSE_7C3866CE97B8 on-for-timer 60)(set BOSE_7C3866CE97B8 volume 25, sleep 2)(set BOSE_7C3866CE97B8 playTrack warmwasser, sleep 6)(set Heizung WW-einmaliges_Aufladen deactivate, sleep 2399)(set Heizung WW-Solltemperatur 50, sleep 2400)(set Heizung WW-Haupttemperatur 50, sleep 2400)) ELSE ((set BOSE_7C3866CE97B8 on-for-timer 60)(set BOSE_7C3866CE97B8 volume 25, sleep 2)(set BOSE_7C3866CE97B8 playTrack keineVerbindungHeizung, sleep 6)))
Egal, ob ich sleep nach dem Befehl mit Komma, extra in Klammern mit oder ohne nachfolgendem Befehl schreibe. Ich erhalte immer das Warning im Logfile:
2020.11.26 13:18:51 1: WARNING: sleep without additional commands is deprecated and blocks FHEM
Ich gehe davon aus, dass es kein Standard ist. :)
Naja sowas hier z.B. "set BOSE_7C3866CE97B8 playTrack keineVerbindungHeizung, sleep 6" also NACH dem sleep KEIN "command" mehr ist gemeint!
Stand doch im Link bzgl. sleep und steht ja auch so in der Warning!
Wenn du schon IF / ELSE nimmst, warum dann nicht DOIF mit wait?
Aber dazu kann Damian mehr sagen...
Gruß, Joachim
ZitatNaja sowas hier z.B. "set BOSE_7C3866CE97B8 playTrack keineVerbindungHeizung, sleep 6" also NACH dem sleep KEIN "command" mehr ist gemeint!
Mist! Den Letzten habe ich übersehen... :D
Danke Dir
ZitatWenn du schon IF / ELSE nimmst, warum dann nicht DOIF mit wait?
Würde ich sehr gerne. Aber wegen des meiner Meinung nach zwingenden IF-ELSE-Konstrukts scheint das nicht zu funktionieren.
Zitat von: twinFHEM am 26 November 2020, 13:52:30
Mist! Den Letzten habe ich übersehen... :D
Ich bin mir nicht sicher (nutze kein IF oder DOIF) aber das hier ist doch gleich?
Zitat
(set Heizung WW-Solltemperatur 50, sleep 2400)(set Heizung WW-Haupttemperatur 50, sleep 2400)
Sogar 2x ;)
Aber wie geschrieben, bin nicht sicher wie das mit Klammern ist...
Für mich wäre die Klammer ein "Kommand-Trenner" und somit wären es 2 Kommands mit jeweils 2 Anweisungen (durch Komma getrennt) wo am Ende eben (wieder) ein sleep OHNE weiteres fhem-Kommando wäre...
EDIT: bzw. der letzte eben auf jeden Fall, da ja danach dann schon das ELSE kommt... Also steht auch das sleep auf jeden Fall (für mich) am Ende OHNE eine weitere Ausführung. Ein ELSE ich keine Ausführung sondern eine weitere Bedingung bzw. halt der "Bedingungs-Notausgang" ;)
Aber da muss jemand was schreiben, der IF / DOIF (besser) kennt...
Ich gehe da dann (lieber) gleich nach Perl, da weiß ich was ich "bekomme" ;)
Gruß, Joachim
Es ist immer das Gleiche: ein FHEM-Befehl muss unmittelbar mit Semikolon hinter sleep <sekunden> kommen, siehe Beispiele von amenomade
Zitat von: twinFHEM am 26 November 2020, 12:01:57
So habe ich es gemacht, oder?
Jein. Dein DOIF hat in der Form NUR zwei Befehle, die mit dem wait Attribut verzögert werden können:
1 - (set Heizung update)
2 - (IF ([Heizung:state] =~ "last") ((set Heizung WW-Haupttemperatur 60)(set Heizung WW-einmaliges_Aufladen activate)(set BOSE_7C3866CE97B8 on-for-timer 60)(set BOSE_7C3866CE97B8 volume 25)(set BOSE_7C3866CE97B8 playTrack warmwasser)(set Heizung WW-einmaliges_Aufladen deactivate)(set Heizung WW-Haupttemperatur 50)) ELSE ((set BOSE_7C3866CE97B8 on-for-timer 60)(set BOSE_7C3866CE97B8 volume 25)(set BOSE_7C3866CE97B8 playTrack keineVerbindungHeizung)))
wait 0,2,4,6 hat deswegen keinen Sinn: wofür sind die 3. und 4. Parameter wenn Du nur 2 Befehle hast?
(2 -) ist ein Block (ein "IF" Befehl), und innerhalb dieses Blocks greift das wait Attribut nicht.
Hallo zusammen,
so scheint es nun zu finktionieren:
([HotWater:"trigger"]) (set Heizung update) ( IF ([Heizung:state] =~ "last") (set Heizung WW-Solltemperatur 60, set Heizung WW-Haupttemperatur 60, set Heizung WW-einmaliges_Aufladen activate, set BOSE_7C3866CE97B8 on-for-timer 60, set BOSE_7C3866CE97B8 volume 25, sleep 2, set BOSE_7C3866CE97B8 playTrack warmwasser, sleep 2400, set Heizung WW-einmaliges_Aufladen deactivate, set Heizung WW-Solltemperatur 50, set Heizung WW-Haupttemperatur 50) ELSE (set BOSE_7C3866CE97B8 on-for-timer 60, set BOSE_7C3866CE97B8 volume 25, sleep 2, set BOSE_7C3866CE97B8 playTrack keineVerbindungHeizung))
Nur nochmal interessehalber...
Wäre dies überhaupt mit DOIF umzusetzen?
Besten Dank für eure Mithilfe! :)
Viele Grüße,
Hendrik
Zitat von: twinFHEM am 27 November 2020, 13:09:42
Hallo zusammen,
so scheint es nun zu finktionieren:
([HotWater:"trigger"]) (set Heizung update) ( IF ([Heizung:state] =~ "last") (set Heizung WW-Solltemperatur 60, set Heizung WW-Haupttemperatur 60, set Heizung WW-einmaliges_Aufladen activate, set BOSE_7C3866CE97B8 on-for-timer 60, set BOSE_7C3866CE97B8 volume 25, sleep 2, set BOSE_7C3866CE97B8 playTrack warmwasser, sleep 2400, set Heizung WW-einmaliges_Aufladen deactivate, set Heizung WW-Solltemperatur 50, set Heizung WW-Haupttemperatur 50) ELSE (set BOSE_7C3866CE97B8 on-for-timer 60, set BOSE_7C3866CE97B8 volume 25, sleep 2, set BOSE_7C3866CE97B8 playTrack keineVerbindungHeizung))
Nur nochmal interessehalber...
Wäre dies überhaupt mit DOIF umzusetzen?
Besten Dank für eure Mithilfe! :)
Viele Grüße,
Hendrik
Wenn du z. B. hinter sleep 2 Semikolon statt Komma setzt ja ;)
Hello again,
DOIF lässt mir einfach keine Ruhe, somit möchte ich das Ganze entsprechend umsetzen. Man möchte ja dazu lernen, doch einige Dinge in der Commandref sind mir nicht ganz klar.
Wäre klasse, wenn ihr mir weiterhelfen könnt. Folgender Code:
defmod gimmeHotWater DOIF ([HotWater:"trigger"] and [Heizung:state] =~ /last/) (set Heizung WW-Solltemperatur 60, set Heizung WW-Haupttemperatur 60, set Heizung WW-einmaliges_Aufladen activate, set BOSE_7C3866CE97B8 on-for-timer 30, set BOSE_7C3866CE97B8 volume 25, set BOSE_7C3866CE97B8 playTrack warmwasser, set Heizung WW-einmaliges_Aufladen deactivate, set Heizung WW-Solltemperatur 50, set Heizung WW-Haupttemperatur 50)
DOELSEIF ([HotWater:"trigger"] and [Heizung:state] =~ /error/) (set BOSE_7C3866CE97B8 on-for-timer 30, set BOSE_7C3866CE97B8 volume 25, set BOSE_7C3866CE97B8 playTrack keineVerbindungHeizung, set Heizung update)
DOELSEIF ([+01:00] and [Heizung:WW-Haupttemperatur > 50]) (set Heizung WW-einmaliges_Aufladen deactivate, set Heizung WW-Solltemperatur 50, set Heizung WW-Haupttemperatur 50, set Heizung update)
attr gimmeHotWater do always
attr gimmeHotWater wait 0,0,0,0,0,2,2400,0,0:0,0,2,0:0,0,0,0
Durch do always wird das DOIF immer ausgeführt. Die ersten beiden Bedingungen allerdings nur, wenn "HotWater" getriggert wird. Die dritte und letzte Bedingung sollte doch somit permanent laufen, oder?
Mit dieser möchte ich erreichen, dass nach einer Stunde geprüft wird, ob die WW-Haupttemperatur immer noch über 50 Grad ist und ggf. wieder auf 50 Grad gesetzt wird.
Zudem möchte ich die zweite und dritte Bedingung mehrmals ausführen.
attr gimmeHotWater repeatcmd 0:30:300
Kann ich die 0 für keine Wiederholung verwenden?
Die zweite Bedingung soll maximal 3x wiederholt werden:
attr gimmeHotWater repeatsame 0:3:0
Die 0 in Verbindung mit do always bewirkt allerdings das Gegenteil.
So?
attr gimmeHotWater repeatsame :3:0
Natürlich habe ich schon ausprobiert, lerne dadurch die komplexen Möglichkeiten von DOIF kennen, aber scheinbar verrenne ich mich momentan. :'(
Wiederholungen werden zunichte gemacht, sobald ein anderer Zwei zuschlägt.
hier triggert z. B. Heizung:WW-Haupttemperatur
[Heizung:WW-Haupttemperatur > 50]
Ausserdem macht 0,0,0,0,0,2,2400,0,0
im wait Attribut keinen Sinn und ist wirkungslos, weil
(set ..., set ..., set ..., set... )
nur ein DOIF - Befehl ist, der dann mit 0 Sekunden Verzögerung ausgeführt wird (alles gleichzeitig)
Damit sowas wie dein wait funktionieren kann, muss man eine Befehlssequenz schreiben:
(set ...) (set ...) (set ...)(set ...)
Oder eben, da Du mehrmals 0 hast (heisst, die können gleichzeitig ausgeführt werden:
(5 erste sets die sofort ausgeführt werden sollen) (1 set nach 2 Sekunden)(1 set nach 2400 Sek)(die restiliche 2 sets)
Siehe (wie immer) CommandRef https://fhem.de/commandref_DE.html#DOIF_wait
Das wurde schon hier gesagt: https://forum.fhem.de/index.php/topic,116161.msg1104448.html#msg1104448 ...
Hallo amenomade,
IF nicht gleich DOIF! ::)
Habe ich echt übersehen, obwohl ich nun schon eine ganze Weile das CommandRef durchgehe.
Besten Dank für den Hinweis & die ausführliche Darstellung!
Und ich wundere mich, warum es mit den Repeats nicht klappt...
Dann auf zu den Repeats! :)
Wie wäre es mit
defmod gimmeHotWater DOIF ([HotWater:"trigger"]) (set Heizung update)(set $SELF checkall)
DOELSEIF ([$SELF:cmd] == 1) and ...)
DOELSEIF ([$SELF:cmd] == 1) and ...)
attr gimmeHotWater wait 0,2:...
Braucht man kein IF oder sleep mehr und kommt trotzdem mit einem FHEM-DOIF aus.