FHEM Forum

FHEM => Automatisierung => Thema gestartet von: Saphora am 26 Mai 2017, 20:58:33

Titel: Notify Perl Code
Beitrag von: Saphora am 26 Mai 2017, 20:58:33
Hallo
Ich habe ein Notify was auf alle Änderungen eines Systems regieren soll. Von daher wird der Perl Code sehr umfangreich.
Die Struktur sieht ungefähr so aus (Internals > DEF):

MessageNotify:message.* {
if() {}
elsif() {}
elsif() {}

        elsif() {
if(){}
elsif (){
if(){
if(){}
else{}
}
else{}
}
elsif (){}
elsif (){}
    }
else {}
}


Der dahinterliegen Code funktioniert, wenn der letzte elseif Abschnitt herausgenommen wird.
Meine Fragen:
- Ist an der verschachtelten Struktur etwas falsch?
- Macht es Sinn den Code in die 99_myUtils.pm auszulagern? Wenn ja, wie sieht die sub mit Übergabe aus?
- Gibt es Verbesserungsvorschläge?

Danke für jede Hilfe.
Titel: Antw:Notify Perl Code
Beitrag von: amenomade am 26 Mai 2017, 21:08:59
EDIT Eine } am Ende ist zu viel. Lieber ein ";" statt dessen.
Ne, sieht gut aus, aber wir wissen nicht, was zwischen den {} liegt.

ZitatMacht es Sinn den Code in die 99_myUtils.pm auszulagern?
Ja, würde ich sagen. Das ist aber abhängig von deinem Code, wenn   Du Parameter brauchst, usw

sub mysub {
if ... usw
}


und im notify :
MessageNotify:message.* { mysub();}

Weitere Verbesserungsvorschläge sind schwierig, ohne dein Code zu haben...
Titel: Antw:Notify Perl Code
Beitrag von: Saphora am 26 Mai 2017, 21:22:02
OK.
Hier der ganze Code. Verbesserung erwünscht :)

MessageNotify:message.* {
if ($EVTPART1 eq 'Temperatur') {
        my $temperature = ReadingsVal("WZ_Wandthermostat", "measured-temp", "");
        fhem("set $NAME send Wohnzimmer: $temperature");
    }

if ($EVTPART1 eq 'Solltemperatur') {
fhem("set $NAME send # # # Soll-Temperaturen # # #");
        my $temperature = ReadingsVal("WZ_Wandthermostat", "desired-temp", "");
    }

if ($EVTPART1 eq 'Benzin') {
my $benzinPreis = ReadingsVal("E5.Spritpreis", "readingsRegex_SuperE5", "");
        fhem("set $NAME send Benzin E5 $benzinPreis €");
        }


if ($EVENT =~ 'Wohnzimmer Heizung') {
if ($EVTPART3 eq "aus"){
fhem("set WZ_SollTemperatur desired-temp off");
fhem("set $NAME send Wohnzimmer an");
}
elsif (Value("WZ_Fensterkontakt") eq "closed" && Value("WZ_Tuerkontakt") eq "closed"){
if($EVTPART3 =~ /^[\d.]+$/){
if ($EVTPART3 < 31){
fhem("set WZ_SollTemperatur desired-temp $EVTPART3");
fhem("set $NAME send Wohnzimmer Heizung auf $EVTPART3 gestellt");
}
else{
fhem("set $NAME send Maximal 30 Grad möglich");
}
}
else{
fhem("set $NAME send *$EVTPART3* kann nicht eingestellt werden");
}
}
elsif (Value("WZ_Fensterkontakt") eq "open"){
fhem("set $NAME send Wohnzimmerfenster ist auf");
}
elsif (Value("BZ_Tuerkontakt") eq "open"){
fhem("set $NAME send Wohnzimmertür ist auf");
}
    }

else {
        fhem("set $NAME send Befehlt nicht bekannt");
    }


}
Titel: Antw:Notify Perl Code
Beitrag von: amenomade am 26 Mai 2017, 22:03:33
Also... da Du $EVENTPART oder $NAME nutzt, wird es m.A. schwieriger nach myUtils zu verschieben. Als Parameter zu sub, usw.

So auf die schnelle, sehe ich keine Verbesserung, die die Lesbarkeit nicht verschlechten würden.

Einige elseif sind verschwunden. Funktioniert dein notify jetzt besser?
Titel: Antw:Notify Perl Code
Beitrag von: Saphora am 26 Mai 2017, 22:08:52
Das Notify funktioniert problemlos, bis der folgende Code drin ist:

elsif (Value("WZ_Fensterkontakt") eq "closed" && Value("WZ_Tuerkontakt") eq "closed"){
if($EVTPART3 =~ /^[\d.]+$/){
if ($EVTPART3 < 31){
fhem("set WZ_SollTemperatur desired-temp $EVTPART3");
fhem("set $NAME send Wohnzimmer Heizung auf $EVTPART3 gestellt");
}
else{
fhem("set $NAME send Maximal 30 Grad möglich");
}
}
else{
fhem("set $NAME send *$EVTPART3* kann nicht eingestellt werden");
}
}
elsif (Value("WZ_Fensterkontakt") eq "open"){
fhem("set $NAME send Wohnzimmerfenster ist auf");
}
elsif (Value("BZ_Tuerkontakt") eq "open"){
fhem("set $NAME send Wohnzimmertür ist auf");
}
    }


Ist zuviel Code in einem Notify ein Problem für FHEM ?
Was anderes würde mir nicht einfallen, warum es dann plötzich nicht mehr geht.
Man sendet etwas, aber keine Reaktion seitens FHEM. Im Log sieht man den Befehl ankommen, er wird aber nicht verarbeitet.
Titel: Antw:Notify Perl Code
Beitrag von: amenomade am 26 Mai 2017, 22:47:42
Kommt das nicht von deinem $EVTPART3, der nicht immer definiert ist?

Ich habe zum Test folgendes angelegt:

define dutest dummy
define nttest notify dutest.* { if ($EVTPART5 =~ /^[\d.]+$/){ fhem ("set ez_Licht on")}}


Wenn ich jetzt set dutest 1 eingebe, bekomme ich folgendes in der Log:
2017.05.26 22:43:47 1: ERROR evaluating my $SELF='nttest';my $EVENT='1';my $NAME='dutest';my $EVTPART0='1';my $TYPE='dummy';{ if ($EVTPART5 =~ /^[\d.]+$/){ fhem ("set ez_Licht on")}}: Global symbol "$EVTPART5" requires explicit package name at (eval 153951) line 1.


Mit "set dutest 1 2 3 4 5 6" geht mein Licht an.
Titel: Antw:Notify Perl Code
Beitrag von: Saphora am 26 Mai 2017, 23:18:39
Also komisch ist es wirklich. Wenn ich einen Befehl mit drei Argumenten (z.B. A B C) eingebe, wird "Befehlt nicht bekannt" ausgebenen. Das ist auch korrekt so.
Warum sollte aber $EVTPART3 das Problem sein?
In den if/elsif Abfragen wird ja´definiert, wann die jeweile Bedingung erfüllt ist.
Aber z.B. bei Eingabe von "A B" wird "Befehl nicht bekannt" nichts ausgegeben.
Das ist mior nicht wirklich klar  :-[
Titel: Antw:Notify Perl Code
Beitrag von: amenomade am 26 Mai 2017, 23:23:23
ZitatWenn ich einen Befehl mit drei Argumenten (z.B. A B C) eingebe
Dann ist $EVTPART3 definiert und enthält C. Der Code läuft.

ZitatAber z.B. bei Eingabe von "A B" wird "Befehl nicht bekannt" nichts ausgegeben.
Dann existiert $EVTPART3 gar nicht, und du kriegst einen Fehler "ERROR evaluating.... ". Natürlich wird kein Code durchgeführt, sogar nicht der aller erste "if".

Perl ist eine interpretierte Programmiersprache. Der Code wird erst geladen, und "evaluated" wenn der notify getriggert wird.  Existiert $EVTPART3, wird der Code durchgeführt. Existiert $EVTPART3 nicht => Syntax error. In dem Fall "ERROR evaluating....."

Schau mal in der Log.

Titel: Antw:Notify Perl Code
Beitrag von: rudolfkoenig am 27 Mai 2017, 14:57:16
Falls man Probleme mit dem Perl-Code hat, dann sollte man es nach 99_myUtils.pm verschieben: da sind die Fehlermeldungen klarer, und man muss nicht mit ;; und \ rumkaempfen. Letzteres versucht zwar FHEMWEB zu verstecken, das funktioniert aber nicht perfekt.

Beispiel: In fhem.cfg bleibt:
define myNotify notify MessageNotify:message.* { myFunction($NAME, $EVTPART1) }
und in 99_myUtils.pm gibt es
sub
myFunction($$)
{
  my ($NAME, $EVTPART1) = @_;
...
}


Testen kann man das mit
{ myFunction("MessageNotify", "bla") }
oder wie bisher mit
trigger MessageNotify message bla

Falls man auf eine variable Anzahl von Event-Feldern reagieren will, dann uebergibt man $EVENT an die Funktion (statt $EVTPART*), da spaltet man es selbst (my @evArr = split(" ", $EVENT)), und prueft auf die Laenge von evArr, bevor man auf bestimmte Elemente zugreift.
Titel: Antw:Notify Perl Code
Beitrag von: Saphora am 27 Mai 2017, 21:40:10
Ok. Da danke ich für die Hinweise. Wo der Fehler liegt, ist mir jetzt klar.
Nice Weekend :)