Aktion x mal hinterheinander ausführen alle zwei stunden mit x minuten pause

Begonnen von awex102, 12 September 2020, 19:53:21

Vorheriges Thema - Nächstes Thema

awex102

Hallo, hat jemand einen Tip wie ich folgende Steuerung elegant umsetzen kann:

Führe on-for-timer zwischen 08 und 20 Uhr alle zwei Stunden 3 mal hintereinander mit jeweils 5 Minuten Pause aus.

Danke und Gruß

xerion

Ich würde mich  freuen, wenn du meinen Einladungscode für Tibber, der Stromanbieter, der dir hilft, deinen Stromverbrauch zu verstehen und zu reduzieren, nutzt: https://invite.tibber.com/5fc08jbs. So bekommen wir beide 50 Euro und 100 % Ökostrom / https://geld-fuer-eauto.de/ref/334561880

awex102


xerion

Schaue dir mail in der DOIF Commandref die Atribute repeatcmd, wait und repeatsame an. Das sollte dort mit umsetzbar sein. In der commandref gibt es auch Beispiele die deiner Anforderung sehr nahe kommen.
Ich würde mich  freuen, wenn du meinen Einladungscode für Tibber, der Stromanbieter, der dir hilft, deinen Stromverbrauch zu verstehen und zu reduzieren, nutzt: https://invite.tibber.com/5fc08jbs. So bekommen wir beide 50 Euro und 100 % Ökostrom / https://geld-fuer-eauto.de/ref/334561880

Damian

Zitat von: awex102 am 12 September 2020, 20:10:56
Kenne mich noch überhaupt nicht mit DOIF aus, hast du einen Tip?


z. B.

defmod di_intervall DOIF ([08:00-20:00,+[2]:00])(set pump on-for-timer 60)
attr di_intervall repeatcmd 300
attr di_intervall repeatsame 3
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

awex102

Klasse, danke... Einwandfrei und was gelernt. Gesteuert wird in der Tat ein Magnetventil, das dann einen 6 fach manuellen Gardena Wasserverteiler steuert.

Damian

Zitat von: awex102 am 13 September 2020, 10:29:06
Klasse, danke... Einwandfrei und was gelernt. Gesteuert wird in der Tat ein Magnetventil, das dann einen 6 fach manuellen Gardena Wasserverteiler steuert.

Du musst wohl noch das Attribut do always setzen, damit es nicht nur einmal, sondern auch nach zwei Stunden wieder funktioniert.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

awex102

Hatte ich gemacht, danke nochmal für den Hinweis falls jemand ähnliches vorhat... DOIF ist echt cool

rudolfkoenig

Die "old-school" Variante:
define a1 at +*02:00 define a2 at +*{3}00:05 set pump on-for-timer 60
attr a1 disabledForIntervals 00:00-07:00 21:00-23:59
attr a1 alignTime 00:00

Damian

Und hier mal eine "programmierte" Lösung in (ereignisgesteuertem) Perl:

defmod di_intervall2 DOIF subs {\
$_count=0;;\
sub pump\
{\
  fhem_set("pump on-for-timer 60");;\
  if ($_count++<3) {\
    set_Exec("timer",300,'pump()');;\
  } else {\
    $_count=0;;\
  }\
}\
}\
\
{[08:00-20:00,+[2]:00];; pump()}

Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Damian

Weil mir alle Lösungen zu umständlich erschienen, habe ich kurzerhand eine etwas einfachere Möglichkeit für bedingte Wiederholungen programmiert, siehe: https://forum.fhem.de/index.php/topic,114252.0.html

Hier konkret z. B.:

DOIF {[08:00-20:00,+[2]:00];set_Exec("timer",300,'fhem_set("pump on-for-timer 60")',undef,'$count<4')}
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

awex102

Eine Frage noch: Wie stelle ich es an, dass z. B. die erste Ausführung kürzer oder länger läuft als die anderen?

Danke!

Damian

Zitat von: awex102 am 16 September 2020, 13:37:25
Eine Frage noch: Wie stelle ich es an, dass z. B. die erste Ausführung kürzer oder länger läuft als die anderen?

Danke!

Gute Frage, dafür habe ich mir z. B. für die set_Exec-Funktion auch etwas überlegt. Man wird die Zeitdauer abhängig vom Durchlauf bestimmen können:

DOIF {[08:00-20:00,+[2]:00];set_Exec("timer",'$count==0?0:300','fhem_set("pump on-for-timer 60")','$count<4')}

Würde bedeuten: Die erste Ausführung sofort, die folgenden mit 300 Sekunden:

oder

DOIF {[08:00-20:00,+[2]:00];set_Exec("timer",'$count*120','fhem_set("pump on-for-timer 60")','$count<4')}

Die erste sofort, die zweite nach 120 Sekunden, die dritte nach 240 Sekunden usw.

Man kann für die Zeit beliebige Perlfunktionen nutzen, damit sind für die Bestimmung der Verzögerung abhängig vom Durchlauf keine Grenzen gesetzt, vom logarithmischen bis zum exponentiellem Anstieg oder Fall ist alles drin.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

awex102

Auch super!

Glaube ich hatte mich falsch ausgedrückt:

Mein eigentliches Ziel ist es, pump on-for-timer 60 separat pro Durchlauf der Wiederholungen setzen können, also z.B. beim ersten Durchlauf 60, beim zweiten Durchlauf 80 und dritten 100 Sekunden on-for-timer.

Damian

Zitat von: awex102 am 16 September 2020, 14:53:01
Auch super!

Glaube ich hatte mich falsch ausgedrückt:

Mein eigentliches Ziel ist es, pump on-for-timer 60 separat pro Durchlauf der Wiederholungen setzen können, also z.B. beim ersten Durchlauf 60, beim zweiten Durchlauf 80 und dritten 100 Sekunden on-for-timer.

Im Prinzip genauso:

DOIF {[08:00-20:00,+[2]:00];set_Exec("timer",300,'fhem_set("pump on-for-timer ".60+$count*20)','$count<4')}

Man könnte auch ein Array  mit beliebigen Zahlen drin definieren.

Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

rudolfkoenig

Die old-school Variante:
define a1 at +*02:00 define a2 at +*{3}00:05 set pump on-for-timer {(Each("pump","60,80,100"))}
attr a1 disabledForIntervals 00:00-07:00 21:00-23:59
attr a1 alignTime 00:00

Damian

Zitat von: rudolfkoenig am 16 September 2020, 15:32:35
Die old-school Variante:
define a1 at +*02:00 define a2 at +*{3}00:05 set pump on-for-timer {(Each("pump","60,80,100"))}
attr a1 disabledForIntervals 00:00-07:00 21:00-23:59
attr a1 alignTime 00:00


@Rudi
Vielleicht solltest du die Each-Funktion in die Commandref aufnehmen, sonst kennen die Nerds sie nur aus solchen Posts :)

@awex102

und so würde es als Perl-Version mit einem Array mit set_Exec aussehen:

defmod intervall DOIF {[08:00-20:00,+[2]:00];;@{$_a}=(60,80,100);;set_Exec("timer",300,'fhem_set"pump on-for-timer  ".$_a[$count]','$count <4')}

dabei muss man wissen, dass $_a  auf $hash->{var}{a} abgebildet wird und damit als eine Instanzvariable innerhalb des Devices zu jedem Zeitpunkt verfügbar ist.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Damian

Zitat von: Damian am 16 September 2020, 14:57:50
Im Prinzip genauso:

DOIF {[08:00-20:00,+[2]:00];set_Exec("timer",300,'fhem_set("pump on-for-timer ".60+$count*20)','$count<4')}

Man könnte auch ein Array  mit beliebigen Zahlen drin definieren.

Ab heute kannst du es auch ausprobieren, siehe: https://forum.fhem.de/index.php/topic,114252.msg1085850.html#msg1085850

PS. Das Beispiel habe ich sogar in die Commandref übernommen
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

awex102

Klasse, vielen Dank!

Am Wochenende hat es mich gepackt und ich habe auf einzelne Ventile umgebaut. Diese werden über ein Relais gesteuert.
Relais etc funktioniert und stehen jeweils als einzelne devices zur Verfügung.

Hat jemand einen Tip, wie ich den Code so umbauen kann, dass  einzelne Devices (Relais) mit vorher bestimmen Laufzeiten nacheinander in der Schleife angesprochen werden können? Optimal mit etwas Zeit zwischen den Vorgängen.


Damian

Zitat von: awex102 am 29 September 2020, 19:22:04
Klasse, vielen Dank!

Am Wochenende hat es mich gepackt und ich habe auf einzelne Ventile umgebaut. Diese werden über ein Relais gesteuert.
Relais etc funktioniert und stehen jeweils als einzelne devices zur Verfügung.

Hat jemand einen Tip, wie ich den Code so umbauen kann, dass  einzelne Devices (Relais) mit vorher bestimmen Laufzeiten nacheinander in der Schleife angesprochen werden können? Optimal mit etwas Zeit zwischen den Vorgängen.

Welche Version hast du jetzt genommen?
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

awex102

Beide ausprobiert, aber die set_Exec finde ich noch etwas smarter

Damian

Zitat von: awex102 am 29 September 2020, 20:52:10
Beide ausprobiert, aber die set_Exec finde ich noch etwas smarter

Du könntest zwei set_Exec-Aufrufe kombinieren. Den einen für das sequentielle Schalten der einzelnen Ventile packst du in eine Funktion und rufst diese dann im ursprünglichen set_Exec auf, z. B.:

DOIF {
  subs {
    sub ventile {set_Exec (....) }
  }
  {[08:00-20:00,+[2]:00];set_Exec("timer",300,'ventile()','$count<4')}
}

Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

awex102

Woher weiß dann sub ventile() welches der 4 devices (mit unterschiedlichen Namen) angesprochen werden soll?
Wenn ich es richtig verstehe, ruft die Hauptfunktion dann 4 mal die Unterfunktion auf, kann ich da einen Parameter mitgeben?
Wenn ich alle 4 Devices nacheinander in der Unterfunktion aufführe bzw. 4 set_Exec in der Unterfunktion erstellen würde, würden diese doch bei jedem Durchlauf komplett durchlaufen werden, oder?


Damian

Zitat von: awex102 am 29 September 2020, 21:27:37
Woher weiß dann sub ventile() welches der 4 devices (mit unterschiedlichen Namen) angesprochen werden soll?
Wenn ich es richtig verstehe, ruft die Hauptfunktion dann 4 mal die Unterfunktion auf, kann ich da einen Parameter mitgeben?
Wenn ich alle 4 Devices nacheinander in der Unterfunktion aufführe bzw. 4 set_Exec in der Unterfunktion erstellen würde, würden diese doch bei jedem Durchlauf komplett durchlaufen werden, oder?

naja, wie man Dinge in einem Array ablegt und darauf in set_Exec zugreift, habe ich bereits gepostet:

hier dann z. B.


subs {
    @{$_ventil}=("ventil1","ventil2","ventil3","ventil4");
    sub ventile {set_Exec("timer_ventile",60,'fhem_set("$_ventil[$count] on-for-timer 60")','$count <4')}
  }


Die Aktion sollte natürlich beendet sein 4*60, bevor die Funktion ventile ein erneutes Mal durch die andere set_Exec-Funkton aufgerufen wird.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

awex102

Nochmal danke, so langsam blicke ich durch ;-)

Jetzt  habe ich noch den Fall, dass ich die Bewässerung nicht x mal am Tag starten möchte, sondern nur einmal.

Dazu habe ich mir folgendes gebaut:

{if ([08:05] and [Beregnungsautomatik:state] eq "An"){
@{$_ventil}=("HM_6F1C24_Sw_01","HM_6F1C24_Sw_02","HM_6F1C24_Sw_03");
set_Exec("timer",70,'fhem_set("$_ventil[$count] on-for-timer ".ReadingsVal("Dauer_Kreis".$count + 1,"state")*10)','$count < 3')}}

Ziel ist es, für die einzelnen Ventile noch eine Laufzeit aus einem dummy zu holen. Daher habe ich versucht, den on-for-timer Wert aus dem Dummy zu lesen (Dauer_Kreis1 bis Dauer_Kreis3).
Das zusammensetzen mit ReadingsVal und $count  funktioniert allerdings nicht. Vermutlich nur ein Anfängerfehler, aber wie setze ich das "richtig" zusammen, den aktuell kommt 0 zurück?

Und noch eine Frage: Im Beispiel soll die Bewässerung um 08:05 starten. Der Timer startet auch, allerdings wird das eigentliche anschalten der Bewässerung erst im "zweiten" Durchlauf um 08:06:10 (08:05 plus die 70 Sekunden wait) gestartet. Ist das by design so gedacht?

Danke!

Damian

Versuche mal mit:

ReadingsVal("Dauer_Kreis".($count + 1),"state")

Solche Dinge würde ich allerdings nicht in verschiedenen Devices verstreut speichern, sondern direkt in Readings des DOIF selbst oder sogar in einem Array.

Ob er auch beim ersten Durchlauf verzögert anfängt, hängt von der Definition ab. Willst du beim ersten Durchlauf keine Verzögerung haben, dann kannst du das selbstverständlich definieren:

{[08:00-20:00,+[2]:00];set_Exec("timer",'$count ==0 ? 0 : 300','ventile()','$count<4')}

Da alle Parameter, wie in der Commandref steht, per eval ausgewertet werden, kannst du dich in Perl beliebig austoben ;)




Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF