FHEM Forum

FHEM => Automatisierung => Thema gestartet von: dan1180 am 07 November 2014, 22:46:11

Titel: Warum funktioniert "else" nicht?
Beitrag von: dan1180 am 07 November 2014, 22:46:11
Hallo zusammen,

jetzt, wo die Tage wieder kürzer und die Temperaturen tiefer werden, geht es wieder an die Verfeinerung und den Ausbau meiner Hausautomation. Ich habe mich mal an die Programmierung von ATs und NOTIFYs herangewagt und bin sogleich an meine Grenzen gestoßen.

Mein Vorhaben:
Über ein AT soll regelmäßig geprüft werden, ob eine meiner Fußbodenheizungen (FBH_XXX) warmes Wasser wollen. Wenn dies der Fall ist und im Kessel genug heißes Wasser bereit steht, soll die Pumpe einschalten. Wenn alle Fußbodenheizungen aus sind, ODER wenn das Wasser im Kessel aus ist, soll die Pumpe wieder aus gehen. Über zwei ATs habe ich es mittlerweile hinbekommen...

Pumpe an:
+*00:05:00 { if (((Value("FBH_Wohnzimmer") eq "on") || (Value("FBH_Esszimmer") eq "on") || (Value("FBH_Kueche") eq "on") || (Value("FBH_Kinderzimmer") eq "on") || (Value("FBH_Bad") eq "on") || (Value("FBH_Schlafzimmer") eq "on")) && (Value("C_SSP_UM") > 48)) { fhem("set FBH_Pumpe on") } }

Pumpe aus:
+*00:05:00 { if (((Value("FBH_Wohnzimmer") eq "off") && (Value("FBH_Esszimmer") eq "off") && (Value("FBH_Kueche") eq "off") && (Value("FBH_Kinderzimmer") eq "off") && (Value("FBH_Bad") eq "off") && (Value("FBH_Schlafzimmer") eq "off")) || (Value("C_SSP_UM") < 40)) { fhem("set FBH_Pumpe off") } }

Warum aber funktioniert es nicht, was ich in einem AT mit einer "else"-Verbindung gemacht habe?
+*00:05:00 {if (((Value("FBH_Bad") eq "on") || (Value("FBH_Kinderzimmer") eq "on") || (Value("FBH_Schlafzimmer") eq "on") || (Value("FBH_Flur") eq "on") || (Value("FBH_Kueche") eq "on") || (Value("FBH_Esszimmer") eq "on") || (Value("FBH_Wohnzimmer") eq "on")) && (Value("C_SSP_UM") > 48)) {fhem("set FBH_Pumpe on")} else {if (((Value("FBH_Bad") eq "off") && (Value("FBH_Kinderzimmer") eq "off") && (Value("FBH_Schlafzimmer") eq "off") && (Value("FBH_Flur") eq "off") && (Value("FBH_Kueche") eq "off") && (Value("FBH_Esszimmer") eq "off") && (Value("FBH_Wohnzimmer") eq "off")) || (Value("C_SSP_UM") < 40)) {fhem("set FBH_Pumpe off")}}}

Und zum Schluss noch...kann ich Code, der Übersichtlichkeit wegen, auch mit <Enter> trennen? Hier ein kleines Beispiel was ich meine:

+*00:05:00
{
if (
((Value("FBH_Wohnzimmer") eq "on") ||
(Value("FBH_Esszimmer") eq "on") ||
(Value("FBH_Kueche") eq "on") ||
(Value("FBH_Kinderzimmer") eq "on") ||
(Value("FBH_Bad") eq "on") ||
(Value("FBH_Schlafzimmer") eq "on")) &&
(Value("C_SSP_UM") > 48)
)
{ fhem("set FBH_Pumpe on") }
}



Vielen Dank für eure Hilfe!
Titel: Antw:Warum funktioniert "else" nicht?
Beitrag von: fiedel am 08 November 2014, 09:15:54
Hi,

du könntest versuchen "elsif" statt "else {if..." zu verwenden. Für die Übersichtlichkeit: Das mit den Umbrüchen weiß ich nicht. Ich würde versuchen, ob ich die Ventile (da du ja alle oderverknüpft abfragst) per Wildcard oder Regex zusammenfassen kann. Z.B. so:
Value("FBH_*") Da ist ggf. etwas experimentieren gefragt, ggf. mit einem online Regexg (http://www.regexr.com)enerator (http://regex101.com/) (Achtung: 2 Links in einem Wort.  :) ).

Gruß

Frank
Titel: Antw:Warum funktioniert "else" nicht?
Beitrag von: betateilchen am 08 November 2014, 10:20:52
Ich würde das Ganze in eine structure packen, in der alle abgefragten FBH* enthalten sind. Wenn alle FBH "off" sind, ist auch die structure "off" , in allen anderen Fällen ist sie "undefined"

Das erleichtert die Auswertung erheblich. Generell würde ich die Abwicklung aber auch in eine eigene Funktion in der 99_myUtils.pm auslagern.

Du kannst den Code grundsätzlich auch mehrzeilig schreiben, aber bitte nur direkt im DEF der Detailansicht des at. Bitte NICHT manuell in der fhem.cfg editieren!

Titel: Antw:Warum funktioniert "else" nicht?
Beitrag von: dan1180 am 08 November 2014, 11:09:22
@Frank:
Die Zusammenfassung mit FBH_* hat leider nicht funktioniert. Ich hab zum Testen mein AT auf nur eine Abfrage (FBH_X=on?) reduziert, was funktioniert hat, und diese dann mit FBH_* ersetzt. Hat nichts mehr gemacht. Mit der Regexr-Geschichte komm ich nicht wirklich weiter. Ich verstehe zwar, was in diesem Generator passiert, ich komm aber nicht drauf, wie ich das in mein AT einbinden kann.

Ach ja... der "enerator"-Link funktioniert nicht  ;)

@Betateilchen:
Seit ich mich - ist nun auch schon über ein Jahr her  ;) - etwas mehr mit der Möglichkeit der Befehlseingabe direkt in FHEM beschäftigt habe, mach ich in der cfg eigentlich gar nichts mehr direkt (trotzdem Danke für den Hinweis).
Wie aus meiner Antwort an Frank ersichtlich bin ich nicht so der Crack in Perl-Programmierung. Daher trau ich mich auch nicht wirklich an die .pm ran.

Das mit "structure" hab ich mir mal genauer angeschaut und konnte damit meinen Code stark vereinfachen. Sieht nun so aus:

Pumpe an:
+*00:05:00 {if ((Value("FBH_All") eq "undefined") && (Value("C_SSP_UM") > 48)) {fhem("set FBH_Pumpe on")}}

Pumpe aus:
+*00:10:00 {if ((Value("FBH_All") eq "off") || (Value("C_SSP_UM") < 40)) {fhem("set FBH_Pumpe off")}}

Zwei Fragen hab ich aber noch:
Titel: Antw:Warum funktioniert "else" nicht?
Beitrag von: simonberry am 08 November 2014, 14:14:15
Hallo,
das mit dem else sollte eigentlich schon gehen, wobei "elsif" wie schon gesagt in dem Fall noch besser wäre.
Hast Du Fehlermeldungen, oder was geht dabei nicht?
Spendiere dem fhem(...) Kommando evtl noch einen Strichpunkt am Ende

Grüße

Simonberry
Titel: Antw:Warum funktioniert "else" nicht?
Beitrag von: dan1180 am 08 November 2014, 23:33:16
Hallo,

also im Logfile finde ich nun folgene Meldungen:
ZitatPERL WARNING: elseif should be elsif at (eval 27032) line 1.
und
ZitatPERL WARNING: Found = in conditional, should be == at (eval 27032) line 1.

Da ich mit meiner Fußbodenheizung und der structure-Lösung ganz zufrieden bin versuche ich nun meinen einzigen zu steuernden Heizkörper mit der entsprechenden Pumpe anzufreunden. Einschalten funktioniert, aus nicht. Hier der Code:
+*00:05:00 {if ((ReadingsVal("HKT_BU_Clima","ValvePosition",0) > 0) && (Value("C_SSP_UM") > 48)) {fhem("set HKK_Pumpe on")}} {elseif ((ReadingsVal("HKT_BU_Clima","ValvePosition",0) = 0) || (Value("C_SSP_UM") < 44)) {fhem("set HKK_Pumpe off")}}
HKT_BU ist mein Heizkörper, SSP_UM die Temperatur im Kessel an der Abnahmehöhe für den Heizkörper. HKK_Pumpe erklärt sich von selbst.

Ich hab doch da bestimmt irgendwo einen Klammer-Fehler {()} oder? Find ihn einfach nicht...Vielen Dank!
Titel: Antw:Warum funktioniert "else" nicht?
Beitrag von: gero am 08 November 2014, 23:41:55
Die Fehlermedlungen sagen doch schon einiges. Und deine Vermutung mit den Klammern ist auch richtig ;)
Probier mal
+*00:05:00 {if ((ReadingsVal("HKT_BU_Clima","ValvePosition",0) > 0) && (Value("C_SSP_UM") > 48)) {fhem("set HKK_Pumpe on")} elsif ((ReadingsVal("HKT_BU_Clima","ValvePosition",0) == 0) || (Value("C_SSP_UM") < 44)) {fhem("set HKK_Pumpe off")}}
aus. (ungetestet)
Titel: Antw:Warum funktioniert "else" nicht?
Beitrag von: dan1180 am 08 November 2014, 23:54:24
Hallo Gero,

vielen Dank es funktioniert. Ich könnte schwören, dass ich diese Variante auch getestet habe   ;D

Auch vielen Dank an alle Anderen!

Gruß
Daniel