FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: Elektrolurch am 26 Juni 2013, 11:25:03

Titel: fhem-Variablen mit Perl setzen
Beitrag von: Elektrolurch am 26 Juni 2013, 11:25:03
{sunrise () }

Hallo,

ich habe als Anfänger da noch etwas Probleme mit Perl. Folgender Code wird nicht korrekt ausgeführt.
Auf der Seite "Haus" soll über zwei dummys die aktuelle Sonnenauf- und -untergangszeit angezeigt werden.
Die Attribute longitude usw sind gesetzt.
Code:
define Sonnenaufgang dummy
attr Sonnenaufgang room Haus
define Sonnenuntergang dummy
attr Sonnenuntergang room Haus

define sunrise_update at *05:00:00      {my $Sonnenaufgang = sunrise ();;\
       my $Sonnenuntergang = sunset ();;\
       FB_mail('xx@@yyyde','Sonnenaufgang / -untergang gesetzt', \
            Value("Sonnenaufgang"));; }

Sonnenaufgang und Sonnenuntergang bleiben undefiniert. Der at ist aber als aktiv eingetragen.
Gebe ich direkt über die Kommandozeilesunrise () und sunset () ein, so

sunrise() liefert 28:32:25
sunset () 22:02:58
1. Da ist wohl noch ein Fehler in der Berechnung von sunrise, da muss 24 h abgezogen werden.
2. Die Mail ist nur zum Testen in das at mit eingebunden. Warum erfolgt aber keine Zuweisung  auf die beiden dummys? Ein Syntax-Fehler wird nicht beim abspeichern der fhem.cfg gemeldet.
3. Wie kann man alternativ noch fhem-Variablen mit Perl setzen? set Sonnenaufgang {sunrise ()}funktioniert nicht, danach hat Sonnenaufgang den Wert "{sunrise ()}". Außerdem würde der set nur einmal ausgeführt werden, also daher der at-Befehl.
 Wie kann ich im Bodeytext der Mail ein concat machen, wenn ich beide Werte ausgeben möchte? geht das so: Value("Sonnenaufgang"9) & Value("Sonnenuntergang")? Ist "&" der String concat in Perl?

Wie gesagt, Perl ist neu für mich, ich komme aus der C++ - Welt.
 
Elektrolurch

 
Titel: Aw: fhem-Variablen mit Perl setzen
Beitrag von: Puschel74 am 26 Juni 2013, 12:19:49
Hallo,

das schon gesehen?

Link (http://forum.fhem.de/index.php?topic=13498.0)

Grüße
Titel: Aw: fhem-Variablen mit Perl setzen
Beitrag von: justme1968 am 26 Juni 2013, 12:24:53
schau dir mal die commandref zu SUNRISE_EL an. da findest du auch was es mit den 24 stunden 'zu viel' auf sich hat (die kein fehler sonder absicht  sind) und welche sunrise varianten es noch gibt.

gruss
  andre
Titel: Aw: fhem-Variablen mit Perl setzen
Beitrag von: Dietmar63 am 26 Juni 2013, 13:01:14
mit
my $Sonnenaufgang = sunrise ();;
änderst du die Perlvariable $Sonnenaufgang. Perlvariablen beginnen, je nach Variablentyp immer mit einem $, %., & oder @.

mit
set Sonnenaufgang 19.07.1963
wird die fhem-Variable Sonnenaufgang mit dem Text "19.07.1963" belegt.

In Deinem Fall mußt du aus einer Perlfunktion heraus die fhem-Variable Sonnenaufgang füllen
Dazu muss der fhem Befehl set ... zusammengebaut werden und mit der Perlfunktion fhem() an fhem übergeben werden:
...
my $Sonnenaufgang = sunrise ();;\
my $Sonnenuntergang = sunset ();;\
fhem ("set Sonnenaufgang $Sonnenaufgang" );;\
fhem ("set Sonnenuntergang $Sonnenuntergang" );;\´
...


man muß leider immer die verschiedenen Ebenen Perl/fhem auseinander halten.

sunrise() und sunset() liefern je nach Variante relative Werte bis zum nächsten sr/ss oder absolute Werte des aktuellen Tages oder des darauf folgenden Tages oder sogar in Werten >24 Stunden, wenn der ss am folgenden Tag ist.  
Titel: Aw: fhem-Variablen mit Perl setzen
Beitrag von: Elektrolurch am 26 Juni 2013, 20:27:34
Hallo Dietmar63,

danke für den Hinweis. Mir war nicht klar, das Perl wohl innerhalb der "strings" auch parst und somit die Variablen erkennt.
Ich habe den Code wie folgt geändert:

# Sunnenaufgang und -untergang setzen

define Sonnenaufgang dummy
attr Sonnenaufgang room Haus
define Sonnenuntergang dummy
attr Sonnenuntergang room Haus

define sunrise_update at *05:00:00      {my $Sonnenaufgang = sunrise_abs ();;\
my $Sonnenuntergang = sunset_abs ();;\
fhem ("set Sonnenaufgang $Sonnenaufgang" );;\
fhem ("set Sonnenuntergang $Sonnenuntergang" );;\
       FB_mail(xx@@yyy.de' (@@yyy.de'),'Sonnenaufgang / -untergang gesetzt', \
            "Sonnenaufgang: $Sonnenaufgang Sonnenuntergang $Sonnenuntergang');;}

Ich bin davon ausgegangen, dass die Zeile:
fhem ("set Sonnenuntergang $Sonnenuntergang" )
dazu führt, das in Sonnenaufgang der Text "$Sonnenaufgang" steht. Danach müsste der concat in der Mail ja so auch funktionieren.
Wenn ich "Trigger sunrise_update" in die Kommandozeile eingebe, werden die Werte allerdings immer noch nicht gesetzt und eine Mail geht auch nicht heraus. Großes Fragezeichen????
Im log steht auch nichts.

Danke für die Hinweise.

Elektrolurch
Titel: Aw: fhem-Variablen mit Perl setzen
Beitrag von: Dietmar63 am 26 Juni 2013, 23:36:55
Triggern funktioniert nur bei notify

Ich rate dir möglichst viel zu loggen mit Log 3,<text>
Dann hast du eine Chance die Ursachen für Fehler schnell zu finden. Zum Einfügen von log_Komandos habe ich mir ein Makro in pspad(editor) erstellt

Weiterhin bin ich ein Freund von oneliner in fhem.Cfg.

Dann wird im at nur eine Funktion aufgerufen. Die Methode wird in 99_util definiert und hat keine ;;\ mehr.

Fb_mail ist durch @@ recht undurchsichtig.
Beim direkten Aufruf aus Perl reicht @. wenn Fb_mail in fhem.Cfg definiert wird erfolgt eine Substitution von @@ durch @. Ob das auch für mehrzeilige Perlfunktionen gilt weiß ich nicht. Jedenfalls habe ich auch mal Probleme damit gehabt und gerätselt.

Titel: Aw: fhem-Variablen mit Perl setzen
Beitrag von: justme1968 am 27 Juni 2013, 10:33:18
ein at kann man mit{ at_Exec( $defs{<at device>} ) } anstoßen.

gruss
  andre
Titel: Aw: fhem-Variablen mit Perl setzen
Beitrag von: Elektrolurch am 27 Juni 2013, 11:35:09
Hallo,

jetzt habe ich die Mailanweisung durch log - Anweisungen ersetzt, genauso wie es teilw. im Forum verwendet wird. Hilfe: Ich verstehe nicht, warum es nicht funktioniert. Da ist doch syntaktisch alles ok.
Code:
define NiemandzuHause2 notify AlleGeraete:absent \
    { log 3,'NiemandzuHause2';;\
        if($hour > 7 ) { fhem "set Familie absent";;}}

define JemandzuHause2 notify AlleGeraete:present \
     {log 3,'JemandzuHause2';;\
              if($hour > 7 ) { fhem "set Familie present" ;;}}


log:
2013.06.27 11:18:48 3: NiemandzuHause2 return value: Unknown command {, try help
Unknown command if($hour, try help
Unknown command }}, try help
2013.06.27 11:18:58 3: Mail sent to Raimund@rriem.de (Raimund@rriem.de)
2013.06.27 11:18:58 3: JemandzuHause2 return value: Unknown command {log, try help
Unknown command if($hour, try help
Unknown command }}, try help

Und warum enthält $bodytext nicht Stunde und Minute?
            my $bodytext = 'mit variable Bodytext fuer den Test $hour $min';;\
sondern den Text " mit variable Bodytext fuer den Test $hour $min"?

Elektrolurch

Titel: Aw: fhem-Variablen mit Perl setzen
Beitrag von: Puschel74 am 27 Juni 2013, 11:44:48
Hallo,

lies dir mal das hier durch:

Link (http://forum.fhem.de/index.php?topic=13475.0)

Grüße

Edith:
In dem von dir geposteten "Auszug" wenn es überhaupt einer sein soll sehe ich nirgends
Zitatmy $bodytext
Also was bringt dich zu der Annahme das in $bodytext $hour enthalten sein soll?

Edith2:
Zitatgenauso wie es teilw. im Forum verwendet wird.
Wenn es teilweise wirklich so im Forum verwendet wird haben alle dieselben Probleme gehabt und in den jeweiligen Beiträgen sollten dann auch die Lösungen zu finden sein.
Titel: Aw: fhem-Variablen mit Perl setzen
Beitrag von: Elektrolurch am 27 Juni 2013, 12:13:33
Hallo Puschel,

leider stehe ich auf dem Schlauch. In dem Artikel geht es doch darum, mehrere fhem-Anweisungen hintereinander ausführen zu lassen. Ich bekomme doch schon nach der notify - Anweisung {log 3,'text...' eine Fehlermeldung im log, wenn das notify ausgeführt wird.
Es wäre einfacher, Du würdest mir gleich sagen, was da falsch ist, den Artikel hatte ich nämlich schon auch vorher mal gelesen. Danke.
Titel: Aw: fhem-Variablen mit Perl setzen
Beitrag von: Puschel74 am 27 Juni 2013, 12:17:00
Hallo,

wie hat Rudi schonmal geschrieben:
Gelesen ist ja auch subjektiv ;-)

Zitat aus dem verlinkten Beitrag von Rudi:
ZitatDas Problem sieht man, wenn man im Detail-Ansicht die REGEXP-Zeile anschaut: wg. dem fruehen NL wird das Regexp mit einem \{ versehen.

Wenn du dir diesen Beitrag wirklich durchgelesen hast siehst du das ich einen korrigierten Code gepostet habe.

Klar kann ich dir deinen auch korrigieren - und dem nächsten und dem nächsten.

Versuch es doch mal selbst und schau mal nach wo der Unterschied zwischen { und deinem { liegt.
FHEM nimmt es sehr genau mit der Zeichensetzung und auch mit Schlüsselwörter.

Grüße

Edith: Ok - ich hab deine signatur erst jetzt gelesen sorry. Moment ich mach mich grad an deinen Code.
Titel: Aw: fhem-Variablen mit Perl setzen
Beitrag von: Puschel74 am 27 Juni 2013, 13:12:11
Hallo,

so

define NiemandzuHause2 notify AlleGeraete:absent {
  Log 3,("NiemandzuHause2");
  if($hour > 7 ) {
    fhem ("set Familie absent");
  }
}

define JemandzuHause2 notify AlleGeraete:present {
  Log 3,("JemandzuHause2");
  if($hour > 7 ) {
    fhem ("set Familie present");
  }
}


sollte der Logeintrag erzeugt werden.
Bearbeite aber bitte in FHEM das DEF des jeweiligen notify.
Dann brauchst du nur den Teil ab
ZitatAlleGeraet:absent {
und
ZitatAlleGeraete:present {
hinein kopieren.
Den Zeilenschutz und -umbrüche übernimmt dann FHEM für dich.

Grüße

Edith: Ich hoffe die Code-Tags sind kein Problem für deinen Reader - wenn ja gib Bescheid.
Dann stell ichs dir ohne Tags nochmal rein.
Titel: Aw: fhem-Variablen mit Perl setzen
Beitrag von: Elektrolurch am 27 Juni 2013, 13:16:48
Hallo,

okay, dass mit dem \} habe ich übersehen, obwohl nicht ganz logisch, da ja noch ein LF (Zeilenschaltung) dazwischen liegt. Da ich den PC nicht mehr lesen kann, verwende ich einen Screenreader. Deshalb beschränke ich mich auch auf das editieren der fhem.cfg.
Jetzt kommt zwar auch keine Fehlermeldung im fhemlogfile, aber die Anweisung log 3,<Text> schreibt auch nichts die die fhemlog-Datei. Was habe ich da übersehen?
Generell:
Eigentlich wäre eine Ergänzung in einem Howto ganz sinnvoll:
1. Einer fhem-Variabeln in fhem einen Wert einer Perlvariablen oder Funkton zuweisen (z.B.
define Sonnenuntergang dummy
set dummy ... #Wert von sunrise() zuweisen
2. In einem perl-Bereich {  = einer fhem-Variablen einen Wert zuweisen
3. In einem Perl-Bereich eine fhem-Variable abfragen. DA gibt es wohl mehrere Versionen ($value, value () )
Und dann ist auch nicht ganz klar, wann was ausgewertet wird vom Perl-Parser (z.B. Werte in " ..."
Man findet zwar über die Beiträge im Forum verteilt hier und da etwas dazu, das aber aus dem Code zu extrahieren, um die richtige Syntax zu erkennen, ist ziemlich mühselig und führt auch zu Fehlern.
Wenn es also zu dem Thema mal einene knappe Ergänzung in einem Howto geben würde, wäre das hilfreich.

Elektrolurch
Titel: Aw: fhem-Variablen mit Perl setzen
Beitrag von: Puschel74 am 27 Juni 2013, 13:22:18
Hallo,

ZitatDeshalb beschränke ich mich auch auf das editieren der fhem.cfg.

Ok. Dann werd ich versuchen die Zeichen ein zu bauen.

define NiemandzuHause2 notify AlleGeraete:absent {\
  Log (3,"NiemandzuHause2");;\
  if($hour > 7 ) {\
    fhem ("set Familie absent");;\
  }\
}

define JemandzuHause2 notify AlleGeraete:present {\
  Log (3,"JemandzuHause2");;\
  if($hour > 7 ) {\
    fhem ("set Familie present");;\
  }\
}

So sollte es auch in der fhem.cfg passen.

$value bitte nichtmehr verwenden. Value( ) ist passend.

Grob gesagt. Sobald du ein { drinnen hast befindest du dich in Perl und musst an fhem dann Befehle mit
fhem ("set Dummy ".$Wert);;\
an FHEM zurück übergeben.

HowTos gibt es viele im Wiki.

Grüße
Titel: Aw: fhem-Variablen mit Perl setzen
Beitrag von: Dietmar63 am 27 Juni 2013, 16:14:19
log wird groß Log geschrieben - Perl unterscheidet zwischen Groß- und Kleinschreibung!
Titel: Aw: fhem-Variablen mit Perl setzen
Beitrag von: Dietmar63 am 27 Juni 2013, 16:27:21
Das Problem besteht meiner Meinung nach darin, dass du gleichzeitig Perl an sich und Perl inherhalb von fhem lernst.
In fhem wird der Perlcode als Sting abgelegt und dynamisch mit der Funktion eval() zur Ausführung gebracht.

Damit der PerlCode in FHEM verwaltet werden kann wird er in Metazeichen "eingepackt": ;;\ ...
Es gibt im Netz Handbücher für Perl, die vieles sehr gut erklären.

Wenn du auf oneliner in fhem.cfg umstellst und nur noch Funktionen der 99_util aufrufst musst du in 99_util mit echtem Perlcode kämpfen und die Beschreibungen im Internet sind ohne zusätzliche Ebene nutzbar. Die 99_util editiert man am Besten über einen externen Editor von Linux oder Windows aus. Der bietet dann sogar Syntaxhighligthing. Dazu benötigt man halt Fernzugriff auf die FB oder den Pi. Man muss dann allerdings mit reload 99_util das Modul in die Laufzeitumgebung von fhem/Perl nachladen.

in fhem.cfg
define blablabla at *05:00:00  { tueDies() }
in 99_util:

sub tueDies($) {
  <Percode>
}

Titel: Aw: fhem-Variablen mit Perl setzen
Beitrag von: Puschel74 am 27 Juni 2013, 16:55:29
Hallo,

was Elektrolurch aber nur bedingt hilfreich sein wird.
Lies dir mal seine Signatur durch.
Von Syntaxhighligthing wird er nicht viel haben und auch diverse Perlbücher werden nur bedingt hilfreich sein.

Ich weiß ja nicht ob sein Reader zwischen Groß- und Kleinschreibung unterscheidet.

Das wär jetzt mal eine Anforderung an eine morderne GUI.

Grüße
Titel: Aw: fhem-Variablen mit Perl setzen
Beitrag von: Elektrolurch am 27 Juni 2013, 17:10:09
Hallo Dietmar,

danke für den Hinweis. Der Screenreader liest standardmäßig keine Großschreibung vor, es sei denn, ich gehe mit der Pfeiltaste die Buchstaben einzeln ab. Deshalb ist es am Anfang für mich etwas schwerer... daher bin ich ganz froh, wenn mich jemand direkt auf einen Fehler hinweist, als auf andere threads zu verweisen. Danke nochmals.
Das Konzept ist mir grundsätzlich schon klar, habe ja auch mal vor 20 Jahren Shellskripts, C und C++ nur so runter programmiert. Jetzt wollte ich mal da wieder mit anfangen. Perl-Code ist ja schon grausig zu lesen. Für das Projekt, was ich vor habe, geht wohl das meiste direkt mit fhem.
Elektrolurch
Titel: Aw: fhem-Variablen mit Perl setzen
Beitrag von: Puschel74 am 27 Juni 2013, 17:19:08
Hallo,

Zitatdaher bin ich ganz froh, wenn mich jemand direkt auf einen Fehler hinweist, als auf andere threads zu verweisen.

Wenn du deine Signatur von Anfang an so ausgefüllt hättest hätte ich dich auch nicht auf den anderen Beitrag verwiesen.
Ich könnte nämlich fast schwören das heute morgen nur der erste Teil in deiner Signatur stand ;-)

Grüße
Titel: Aw: fhem-Variablen mit Perl setzen
Beitrag von: Elektrolurch am 27 Juni 2013, 17:33:08
Hallo,

das stimmt. Ich bin auch erst heute morgen auf die Idee gekommen, dass in die Signatur hineinzuschreiben. Ist schon klar, dass es auch viele nervige Frager gibt.. und dann gerne auf bestehende Beiträge verwiesen wird. Ich hatte mir schon eine Liste von Fragen erstellt und hatte schon eine Reihe von Beiträgen dazu angesehen. Manches ist aber einfach nicht ganz schlüssig.
Beispiel:
log 3, ("Text');;
Warum muss das jetzt in runde Klammern?
Ich habe da auch Aufrufe ohne die () gesehen. Ja, aller Anfang ist schwer.
Titel: Aw: fhem-Variablen mit Perl setzen
Beitrag von: Puschel74 am 27 Juni 2013, 17:40:28
Hallo,

Zitatlog 3, ("Text');;

Hier hast du
a) wieder das Problem das log klein geschrieben ist. Das L muss aber groß geschrieben werden.
b) Du solltest nicht " und ' mischen - das gibt Fehlermeldungen.
Ich denke aber mal das war jetzt nur in diesem Beispiel von dir.

Warum das jetzt in ( ) kommt kann ich dir leider nicht beantworten - ich vermute mal wegen der { am Anfang.
Diese kennzeichnet ja den Perl-Teil.
Ich schreib meine Logeinträge immer so

Log(3,"Hier das was ich lesen will");;

Grüße
Titel: Aw: fhem-Variablen mit Perl setzen
Beitrag von: Dietmar63 am 27 Juni 2013, 17:55:14
ZitatPerl-Code ist ja schon grausig zu lesen
Anfangs ja - später nein. Es ist halt gewöhnungsbedürftig!

Wer von Perl nach c++ wechselt hat auch so seine Schwierigkeiten.
Titel: Aw: fhem-Variablen mit Perl setzen
Beitrag von: Dietmar63 am 27 Juni 2013, 18:00:48
Log(3,"Hier das was ich lesen will");
bzw.
Log 3,"Hier das was ich lesen will";

sind gleichwertige Scheibweisen in Perl.
In Perl gibt es den Grundsatz: "Du kannst Dinge immer auf vielerlei Art machen". - na ja!

Merkwürdig ist zum Beispiel die Variante das if (<Bedingung>) hinter die Anweisung zu schreiben.
Titel: Aw: fhem-Variablen mit Perl setzen
Beitrag von: rudolfkoenig am 27 Juni 2013, 18:14:05
Kommt daher, dass Larry Wall Linguistik studiert hat, und mit perl versucht hat die natuerliche Sprache nachzubauen, da gibt es auch mehrere Moeglichkeiten fuer den Satzbau.