Hallo,
ich suche zur Zeit für die Steuerung meiner Außenbeleuchtung nach einem Weg um herauszufinden, ob ein bestimmtes "at" angelegt ist.
Hintergrund: Gewünschte Funktion der Außenbeleuchtung ist folgende: ein kurzer Tasterdruck schaltet die Beleuchtung für zwei Minuten ein
define nAussenEinKurz notify Taster:kurz delete ALoffTmp;;set Aussenlampe on;;define ALoffTmp at +00:02:00 set Aussenlampe off
Ein langer Tastendruck dagegen toggelt den Zustand der Lampe, und zwar ohne zeitliche Begrenzung. Ist die Lampe aus, wird sie unbegrenzt eingeschaltet und andersrum. Sollte die Lampe aber nun aufgrund eines kurzen Tastendruckes bereits brennen, möchte ich, dass lediglich die zeitliche Begrenzung aufgehoben, die Lampe aber NICHT ausgeschaltet wird. Das leistet mein aktueller Code nicht:
define nAussenEin notify Taster:lang delete ALoffTmp;;set Aussenlampe toggle
Ein Lösungsversuch mittels IF-Kommando als notify-Kommando wie folgt schlug fehl, da das Kommando sich darüber beschwert, dass es ALoffTmp nicht gibt (wenn die Lampe aus ist oder nicht über kurzen Tastendruck eingeschaltet wurde), es wird leider nicht die ELSE-Clause ausgeführt. Könnte man das IF-Kommando eventuell einfach entsprechend so erweitern, dass man auch auf die Existenz eines Devices testen kann?
IF ([ALoffTmp]) (delete ALoffTmp;;set Aussenlampe on) ELSE (set Aussenlampe toggle)
Vielen Dank schon im Voraus für eure Lösungsansätze!
crispinus
Hallo crispinus,
versuch es doch mal damit:
define di_Aussen DOIF ([Taster] eq "kurz"]) (set Aussenlampe on-for-timer 120) DOELSEIF ([Taster] eq "lang"]) (set Aussenlampe toggle)
attr di_Aussen do always
Gruß
Igami
Was spricht gegen die Verwendung von on-for-timer und das ggfs. mit on-for-timer 0 zurück zu setzen?
if (defined "at-Name") ...
Die Tatsache, dass die zu schaltende Lampe als ECMDDevice leider (meines Wissens und auch meinen Tests nach) kein on-for-timer unterstützt (ist ein Arduino-Board, man könnte das natürlich auch in der Firmware implementieren, dafür müsste ich aber das Board aus dem Schaltschrank entfernen, was mit vergleichsweise hohem Aufwand verbunden ist). Deshalb die Lösung über das at.
Readingsproxy nutzen, dann hast Du das drin...
Und die Antwort auf die eigentliche Frage steht hier:
http://forum.fhem.de/index.php/topic,23584.msg168483.html#msg168483 (http://forum.fhem.de/index.php/topic,23584.msg168483.html#msg168483)
Zitat von: krikan am 13 September 2014, 08:18:52
if (defined "at-Name") ...
Ist das als Perl-Special gedacht oder eine Syntax für das IF-Kommando, die ich nirgendwo dokumentiert gefunden habe? Auf jeden Fall funktioniert es bei mir als FHEM-Kommando nicht richtig, wenn ich das so schreibe, wird immer die IF-Clause ausgeführt, egal ob "at-Name" definiert ist oder nicht. Im IF-Modulsource konnte ich auch kein "defined" als Qualifier finden.
VG
crispinus
Ist ein kleines if, darum Perl. Schau mal was Marvin Dir verlinkt hat, dort steht es ausführlicher.
Hallo,
ja, es macht durchaus einen Unterschied ob if oder IF.
Grüße
schau dir readingsProxy an. du bekommst on-for-timer umsonst mit dazu.
gruss
andre
Hallo,
erstmal vielen Dank für die vielen Vorschläge.
readingsProxy ist zwar ein tolles Modul, welches ich vorher noch nicht kannte, nützt aber für meinen konkreten Anwendungsfall wohl eher nichts, denn:
es spart mir ja letztlich nur das Anlegen des at-Kommandos zum Ausschalten. Ich kann bei langem Tastendruck immer noch nicht unterscheiden zwischen togglen der Lampe (wenn kein Timer gesetzt ist) und löschen des angelegten Timers während die Lampe eingeschaltet bleibt. Ich kann lediglich on-for-timer auf 0 setzen um den Timer zu löschen, aber das ändert den Zustand der Lampe nicht, ich muss also immer noch togglen bzw. eben entscheiden das nicht zu tun sondern die Lampe "an" zu belassen, wenn der Timer zuvor aktiv und die Lampe an war. Das konnte ich vorher mit dem "delete" des at-Kommandos genau so erreichen - es wurde zwar der Timer gelöscht, aber eben auch die Lampe ausgeschaltet (da toggle), was so nicht beabsichtigt war (die Lampe sollte stattdessen unbegrenzt an bleiben).
Der Vorschlag mit dem if löst dagegen mein Problem, auch wenn ich die Syntax (nach Lektüre des verlinkten Threads) noch etwas angepasst habe. Der Vollständigkeit halber sei die bei mir funktionierende Variante hier noch einmal exemplarisch aufgelistet:
define LampeToggleOderAn notify LampeToggleOderAn { if(defined($defs{'atLampeAus'})) { fhem "delete atLampeAus;;set Lampe on" } else { fhem "set Lampe toggle" } }
Die oben stehende, etwas kürzere Variante mit dem if(defined "atLampeAus")
führte bei mir immer zum Ausführen der IF- statt der ELSE-Clause, auch wenn atLampeAus gar nicht definiert war.
VG
crispinus
Siehe meinen Beitrag und den Link.
Zitatif(exists($defs{'objekt'})) ...
readingsProxy
Du könntest per readingsProxy aus Deinem Toggle-Device ein on/off-Device machen mit valueFn {LASTCMD}. Das hatte wir irgendwo im EnOcean-Bereich (Aufteilung Kanäle) schon einmal, finde es auf die Schnelle gerade nicht. Letztlich eine "Geschmacksfrage".
defined versus exists
if(defined($defs{'atLampeAus'} -> das ist korrekt
In diesem Zusammenhang mal eine Perl-Grundlagen-Frage:
Mit exists prüft man die reine Existenz eines Hash-Elementes, sein Wert ist egal.
Mit defined prüft man, ob ein Hash-Element einen Wert anders als "undef" hat. Also neben Existenz des Hash-Elements auch den (Fehler-)wert "undef".
Darum finde ich defined in vielen Fällen besser. Ist das falsch?
Zitatdefined versus exists
In diesem Zusammenhang mal eine Perl-Grundlagen-Frage:
Mit exists prüft man die reine Existenz eines Hash-Elementes, sein Wert ist egal.
Mit defined prüft man, ob ein Hash-Element einen Wert anders als "undef" hat. Also neben Existenz des Hash-Elements auch den (Fehler-)wert "undef".
Darum finde ich defined in vielen Fällen besser. Ist das falsch?
Keiner eine Meinung/Kommentar dazu?
Doch, aber dies hier ist nicht Dein Thread.
Danke, betateilchen für Deine ausführliche Antwort. ;)
Aber im Thread ging es auch um die Verwendung von exists oder defined. Ich meine letzteres ist besser, Marvin78 wohl erstes. Also wäre es nett, wenn Du mehr preisgibst. Ich meine Du verwendest auch defined. Kann aber natürlich auch separaten Thread aufmachen, wenn Du das wünscht.
EDIT:
Verweis auf separaten Thread http://forum.fhem.de/index.php/topic,27011.msg199677.html#msg199677
exists und defined sind zwei unterschiedliche dinge und es gibt kein generelles besser oder schlechter. so wie bei größer und größer gleich. mal ist das eine richtig und mal das andere. in manchen konstellationen geht beides.
gruss
andre
Zitat von: krikan am 14 September 2014, 09:49:19
readingsProxy
Du könntest per readingsProxy aus Deinem Toggle-Device ein on/off-Device machen mit valueFn {LASTCMD}. Das hatte wir irgendwo im EnOcean-Bereich (Aufteilung Kanäle) schon einmal, finde es auf die Schnelle gerade nicht. Letztlich eine "Geschmacksfrage".
Also wenn ich deinen Vorschlag jetzt richtig verstanden habe, dann trifft das trotzdem nicht mein Problem. Das eigentliche Device (die Lampe) ist ja gar kein ausschließliches toggle-Device, sondern lässt sich per on/off sehr wohl in einen gewünschten Zustand bringen. Es gibt nur eine spezifische Situation (Lampe + Timer zur Abschaltung ein), in der bei einer bestimmten Aktion (langer Tastendruck) kein Toggle auf Unendlich an/Unendlich aus gewünscht ist, sondern stattdessen ein Löschen des Timers und Halten der Lampe im eingeschalteten Zustand. Ich verstehe nicht, wie mir ein readingsProxy dabei helfen sollte, bin aber für ein Codebeispiel dankbar.
VG
crispinus