neuer FHEM-Befehl IF

Begonnen von Damian, 25 Dezember 2013, 23:50:06

Vorheriges Thema - Nächstes Thema

Damian

#45
Zitat von: Zrrronggg! am 20 Januar 2014, 22:11:28

Ansonsten sehe ich Potential für zusätzliche Verwirrung gerade bei Anfängern. Leute, die meinen, man müsse grundsätzlich sowas schreiben:

define test at 13:00  { fhem("set xy on");;}


Und warum tun die das? Ganz einfach, weil sie als Anfänger nicht zwischen Perl und FHEM unterscheiden können und weil sie mindestens in jedem zweiten Beispiel einen bunten Mix aus FHEM und Perl-Befehlen zu sehen bekommen, weil sie zur Lösung ihrer Probleme mit nur FHEM-Befehlen nicht weiter kommen - nur meine Meinung.

Gruß

Damian

Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Zrrronggg!

a) besser Erklären
b) Hilfskonstrukte bauen


b) hat aus meiner Sicht den Nachteil, das man am Ende a) trotzdem machen muss, nur vielleicht etwas später.



FHEM auf Linkstation Mini, CUL 868 SlowRF, 2xCUL 868 RFR, CUL 433 für IT, 2xHMLAN-Configurator mit VCCU, ITV-100 Repeater, Sender und Aktoren von FHT, FS20, S300, HM, IT, RSL

Damian

#47
Zitat von: Zrrronggg! am 20 Januar 2014, 23:26:46
a) besser Erklären
b) Hilfskonstrukte bauen


b) hat aus meiner Sicht den Nachteil, das man am Ende a) trotzdem machen muss, nur vielleicht etwas später.

Sicher, allerdings behebt das nicht die Ursache des Problems, wenn das System für einfache Standardfälle nicht intuitiv genug ist.

Ich will es nochmal am einfachen Beispiel festmachen.

Da will jemand eine Zahl übernehmen und in Abhangigkeit der Größe einen Schalter schalten. Eigentlich eine triviale Sache und sollte mit Hilfe eines Automatisationssystem mit den Grundfunktionen einfach und intuitiv realisierbar sein.

Mögliche Lösung heute:

define LuefterEin at +*00:20:00 {my $actuator = (ReadingsVal("FHT_4955","actuator",0) =~ /(-?\d+(\.\d+)?)/) ? $1 : 0);;if ($1 > 15) { fhem ("set Luefter on")}}

Man kann es versuchen zu erklären, wobei man schon für reguläre Ausdrücke eine Vorlesung halten könnte.

Oder das System bietet die Möglichkeit es einfach und intuitiv zu realisieren, dann erspart man sich jegliche Erklärung.

define LuefterEin at +*00:20:00 IF ([FHT_4955:actuator:d] > 15)(set Luefter on)

Die einzige Erklärung wäre vielleicht, dass das d beim actuator zum Filtern von Zahlen ist, alles andere dürfte intuitiv klar sein.

Und ich möchte noch mal festhalten: Ich habe es nicht deswegen zum Download angeboten, weil ich es wollte, sondern weil es die User wollten - warum wohl?

Gruß

Damian 
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Franz Tenbrock

Als Anfänger ohne vorherige Programmierkenntnisse muss ich sagen das die 2. Zeile definitiv deutlich einfacher zu verstehen ist.
Generell ist es wichtig für mich gewesen Beispiele die man nachbauen kann zu haben.
Das Einsteiger PDf war hier Gold wert.
Lieber ein Beipiel mehr als eins zu wenig.

Das mit dem D in der Zeile wurde ja zum Glück auch angesprochen, darüber wäre ich gestolpert.
FHEM ist so mächtig das es halt am Anfang schwer ist den Überblick zu bekommen. Nicht jedem liegt es auch die commandref zu lesen und auch zu verstehen.
Viele sind es nciht gewohnt in ihrem Alltag täglich English zu lesen, und darüber hinaus es dann auch noch zu verstehen.

Für Anfänger zumindest reichen für sehr viele Aufgaben sicher auch einzelne if Schleifen.

Ich werde es in Kürze zumindest sicher ausprobieren udn freue mich schon.

Hatte noch keien Zeit im Wiki zu forschen ob da schon was steht. Das Wiki war für mcih schon sehr häufig sehr hilfreich.
cubi3, Cul 868, ESA2000WZ, EM1000GZ,  FS20, dashboard, 1-Wire, Max Thermos, Max Wandthermo, Max Lan, Fritzbox callmonitor, , nanocul, HM Led16, HM Bewegungsmelder, HM Schalter, RPi, banana, ESP8266, DoorPi

kermi

Ich habe schon seit über 2 Jahren ein gut funktionierendes FHEM - System auf meiner FB.
Trotz dieser langen Zeit habe ich auch heute noch immer Probleme bei diversen Codezeilen und ohne entsprechende Beispiele bin ich aufgeschmissen. Da hilft mir auch kein commandref lesen, teilweise verstehe ich auch da den Zusammenhang nicht.
Ich bin einfacher Anwender und möchte dieses bei FHEM auch bleiben. Natürlich muss man sich mit FHEM auseinandersetzen, sich in die Materie einarbeiten aber deswegen gleich ein Perl-Studium hinlegen??

Ich finde den FHEM-Befehl IF einfach nur genial, es wird mir in Zukunft viele grauen Haare und noch mehr Zeit sparen.

Gruß
Stephan
FB 7390 mit FHEM 5.5
2x CUL V2
HM-Sec-RHS, HM-ES-PMSw1-Pl, HM-PB-4Dis-WM, HM-LC-Dim1TPBU-FM, HM-LC-Sw1-FM, HM-PB-2-WM55, KFM 100, HM-OU-LED16,
EM 1000 WZ ... und div. Quatsch

Zrrronggg!

#50
Eure Einwände sind mir klar und ich hatte die Probleme auch.

Nur: FHEM wird nie wirklich einfach sein und erfordert intensive Beschäftigung mit der Materie.
Wieviel Zeit man da reinstecken will oder je nach "Vorbildung" muss ist sicher recht unterschiedlich.

Ich habe meinen Standpunkt vorgetragen, ihr euren. Mehr ist's nicht.

Aber wo wir gerade dabei sind, was fragt
  ([FHT_4955:actuator:d] > 15)
denn konkret ab?
FHEM auf Linkstation Mini, CUL 868 SlowRF, 2xCUL 868 RFR, CUL 433 für IT, 2xHMLAN-Configurator mit VCCU, ITV-100 Repeater, Sender und Aktoren von FHT, FS20, S300, HM, IT, RSL

Joachim

Moin Zrrronggg!,

ZitatNur: FHEM wird nie wirklich einfach sein und erfordert intensive Beschäftigung mit der Materie.
hier hast Du 100% recht, aber muss man sich deshalb das Leben noch schwerer machen, als es ohnehin schon ist?
Wenn ich mir diese beiden Zeilen ansehe:
Zitatdefine LuefterEin at +*00:20:00 {my $actuator = (ReadingsVal("FHT_4955","actuator",0) =~ /(-?\d+(\.\d+)?)/) ? $1 : 0);;if ($1 > 15) { fhem ("set Luefter on")}}
Zitatdefine LuefterEin at +*00:20:00 IF ([FHT_4955:actuator:d] > 15)(set Luefter on)
dann spriche das eigentlich Bände.
Und wer es nicht mag, kann auch weiterhin die alte Möglichkeit verwenden.
Das wird wahscheinlich in eine ähnliche Glaubensfrage herauslaufen, wie das direkte Bearbeiten der fhem.cfg.

Gruß Joachim
FHEM aktuellste Version auf FB 7570 und 7390 mit Zebradem Toolbox Freetz
FHEM auf Raspberry
1-Wire mit LinkUSBi und Rs-Pi ds2482-800  1-Wire-9 Board; Max mit Cube, HMLAN
div. 1-Wire Sensoren; MAX-Thermostaten; Homematic-Komponenten, Zehnder KWL über RS-232

rudolfkoenig

Die perl Version ist unnoetigerweise kompliziert, und kann auch als
define LuefterEin at +*00:20:00 {fhem ("set Luefter on") if(int(ReadingsVal("FHT_4955","actuator",0)) > 15) }

geschrieben werden.

Vermutlich wird dieses IF  fuer viele Anfaenger/Nicht-Programmierer eine Erleichterung sein und fuer die Fortgeschrittenen gleichzeitig Verwirrung stiften. Da die Betroffenen keine Doku lesen, weiss ich nicht, wie man diese Verwirrung mindern soll.

Zrrronggg!

#53
Zitat
Zitatdefine LuefterEin at +*00:20:00 {my $actuator = (ReadingsVal("FHT_4955","actuator",0) =~ /(-?\d+(\.\d+)?)/) ? $1 : 0);;if ($1 > 15) { fhem ("set Luefter on")}}

define LuefterEin at +*00:20:00 IF ([FHT_4955:actuator:d] > 15)(set Luefter on)
dann spriche das eigentlich Bände.

Ja, aber das ist 1. eine extremes Beispiel und ausserdem scheint mir das erste Beispiel auch noch deutlich einfacher schreibbar zu sein. Im Moment verstehe ich noch nicht, was das genau machen soll.


EDIT: Ich sehe gerade Rudolf hat schon gepostet.


Das ist genau das Problem. Viele machen die Sachen hier komplizierter als nötig. Die Kreativität mit der manche hier einfachste Sachen möglichst komplex formulieren erstaunt mich immer wieder. Am Anfang habe ich sogar gedacht ich übersehe irgendwas oder habe einfach zu wenig Ahnung. Ein schönes Beispiel ist der Wikiartikel zum Thema "Stellen des Datums bei FHTs".

Da wird nämlich folgendes Vorgeschlagen:

define fht_setdate notify fht_setdate { \
if ( $year gt 2010 ) {\
  my @@fhts=devspec2array("TYPE=FHT");; \
  foreach(@@fhts) { \
   my $cmd="set ".$_." date time";;\
   fhem $cmd;;\
   Log 4, "sent cmd ".$cmd;;\
  } \
} else {\
   Log 1, "error setting date for fhts: year <= 2010 - date invalid?!"\
}\
}
define t_fht_setdate at *02:00:00 trigger fht_setdate


wärend ich mir als Anfänger immer mit

define fht_dateupdate at *04:00:01 set TYPE=FHT date
define fht_timeupdate at *05:00:01 set TYPE=FHT time


geholfen habe und mich monatelang gefragt habe, wo ich damit zu kurz gedacht habe (mal vom Test auf Jahr > 2010 abgesehen, den ich im Zeitalter von ntp auch nicht sooo nützlich fand).

Daraus dann abzuleiten, dass man Befehle einfacher machen muss ist ... äh ... nicht unbedingt zwingend.

Auch Damians neue Sachen werden von den Ornamentkünstlern sehr schnell kreativ verkompliziert werden   ;)
FHEM auf Linkstation Mini, CUL 868 SlowRF, 2xCUL 868 RFR, CUL 433 für IT, 2xHMLAN-Configurator mit VCCU, ITV-100 Repeater, Sender und Aktoren von FHT, FS20, S300, HM, IT, RSL

Damian

Zitat von: rudolfkoenig am 21 Januar 2014, 13:24:08
Vermutlich wird dieses IF  fuer viele Anfaenger/Nicht-Programmierer eine Erleichterung sein und fuer die Fortgeschrittenen gleichzeitig Verwirrung stiften. Da die Betroffenen keine Doku lesen, weiss ich nicht, wie man diese Verwirrung mindern soll.

Sehe ich noch nicht mal so kritisch, denn die Anfänger kann man immer auf die Commandref des Befehls verweisen und die kann man mit vielen praktischen Beispielen bestücken (das habe ich übrigens im THRESHOLD-Modul gemacht und die Leute kommen gut klar damit). Die Fortgeschrittenen mit Perl-Kenntnissen sollten doch relativ schnell erkennen, was dahinter steckt und den Unterschied zwischen einem Perl-Befehl und einem Nicht-Perl-Befehl erkennen können.

Gruß

Damian
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Damian

Zitat von: Zrrronggg! am 21 Januar 2014, 14:04:57
Das ist genau das Problem. Viele machen die Sachen hier komplizierter als nötig.

OK. Dann ein anderes Beispiel: Ich möchte hinter einem at-Befehl im Reading nach on oder off filtern, weil da noch andere Sachen stehen und bei on einen Schalter schalten. Könntest du mir dafür eine kurze Lösung geben, bevor ich dir meine gebe?

Gruß

Damian
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

rudolfkoenig

define at *10:00 { fhem "set N2 on" if(ReadingsVal("N1","R1","D1") =~ m/on/) }


@Damian: ich will nicht dein IF schlechtreden, es ist einfacher fuer Anfaenger, und ist fuer bestimmte Fragestellungen kuerzer als ein Perl Ausdruck. Das ist kein Kunststueck, ich kann auch Aufgaben finden, die mit IF nicht oder nur haesslich zu realisieren sind.

Die Frage ist: macht man es den Anfaengern am Anfang leichter, und dafuer spaeter schwerer, oder gleich am Anfang schwer. :) Dein IF ist keine vollstaendige/etablierte/dokumentierte Sprache, und Anfaenger lernen damit was, was sie spaeter nicht verwenden koennen.
Man wird versuchen dich zu ueberzeugen, die "wenigen" fehlenden Elemente, die eine Sprache ausmachen, auch zu implementieren.

Ich bin nicht gegen IF (offensichtlich gibt es Bedarf dafuer), will aber, dass es deutlich dokumentiert wird.

Damian

#57
Zitat von: rudolfkoenig am 21 Januar 2014, 18:09:04
define at *10:00 { fhem "set N2 on" if(ReadingsVal("N1","R1","D1") =~ m/on/) }

OK das ist schon ziemlich kurz - ist ja vom Perl-Experten ;) (nebenbei: das m hättest du auch noch weglassen können)

Dass meine Lösung kürzer und intuitiver für Nicht-Perl-Experten wäre, brauche ich natürlich jetzt nicht zu nennen. Die z. Zt. vollständige deutsche Doku steht ja im ersten Post.

Es wäre interessant die Grenzen von IF auszuloten. Der Programmierer ist oft selbst irgendwann betriebsblind und sieht einfache Dinge nicht.
Ich habe den Parser versucht ziemlich vollständig zu implementieren. Übrigens in dem Zusammenhang: Eine Implementierung von Klammerebenen würde auch dem FHEM-Parser gut tun und das könnte man sogar abwärtskompatibel machen, denn die Geschichte mit dem Maskieren von Semikolons, ist aus meiner Sicht keine schöne Lösung und führt immer wieder zur Verwirrung.

Es wird z. Zt. hier viel über grundsätzliche Sachen diskutiert, was im Grunde auch gut ist, denn so schaut man etwas über den Tellerrand und kann auch frischen Wind in ein System bringen. Wir sollten aber erst mal abwarten, welche Erfahrungen es mit IF gibt, denn bisher gibt es noch kein Erfahrungsfeedback.

Gruß

Damian
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

DrBytebreaker

Bitte, Damian, mach weiter mit den FHEM IF.
Der Erfolg von Systemen hängt von der Einfachheit ab. Und FHEM hat Erfolg verdient. Wer nicht den Anspruch hat, schwierigste Zusammenhänge programmieren zu wollen, sondern nur ein funktionierendes System auf die Beine zu stellen, ist dankbar für alle Vereinfachungen. Warum haben Windows, MAC OS, Apps, Tabletts Erfolg? Genial einfach zu verwenden ohne Kommandozeileneditor für schnelle gute Ergebnisse....Wer mehr will, muss dann eben tiefer graben. Aber nicht gleich von Anfang an.
Vor der ganz großen Lösung mit einer eigenen Sprache bevorzuge ich einfache, leicht erstellbare Grundfunktionen. Weitergehendes kann man immer irgendwie durch Sonderzeichenkolonnen, Klammerkonstruktionen und ausgelagerte Skripte erreichen. Die FHEM-IF-Geschichte ist jedenfalls definitiv Grundfunktion für mich und dürfte Erfolgspotenzial haben.
:)

Das ist jetzt mal meine ganz ehrliche Meinung. Mit Respekt vor allen, die das Projekt bisher so aktiv und leidenschaftlich vorangebracht haben.
FHEM 5.7 Raspian auf Raspberry 2, 3 AVR-NetIOs, OWS Temperatursensoren, FS20-Aktoren und Sensoren, div. GPIOs, Intertechno Funksteckdosen, 3 WebCams

Damian

#59
Zitat von: DrBytebreaker am 22 Januar 2014, 16:40:21
Der Erfolg von Systemen hängt von der Einfachheit ab.

Wo wir wieder bei Grundsatzdiskussion wären.
Ich will mal versuchen zu erklären, warum die Mischung verschiedener Sprachen problematisch ist.

Wenn man eine höhere Programmiersprache (z. B. Perl) erlernen will, dann schaut man sich im Internet diverse Dokumentationen an und findet relativ schnell eine Lösung, weil es ein gesetzter Standard ist und wenn man schon mal eine höhere Programmiersprache gelernt hat, dann fällt es einem relativ leicht sich die Konstrukte der anderen Sprache schnell anzueignen - so ging es mir zumindest, als ich vor einem Jahr noch nicht mal wusste wie man das Wort "Perl" überhaupt schreibt.

Befindet man sich in einem anderen System, hier: FHEM, dann gelten dort ebenfalls gesetzte Regeln und Konstrukte und auch dafür gibt es Dokumentation, die man nachlesen kann, hier: Die Commandref

Und nun kommt die Mischung aus Beidem. Ich will es mal an dem vorherigen, relativ einfachen Beispiel von Rudi erklären:

define at *10:00 { fhem "set N2 on" if(ReadingsVal("N1","R1","D1") =~ m/on/) }

Es fängt ja mit der Definition eines Moduls (hier at). Das heißt, ich befinde mich in der FHEM-Welt. Das erwarte ich auch, da ich so etwas in der Kommandozeile eingeben kann. Nun geht es weiter mit der geschweiften Klammer. Da fragen man sich schon: Ist das die Sache des FHEM-Parsers oder ist das vielleicht bereits ein Block in Perl, denn dort werden Blöcke auch in geschweifte Klammern gesetzt. Wenn man nun herausgefunden hat, dass der FHEM-Parser dafür zuständig ist, dann kommt der nächster Bezeichner "fhem". Jetzt muss ich bereits wissen, dass FHEM die Kontrolle inzwischen an Perl übergeben hat. Wenn man das herausgefunden hat, kommt die nächste Frage: Ist das eine Funktion? Aber Funktionen besitzen üblicherweise Klammern und hier kommt bereits das Anführungszeichen. Nun muss man wissen, dass man in Perl bei Funktionen Klammern auch weglassen kann, der Inhalt scheint nun wieder FHEM-Welt zu sein, die mit dem nächsten Anführungszeichen wieder endet. Dann kommt ein if, da es kein Modul namens if in FHEM gibt, kann es sich jetzt wieder nur um Perl-Welt handeln. Dann kommt offenbar ein Funktionsaufruf mit Parametern. Den findet man nicht direkt unter den Modul-Namen von FHEM und auch nicht in der Perldokumentation, sondern in irgendwelchen Beispielen, die hier hundertfach kursieren. Nun weiß ich, dass ReadingsVal eine Funktion in Perl ist, die mir den Inhalt des Readings liefert und ich stoße zugleich auf einen Konstrukt, den ich noch in keiner anderen Programmiersprache gesehen habe =~. OK, es handelt sich hier offenbar um Perl-Welt und da finde ich in der entsprechenden Perl-Dokumentation, dass man damit nach Zeichenketten suchen kann.

Nun kann jeder mal nachzählen, wie oft die zwei Welten hier gewechselt haben und das macht die Sache so undurchschaubar, denn es entsteht immer die Frage: Wo kann ich hierzu eine Erklärung oder Lösung finden?

Ich habe die Vermischung beider Welten immer vermieden. Entweder konnte ich es mit Grundfunktionen ohne Perl realisieren, oder ich habe mir ein FHEM-Modul gebaut, welches mein Problem löst, jedoch nur Funktionsaufrufe in Perl nutzt, aber niemals FHEM-Befehle. Ich bin also immer in einer Welt geblieben. Nun kann aber nicht jeder gleich sich sein FHEM-Modul selbst bauen und tüftelt an abenteuerlichen Konstruktionen, die eine undurchsichtige Mischung zweier Welten darstellt, weil zu Grundfunktionalität von FHEM nach Ansicht vieler hier, offenbar Perl zählt - und das sehe ich anders. Ich muss ja auch nicht Java kennen, wenn ich ein Handy bediene, ich muss nicht Assembler kennen, wenn ich Java programmiere, ich muss nicht die Architektur eines bestimmten Prozessortyps kennen, wenn ich Assembler programmiere usw.

In diesem Sinne ...

Gruß

Damian
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF