Hallo,
Einfache Aufgabe: Unterschreitet die Raumtemperatur einen Wert von 15, dann öffne Heizungsventil.
Den Wert liefert ein HMS100TF.
Der Notify sieht so aus:
define low_level_heizung notify HMS_WZ { if (ReadingsVal("HMS_WZ","temperature",99) < 15) { Log 3, "$NAME: Schalte KV4, $EVENT" } else { Log 3, "$NAME: ELSE Schalte KV4, $EVENT" } }
Bei einem
trigger HMS_WZ temperature:14
Wird immer der ELSE-Teil ausgeführt. S. Log:
2014.11.26 07:34:46 4: HTTP FHEMWEB:XXX.XXX.XXX.XXX:51628 GET /fhem&cmd=trigger+HMS_WZ+temperature%3A14
2014.11.26 07:34:46 4: low_level_heizung exec { if (ReadingsVal("HMS_WZ","temperature",99) < 15) { Log 3, "$NAME: Schalte KV4, $EVENT" } else { Log 3, "$NAME: ELSE Schalte KV4, $EVENT" } }
2014.11.26 07:34:46 3: HMS_WZ: ELSE Schalte KV4, temperature:14
Ich vermute, dass die Lösung so trivial ist, dass ich mich in Grund und Boden schämen werde.
Aber ich suche seit 3 Tagen nach einer Lösung. Suchmaschine & Forum hab ich auch schon durchsucht...
hüüülfe
Hallo,
aus der Commandref
ZitatIF (<condition>) (<FHEM commands1>) ELSE (<FHEM commands2>)
Hier sind IF und ELSE groß geschrieben - Perl ist Case Sensitiv, unterscheidet also zwischen Groß und Klein. Zudem stehen die Befehle in "normalen" Klammern.
Ich weiß, es gibt das Perl
if und das fhem
IF. Ich würde es mal mit dem fhem IF probieren.
Gruß Christoph
Edit: Kann es sein, das ReadingsVal nicht richtig funktioniert ? Dann würde der Wert durch 99 ersetzt und das bedeutet die ELSE Bedingung ist erfüllt. Ersetze die 99 doch mal durch 0 und schaue dann ob immer die THEN Bedingung erfüllt ist. Das würde dann für ein Problem mit ReadingsVal stehen. Im nächsten Schritt würde ich dann am Device ein UserReading erstellen und wenn das stimmt, diesen Wert nutzen.
- IF und ELSE ergeben einen Syntax-Fehler.
- Die 99 durch die 0 zu ersetzen, ändert das Verhalten nicht.
Dass es am ReadingsVal liegt, hatte ich schon vorher vermutet. Aber was mache ich da falsch?
Wie meinst Du das mit dem UserReading?
gruß
Klinki
Hallo,
ein UserReading kann im Detailbereich des Gerätes angelegt werden. Hier können vorhandene Reading zerlegt und anders Formatiert werden. Der Vorteil ist, das diese neue Reading im Detailbereich nagezeigt wird. Man kann somit spielen und sehen was passiert, bis man den "richtigen" Wert hat.
Bei IF und ELSE müssen die Klammern anders sein - siehe Commandref. An sonste siet das ja aus wie in der Einsteigerdoku.
Was ich mir noch vorstellen könnte - der Trigger löst aus und das ReadingsVal nimmt den "realen" Wert vom Gerät - und der ist größer als 15.
=> UserReading temp erstellen. Dem den Wert 14 geben und gegen diesen Wert im notify prüfen.
Gruß Christoph
Du schickst ein event, prüfst aber auf das reading ;)
notify: besser mit regex nur auf temp. außerdem ohne readingsval sondern direkt auf das event (part) prüfen. (commandref perl specials)
vg
jörg
Hi Jörg,
Die Aktion, die nachher ausgelöst wird, ist ja nur zu Probe. In der Variable $EVENT steht im Log dann auch der Wert des Readings des Geräts.
2014.11.28 08:13:12 4: low_level_heizung exec { if (ReadingsVal("HMS_WZ","temperature",99) < 15.0) { Log 3, "$NAME: Schalte KV4, $EVENT" } else { Log 3, "$NAME: ELSE Schalte KV4, $EVENT " } }
2014.11.28 08:13:12 3: HMS_WZ: ELSE Schalte KV4, temperature: 19
2014.11.28 08:13:12 4: low_level_heizung exec { if (ReadingsVal("HMS_WZ","temperature",99) < 15.0) { Log 3, "$NAME: Schalte KV4, $EVENT" } else { Log 3, "$NAME: ELSE Schalte KV4, $EVENT " } }
2014.11.28 08:13:12 3: HMS_WZ: ELSE Schalte KV4, humidity: 39.5
2014.11.28 08:13:12 4: low_level_heizung exec { if (ReadingsVal("HMS_WZ","temperature",99) < 15.0) { Log 3, "$NAME: Schalte KV4, $EVENT" } else { Log 3, "$NAME: ELSE Schalte KV4, $EVENT " } }
2014.11.28 08:13:12 3: HMS_WZ: ELSE Schalte KV4, battery: ok
2014.11.28 08:13:12 4: low_level_heizung exec { if (ReadingsVal("HMS_WZ","temperature",99) < 15.0) { Log 3, "$NAME: Schalte KV4, $EVENT" } else { Log 3, "$NAME: ELSE Schalte KV4, $EVENT " } }
2014.11.28 08:13:12 3: HMS_WZ: ELSE Schalte KV4, type: HMS100TF
2014.11.28 08:13:12 4: low_level_heizung exec { if (ReadingsVal("HMS_WZ","temperature",99) < 15.0) { Log 3, "$NAME: Schalte KV4, $EVENT" } else { Log 3, "$NAME: ELSE Schalte KV4, $EVENT " } }
2014.11.28 08:13:12 3: HMS_WZ: ELSE Schalte KV4, T: 19 H: 39.5 Bat: ok
Aber das nur nebenbei - zur Sache:
@Bennemannc: Deine zweite Vermutung war richtig: Der(oder das) ReadingsVal liest den Wert des realen Geräts und NICHT den des Triggers! ::)
Ich habe jetzt (einfach) die 15 durch eine 20 ersetzt und siehe da: Bei einer realen Temperatur von 19 Grad schaltet das Gerät den THEN-Teil und nicht den ELSE-Teil. So wie es sich gehört.
Den Wert, den ich beim Trigger angebe, interessiert das ReadingsVal nicht.
Vielen Dank für den Tipp!
dennoch...seeehr viel Zeit für die Suche von Fehlern aufgebracht, die nicht da sind! :-[
Hallo,
Jörg hat eigentlich nichts anderes geschrieben wie ich - er hat es nur anders ausgedrück. Sein Ansatz war, zur Prüfung einen Teil des Triggers - also die 14 - zu nehmen und nicht das Reading vom Gerät.
Damit wäre die Sache flexibeler und könnte auch sauber mit dem "trigger" Befehl geprüft werden.
-- Es führen eben viele Weg zu Ziel --
Gruß Christoph
Ich muss gestehen, dass ich die Hinweise von Jörg jetzt erst richtig verstehe. Man möge mir meine Unwissenheit nachsehen - bin neu.
Wo liegt denn der Vorteil bei der Regex-Variante? Außer, dass es dann mit dem Trigger funktionieren würde?
Mit Regex stand ich bisher immer auf Kriegsfuß und bin deshalb auch beim ReadingsVal gelandet. Und weil es einfache Beispiele im Einsteiger-PDF gibt.
Danke nochmal!
ZitatWo liegt denn der Vorteil bei der Regex-Variante? Außer, dass es dann mit dem Trigger funktionieren würde?
Wenn sich in Deinem "HMS_WZ" etwas ändert sendet es ein event wo drinsteht
was sich geändert hat. Die regex erfüllt jetzt zwei Aufgaben:
Zum ersten sorget sie dafür das Dein notify nir auf Änderungen der Temperatur reagiert. Viele Geräte senden Unmengen von verschiedenen Sachen in die fhem-welt: Temp, Luft-feuchte, Batterie (und so weiter). Wenn Dein notify jedes mal aktiviert wird steigt die Rechenlast an. Bei vielen verschiedenen notifys (da kommst Du schnell hin wenn Du weiter aufbaust) ist das nicht zu vernachlässigen. Die Rechenlast steigt und fhem würde schnell träge werden, das möchtest Du nicht :)
Die zweite Funktion in diesem Zusammenhang: die regex reagiert dann auf Temperatur und liefert den (empfangenen) Wert im notify ab, damit das notify damit arbeiten kann. Den Wert extra noch mal per readingsval zu holen ist also überflüssig, in Deinem Fall sogar schädlich
Du hast per trigger den Wert 14 an das notify geschickt. Dein notify beachtet den jedoch nicht sondern "holt" sich die echte Temperatur (per ReadingsVal) vom "HMS_WZ". Die echte wird aber über 14° liegen 8) und deshalb bekommst Du den vermeintlichen Fehler - der gar keiner ist.
Zu regex: unbedingt lernen (!!!), gehören zu den key Konzepten in fhem. Gibt verschiedene Seiten im Netz dazu. Sowohl Erklärung als auch Seiten wo Du testen kannst ob Deine regex das macht was Du denkst: http://regex101.com/ . Benutze ich auch regelmäßig.
vg
jörg
Hi Jörg,
So, habe jetzt mein funktionierendes Notify über Regex zusammen:
define low_level_heizung2 notify HMS_WZ:temperature:.* { if ($EVTPART1 < 16) { fhem("set KV_Schalter4 on-old-for-timer 3600") ;; Log 3, "$NAME: Schalte KV4, $EVENT" } else { Log 3, "$NAME: Schalte KV4 NICHT, $EVENT " }}
Wenn ich jetzt aber meinen Trigger ausführe:
trigger HMS_WZ temperature:14
...bekomme ich immer eine Fehlermeldung
2014.11.29 11:41:21 3: low_level_heizung2 return value: Global symbol "$EVTPART1" requires explicit package name at (eval 20542) line 1.
Vermutlich, weil die globale Variable $EVTPART1 bei einem Trigger nicht zur Verfügung steht....denke ich mal...
Wenn ich mir den Teil der Variablen bei jeder Ausführung des Notify wieder selbst erstelle, geht´s - auch per Trigger:
define low_level_heizung2 notify HMS_WZ:temperature:.* { my @EVP = split(":", $EVENT);; if ($EVP[1] < 16) { fhem("set KV_Schalter4 on-old-for-timer 3600") ;; Log 3, "$NAME: Schalte KV4, $EVENT" } else { Log 3, "$NAME: Schalte KV4 NICHT, $EVENT " }}
Damit kann ich leben. Ist halt nur etwas umständlich. Ginge das auch eleganter?
VG
klinki
klar, anders geht immer, elegant liegt im Auge des Betrachters :)
Mir ist beim schnellen drüberschauen nicht klar warum $EVTPART1 fehlt. Vermutung, bei dem hier wäre es da:
trigger HMS_WZ temperature: 14
Der Unterschied liegt im "space" nach dem doppelpunkt, so liefert der HMS (jedes device) das von sich aus.
Aber he: wenn es jetzt läuft 8)
schönes we
joerg
Hallo,
wenn $EVTPART1 nicht vorhanden ist steckt die benötigte Info vermutlich in $EVTPART0.
Dafür bau ich mir dann gerne Log(3,"$EVTPART0");
in den Code ein um zu schauen was wirklich drinnen steht ;)
Geht übrigens auch mit $EVENT, $NAME usw.
Grüße
Hi,
Das ist ja das Ulkige: $Event ist immer da; $EVTPART0, $EVTPART1, usw... sind nicht da. Das gilt aber nur für den Trigger!
Wenn das Gerät von sich aus sendet, ist alles da.
Ich werde noch ein bisschen experimentieren - aber das ist jetzt auch nur noch Ehrgeiz. Schließlich läuft alles zu meiner Zufriedenheit!
Danke euch nochmal!
Hallo,
die Trennung in die $EVTPARTx wird über Leerzeichen im Trigger gemacht. Daher hat "trigger temperature:14" keine Parts - ist eben kein Leerzeichen drin. "Trigger temperature: 14" hat eine Part0 "temperature:" und einen Part1 "14". Steht so in der Commandref.
Gruß Christoph
define low_level_heizung notify HMS_WZ { my $t = ReadingsVal("HMS_WZ","temperature",99); if ($t < 15) { Log 3, "$NAME: Schalte KV4, $EVENT" } else { Log 3, "$NAME: ELSE Schalte KV4, $EVENT" } }