wait in Abhängigkeit von Dummy

Begonnen von Gunther, 18 Juni 2020, 23:23:02

Vorheriges Thema - Nächstes Thema

Gunther

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:

  • Öffne so viele Ventile, wie im Dummy anzahl_ventile_parallel angegeben
  • Wenn das erste Ventil fertig ist, öffne das nächste

Freue mich über Hilfe!
FHEM@Proxmox@Nuc: TabletUI als User-Interface (4 Wandtablets) / IOs per ser2net gekapselt
Homematic: Heizung, Fenster, Bewegung | Jeelink: Temperatur | Z-Wave: Bewegung, Temperatur | FS20: Temperatur, Fenster | Viessmann-Heizung eingebunden

amenomade

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}

Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

Gunther

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?  ::)
FHEM@Proxmox@Nuc: TabletUI als User-Interface (4 Wandtablets) / IOs per ser2net gekapselt
Homematic: Heizung, Fenster, Bewegung | Jeelink: Temperatur | Z-Wave: Bewegung, Temperatur | FS20: Temperatur, Fenster | Viessmann-Heizung eingebunden

amenomade

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) }


Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

Gunther

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...
FHEM@Proxmox@Nuc: TabletUI als User-Interface (4 Wandtablets) / IOs per ser2net gekapselt
Homematic: Heizung, Fenster, Bewegung | Jeelink: Temperatur | Z-Wave: Bewegung, Temperatur | FS20: Temperatur, Fenster | Viessmann-Heizung eingebunden

amenomade

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.
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

Gunther

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?
FHEM@Proxmox@Nuc: TabletUI als User-Interface (4 Wandtablets) / IOs per ser2net gekapselt
Homematic: Heizung, Fenster, Bewegung | Jeelink: Temperatur | Z-Wave: Bewegung, Temperatur | FS20: Temperatur, Fenster | Viessmann-Heizung eingebunden

amenomade

Und
{ min(Value("ventil_01_dauer")+0, Value("ventil_02_dauer")+0 ) }?
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

Damian

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
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Gunther

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
FHEM@Proxmox@Nuc: TabletUI als User-Interface (4 Wandtablets) / IOs per ser2net gekapselt
Homematic: Heizung, Fenster, Bewegung | Jeelink: Temperatur | Z-Wave: Bewegung, Temperatur | FS20: Temperatur, Fenster | Viessmann-Heizung eingebunden

Gunther

Zitat von: Damian am 22 Juni 2020, 23:00:04
dann nimm statt min minNum, min vergleicht lexikografisch

Das geht! Danke!
FHEM@Proxmox@Nuc: TabletUI als User-Interface (4 Wandtablets) / IOs per ser2net gekapselt
Homematic: Heizung, Fenster, Bewegung | Jeelink: Temperatur | Z-Wave: Bewegung, Temperatur | FS20: Temperatur, Fenster | Viessmann-Heizung eingebunden

Gunther

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
FHEM@Proxmox@Nuc: TabletUI als User-Interface (4 Wandtablets) / IOs per ser2net gekapselt
Homematic: Heizung, Fenster, Bewegung | Jeelink: Temperatur | Z-Wave: Bewegung, Temperatur | FS20: Temperatur, Fenster | Viessmann-Heizung eingebunden

Gunther

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
FHEM@Proxmox@Nuc: TabletUI als User-Interface (4 Wandtablets) / IOs per ser2net gekapselt
Homematic: Heizung, Fenster, Bewegung | Jeelink: Temperatur | Z-Wave: Bewegung, Temperatur | FS20: Temperatur, Fenster | Viessmann-Heizung eingebunden

Damian

#13
Nur zur Info: das kannst du etwas kürzer mit dem ternären Perl-Operator ? schreiben: https://de.wikibooks.org/wiki/Perl-Programmierung:_Operatoren
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Per

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...