FHEM Forum

FHEM => Automatisierung => DOIF => Thema gestartet von: Gunther am 18 Juni 2020, 23:23:02

Titel: wait in Abhängigkeit von Dummy
Beitrag von: Gunther am 18 Juni 2020, 23:23:02
Bei meiner Gartenberegnung möchte ich gerne in Abhängigkeit des Dummys anzahl_ventile_parallel (1,2,3 oder 4 Beregnungskreise) den Wait-Timer "verschieben", so dass immer nur x Kreisläufe gleichzeitig beregnen (im Code unten mit dummy_ventil_01/2/3/4 dargestellt).

Da ich kein Programmierer bin, war meine Idee ein DOIF mit einem variablen Wait-Timer zu nutzen.
Ich habe gefunden, dass das mittlerweile geht. Leider bekomme ich das nicht hin.

Hier mein DOIF:
defmod doif_au_ga_bewaesserung DOIF ([bewaesserung_programm:"^Rasen$"]) \
(set dummy_ventil_01 on-for-timer {([ventil_01_dauer]*60)})\
(set dummy_ventil_02 on-for-timer {([ventil_02_dauer]*60)})\
(set dummy_ventil_03 on-for-timer {([ventil_03_dauer]*60)})\
(set dummy_ventil_04 on-for-timer {([ventil_04_dauer]*60)}) \
DOELSEIF ([bewaesserung_programm:"^aus$"]) \
(set dummy_ventil_01 off)\
(set dummy_ventil_02 off)\
(set dummy_ventil_03 off)\
(set dummy_ventil_04 off)


ventil_01_dauer entspricht der Beregnungszeit in Minuten.

Jetzt stehe ich auf dem Schlauch, wie ich es hinbekomme, dass z. B. bei
anzahl_ventile_parallel = 2
ein
attr doif_au_ga_bewaesserung wait 0,0,{([ventil_02_dauer]*60)}) oder {([ventil_01_dauer]*60)} (je nachdem was länger dauert),0:0,0,0,0
gesetzt wird

Bei
anzahl_ventile_parallel = 3
ein
attr doif_au_ga_bewaesserung wait 0,0,0,{([ventil_02_dauer]*60)}) oder {([ventil_01_dauer]*60)} (je nachdem was länger dauert):0,0,0,0
also 3 Ventile zusammen und solange waren, bis das längste Ventil fertig ist.

Toll wäre natürlich folgende Logik:

Freue mich über Hilfe!
Titel: Antw:wait in Abhängigkeit von Dummy
Beitrag von: amenomade am 19 Juni 2020, 01:43:09
Du kannst im wait beliebig mit Perl spielen
attr doif_au_ga_bewaesserung wait 0,0,{if ([anzahl_ventile_parallel] == 2){max([ventil_02_dauer]*60, [ventil_01_dauer]*60)} else {0}},{andere Kalkulation}

Titel: Antw:wait in Abhängigkeit von Dummy
Beitrag von: Gunther am 21 Juni 2020, 22:05:40
Danke! Dein Beispiel funktioniert.

Mein erster Erweiterungsversuch leider nicht:
0,{if ([anzahl_ventile_parallel] == 1){max([ventil_02_dauer]*60)} else {if ([anzahl_ventile_parallel] == 2){min([ventil_02_dauer]*60, [ventil_01_dauer]*60)} else {0}}},0,0:0,0,0,0

Ich möchte bei
anzahl_ventile_parallel = 2
die kürzere Zeit (min?) von
ventil_01_dauer oder ventil_02_dauer
nehmen.
Leider nimmt die wait-Anweisung immer die längere Zeit, egal bei welchem Ventil ich sie eintrage.
Ist "min" die falsche Anweisung oder habe ich einen Denkfehler oder beides?  ::)
Titel: Antw:wait in Abhängigkeit von Dummy
Beitrag von: amenomade am 22 Juni 2020, 00:03:00
Empfehlung: nimm das ganze in einem vernünftigen Editor, und mach dazu ein paar Zeilenumbrüche und  Tabs, so siehts Du besser. Danach kann man die wieder entfernen

So sieht dein Ding im Moment aus:
{
  if ([anzahl_ventile_parallel] == 1){
    max([ventil_02_dauer]*60)
  } else {
    if ([anzahl_ventile_parallel] == 2){
      min([ventil_02_dauer]*60, [ventil_01_dauer]*60)
    } else {0}
  }
}

Du hast ein "max" mit nur einem Wert.
Danach wären ein paar Grundlagen zu Perl nicht schlecht, z.B. die Benutzung von elsif https://www.perltutorial.org/perl-if/
Aber gut, mit verschachtelte if sollte es auch gehen

Wenn Du ein Zweifel hast, was geht oder nicht geht (z.B. min / max) dann probiere es einfach in der Kommandozeile von Fhem:
{ min(1, 2) }


Titel: Antw:wait in Abhängigkeit von Dummy
Beitrag von: Gunther am 22 Juni 2020, 21:38:55
Danke für Deine super Unterstützung.

Perl-if habe ich mir angeschaut.

Es scheitert leider immer noch.

Ich habe mal versucht zu testen. Mit numerischen Werten klappt das.
Wenn ich z. B.
{max(1,2)}
durch
{max([ventil_01_dauer],2)}
ersetze bekomme ich folgende Fehlermeldung:
Bareword "ventil_01_dauer" not allowed while "strict subs" in use at (eval 24926727) line 1.

Mein wait sieht testweise so aus:
0,{
  if ([anzahl_ventile_parallel] == 1){
  min( [ventil_01_dauer], [ventil_02_dauer] )
  }else {0}
  },0,0:0,0,0,0


Wenn ich jetzt mein DOIF starte und die Ventilzeiten wie folgt definiert sind:
ventil_01_dauer = 10
ventil_02_dauer = 5

nimmt das wait 10 Sekunden

Wenn ich jetzt mein DOIF starte und die Ventilzeiten wie folgt definiert sind:
ventil_01_dauer = 5
ventil_02_dauer = 10

nimmt das wait ebenfalls 10 Sekunden

So als wenn "min" wie "max" funktioniert.
Ich stehe auf dem Schlauch...
Titel: Antw:wait in Abhängigkeit von Dummy
Beitrag von: amenomade am 22 Juni 2020, 21:50:02
Ja, die Syntax mit eckigen Klammern [ventil_01_dauer] ist nur im DOIF und set-magics Kontext nutzbar.
In der Kommandozeile musst Du mit Value() oder ReadingsVal() arbeiten.

Im wait Attribut eines DOIFs... weiss ich nicht genau. Vielleicht muss man auch dort mit den Funktionen rechnen.
Titel: Antw:wait in Abhängigkeit von Dummy
Beitrag von: Gunther am 22 Juni 2020, 22:51:17
Danke. Wenn ich
{ min(Value("ventil_01_dauer"), Value("ventil_02_dauer") ) }
in der Befehlszeile angebe wird immer der größere Wert genommen.
Ich verstehe es nicht. Setze ich die Klammern falsch?
Titel: Antw:wait in Abhängigkeit von Dummy
Beitrag von: amenomade am 22 Juni 2020, 22:54:41
Und
{ min(Value("ventil_01_dauer")+0, Value("ventil_02_dauer")+0 ) }?
Titel: Antw:wait in Abhängigkeit von Dummy
Beitrag von: Damian am 22 Juni 2020, 23:00:04
Zitat von: Gunther am 22 Juni 2020, 22:51:17
Danke. Wenn ich
{ min(Value("ventil_01_dauer"), Value("ventil_02_dauer") ) }
in der Befehlszeile angebe wird immer der größere Wert genommen.
Ich verstehe es nicht. Setze ich die Klammern falsch?

dann nimm statt min minNum, min vergleicht lexikografisch
Titel: Antw:wait in Abhängigkeit von Dummy
Beitrag von: Gunther am 22 Juni 2020, 23:01:53
auch nicht.

Wenn beide 1stellig oder 2-stellig sind geht es!

min scheint immer die erste Stelle zu nehmen:
4 und 56 --> 4
7 und 56 --> 56
Titel: Antw:wait in Abhängigkeit von Dummy
Beitrag von: Gunther am 22 Juni 2020, 23:02:45
Zitat von: Damian am 22 Juni 2020, 23:00:04
dann nimm statt min minNum, min vergleicht lexikografisch

Das geht! Danke!
Titel: Antw:wait in Abhängigkeit von Dummy
Beitrag von: Gunther am 22 Juni 2020, 23:25:47
Hmm, leider wird bei folgendem Code im wait keine Verzögerung verwenden:

Hier mal mein Versuch zu Formatieren:
0,
{
if ([anzahl_ventile_parallel] == 1){
Value("ventil_01_dauer")*60/60
} elseif ([anzahl_ventile_parallel] == 2){
minNum(Value("ventil_01_dauer")*60/60, Value("ventil_02_dauer")*60/60)
} else {
0
  }
}
,0,0:0,0,0,0


Unformatiert sieht es so aus:
0,{if ([anzahl_ventile_parallel] == 1){Value("ventil_01_dauer")*60/60} elseif ([anzahl_ventile_parallel] == 2){minNum(Value("ventil_01_dauer")*60/60, Value("ventil_02_dauer")*60/60)} else {0}},0,0:0,0,0,0

getestet mit anzahl_ventile_parallel = 1 und 2
ventil_01_dauer und ventil_02_dauer gesetzt

Freue mich nochmal über Eure fachkundige Hilfe
Titel: Antw:wait in Abhängigkeit von Dummy
Beitrag von: Gunther am 24 Juni 2020, 22:47:31
auch wenn ich es nicht so umsetzen werde, hier für die Nachwelt der funktionierende Code für das wait-Attribut:

0,{ if (Value("anzahl_ventile_parallel") == 1){ (Value("ventil_01_dauer")*60 ) } elsif (Value("anzahl_ventile_parallel") == 2){ minNum(Value("ventil_01_dauer")*60, Value("ventil_02_dauer")*60 ) } else {0} },0,0:0,0,0,0
Titel: Antw:wait in Abhängigkeit von Dummy
Beitrag von: Damian am 24 Juni 2020, 22:54:26
Nur zur Info: das kannst du etwas kürzer mit dem ternären Perl-Operator ? schreiben: https://de.wikibooks.org/wiki/Perl-Programmierung:_Operatoren
Titel: Antw:wait in Abhängigkeit von Dummy
Beitrag von: Per am 25 Februar 2021, 09:46:36
Eine Kleinigkeit: da die *60 immer sind und am Verhältnis nichts ändern, sollte man diese erst zum Schluss einfügen, das spart Rechnerlast.

Und beim Fehlversuch: *60/60 = 1...