neue Features: ereignisgesteuertes Perl - DOIF-Perl

Begonnen von Damian, 25 Februar 2018, 21:29:16

Vorheriges Thema - Nächstes Thema

spi3845

#255
Hallo,

kann man inzwischen eine Perl-Variable innerhalb von [] verwenden?

Also etwas der Art:
defmod di_text DOIF {
my $geraet="sensor123";;

if ([$geraet:gesperrt,1] eq 0) {
Log 1, "es geht";;
}

}


Danke schon mal!

Noch ein Nachtrag:

wie halte ich es dann mit z. B.
set_Exec("timer", 30, 'fhem("setreading $geraet gesperrt 0")');;

Muss ich hier dann $_geraet statt $geraet deklarieren und nutzen?

Damian

Zitat von: spi3845 am 10 März 2022, 11:50:48
Hallo,

kann man inzwischen eine Perl-Variable innerhalb von [] verwenden?

Also etwas der Art:
defmod di_text DOIF {
my $geraet="sensor123";;

if ([$geraet:gesperrt,1] eq 0) {
Log 1, "es geht";;
}

}


Danke schon mal!

Noch ein Nachtrag:

wie halte ich es dann mit z. B.
set_Exec("timer", 30, 'fhem("setreading $geraet gesperrt 0")');;

Muss ich hier dann $_geraet statt $geraet deklarieren und nutzen?

Man kann keine Variablen als Triggerinformation nutzen.

statt

'fhem("setreading $geraet gesperrt 0")'

definierten:

"fhem('setreading $geraet gesperrt 0')"

damit $geraet vor der Ausführung ausgewertet wird und nicht erst danach - das ist eine Perleigenschaft.

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

spi3845

#257
Zitat von: Damian am 10 März 2022, 14:27:51
Man kann keine Variablen als Triggerinformation nutzen.
Ja, das hatte ich irgendwo schon gesehen und es hat auch nicht geklappt. Hatte gehofft, es gibt inzwischen einen Workaround. Danke aber für die Info!

Zitat von: Damian am 10 März 2022, 14:27:51
statt

'fhem("setreading $geraet gesperrt 0")'

definierten:

"fhem('setreading $geraet gesperrt 0')"

damit $geraet vor der Ausführung ausgewertet wird und nicht erst danach - das ist eine Perleigenschaft.

Danke! Der Teufel steckt im Detail. Es könnte so einfach sein, wenn es nur eine Art von Klammern und Anführunsgzeichen gäbe  8)


jkriegl

Nutze den di_counter, möchte aber gerne den Timer auf vor Mitternacht ändern.
Dazu muss in midnight_.* if ($mday==1) geändert werden.
Den Ultimo+1, also ist der nächste Tag der erste?, bekomme ich mit
defmod next_day DOIF ([20:10:30] ) (setReading test_ultimo day {(strftime('%e', localtime+86400))})
Mir gelingt es nicht die obige if-Abfrage durch das Ermitteln des ultimo+1 ($mday) im TPL zu ersetzen.
   if ((strftime("%e", localtime+86400)==1)) {
     set_Reading ("$3_last_month", get_Reading("$3_month",0),1);
     set_Reading ("$3_month",0,1);
   }
Rpi 3, Fhem, Cul 868, HM-CC-RT-DN, HM-Sec-Sco, HM-ES-PMSw1-Pl, ebus (Vaillant), ECMD, Telegram, HTTPMOD, Xiaomi, Shelly

Damian

Du könntest den Aufruf so anpassen:

Zitatmid {[23:59];;                          ## Sicherung der Daten um Mitternacht\
  for (my $i=0;;$i<@{$_counter};;$i++) { ## Für jeden Zähler wird die Funktion midnight aufgerufen\
    midnight($_counter[$i][0],$_counter[$i][1],strftime("%e", localtime+120,strftime("%Y", localtime+120);;\
  }\
}\
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

jkriegl

Vielen Dank.
Das obige next_day DOIF funktioniert sowieso nicht.
Ermittle über ein at, ob es sich um den Ultimo handelt und schreibe das Ergebnis in ein Reading, das ich im TPL_counter abfrage.
Übrigens gibt es ein at_ultimo at.
Rpi 3, Fhem, Cul 868, HM-CC-RT-DN, HM-Sec-Sco, HM-ES-PMSw1-Pl, ebus (Vaillant), ECMD, Telegram, HTTPMOD, Xiaomi, Shelly

twinFHEM

#261
Hallo zusammen,

ich habe folgenden Perl-Code in einem DOIF:

defmod DI_countdowndVerbrauchTempGes DOIF {if (([savergy_actions:timerdVerbrauchTempGes] > 0) and ([+00:00:05] and [?savergy_actions:timerdVerbrauchTempGes:sec] < 5)) {\
my $c=ReadingsVal("savergy_actions","counterMeldungen",0) + 1;fhem("setreading savergy_actions counterMeldungen $c");\
my $min=ReadingsVal("savergy_actions","timerdVerbrauchTempGes",0) * 60;\
my $diffNow=ReadingsVal("savergy_actions","dVerbrauchTempDiff",0);\
\
set_Exec("TimerLog".$c,$min,'fhem{Log 1, "Timer".$c." zuende!"}');\
set_Exec("Timer".$c,$min,'fhem("setreading savergy_actions dVerbrauchTempDiff ".ReadingsVal("savergy_actions","dVerbrauchTempGes",0) - $diffNow."")');\
}}\


Mit my werden 3 lokale Variablen deklariert. Nach Ablauf des internen Timer, gestartet mit set_Exec, bekomme ich folgende Fehlermeldungen:

1:DI_countdowndVerbrauchTempGes error in fhem{Log 1, "Timer".$c." zuende!"}: Global symbol "$c" requires explicit package name (did you forget to declare "my $c"?) at (eval 18257) line 1.

1:DI_countdowndVerbrauchTempGes error in fhem("setreading savergy_actions dVerbrauchTempDiff ".ReadingsVal("savergy_actions","dVerbrauchTempGes",0) - $diffNow.""): Global symbol "$diffNow" requires explicit package name (did you forget to declare "my $diffNow"?) at (eval 18258) line 1.


Allerdings habe ich sie doch deklariert!? Und für $min taucht keine Fehlermeldung auf.
Kann mir das einer erklären?

Ich hatte noch die Vermutung, dass es an den Anführungszeichen liegt und habe es probiert mit

set_Exec("TimerLog".$c,$min,"fhem{Log 1, 'Timer'.$c.' zuende!'}");


Hier bekomme ich dann folgende Meldung:

1:PERL WARNING: String found where operator expected at (eval 19115) line 1, near "27.' zuende!'"
1:PERL WARNING: (Missing operator before ' zuende!'?)
1:DI_countdowndVerbrauchTempGes error in fhem{Log 1, 'Timer'.27.' zuende!'}: syntax error at (eval 19115) line 1, near "27.' zuende!'"


Ich taste mich gerade an den Umgang mit Perl-Code in FHEM heran.
Ab wann macht es eurer Meinung nach Sinn, den Code in eine bzw. die 99_myUtils auszulagern?

Damian

Das ist ganz einfach, wenn man die Eigenschaften und Tücken von Perl kennt.

Mit

'fhem{Log 1, "Timer".$c." zuende!"}'

übergibst du den Code mit $c an set_Exec. In set_Exec ist aber $c nicht bekannt.

mit

"fhem{Log 1, 'Timer $c zuende!'}"

wird dagegen $c aufgelöst bevor es an set_Exec übergeben wird, daher wird das funktionieren :)
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

twinFHEM

Danke Damian, passt natürlich! :)

Eigenwilliges Feature von PERL...
Aber ich glaube, wir werden Freunde... :D

Übrigens; ein sehr geiles Modul!!!

tobelix

Zitat von: Damian am 11 Juni 2020, 09:50:48Längere Definitionen würde ich in eine externe Datei auslagern (myutils-sonstwas, mit package DOIF), die man mit einem vernünftigen Programm-Editor bearbeiten kann.


Hi Damian, hättest du hierzu vielleicht zwei Code Snippets was im DOIF angegeben werden muss und wie es in der myutils Datei stehen muss damit der Codeblock entsprechend aufgerufen wird?

Damian

in myUtils:

package DOIF;

sub bla {
...
}

in DOIF z. B. um 8:00 Uhr bla-Routine aus myUtils aufrufen

DOIF {[08:00];bla (...)}


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

tobelix

Danke. Wie kann ich das Debuggen?

Im DOIF wird zwar angezeigt "block_01 excecuted". Aber es passiert nichts.
verbose auf 5 setzen im DOIF führt auch nicht dazu, dass im Log eine Fehlermeldung eingetragen wird.

Damian

Debuggen in FHEM ist schwierig.

Wenn die Routine nicht gefunden wird, dann gibt es eine Fehlermeldung im Reading  block_01

Ich habe es ohne Probleme bei mir getestet:

In 99_myUtils.pm über Edit-Files eingegeben:

###############################################################################
  #
  #  Consume a string with lines like: Timestamp: value
  #  return HTML to show the history visually
  #
  ###############################################################################
package DOIF;

sub doif_test {

set_State("30");

}

package main; 

...

und in DOIF

defmod doif_extern DOIF {doif_test()}
Der Status wird durch Ausführen von block_01 auf 30 gesetzt.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

RalfRog

Hallo
Ich habe mal "aus dem Kopf" ein OldReadingsAge im DOIF eingebaut. Das läuft natürlich auf Fehler - kein Wunder, ist ja in der Doku zu finden:
Folgende FHEM-Perlfunktionen wurden ebenfalls im DOIF-Namensraum definiert, sie können, wie gewohnt ohne Doppelpunkt genutzt werden:

fhem, Log, Log3, InternVal, InternalNum, OldReadingsVal, OldReadingsNum, OldReadingsTimestamp, ReadingsVal, ReadingsNum, ReadingsTimestamp, ReadingsAge, Value, OldValue, OldTimestamp, AttrVal, AttrNum

Hier war es auch schon im Beitrag #84 erwähnt.

Über ::OldReadingsAge kann man es sicher im Namensraum main ausführen - muss ich noch probieren.

 ;)  Gibt es einen speziellen Grund, dass es nicht im DOIF-Namensraum definiert wurde?

GRuß Ralf
FHEM auf Raspi 2B mit nanoCUL, HM-MOD-RPI-PCB und über LAN MAX!Cube mit a-culFW (Stack 868 + 433)
HM- Fensterkontakte, UP-Schalter, Bewegungsmelder und ein Rauchmelder

Damian

Zitat von: RalfRog am 09 Juli 2023, 15:59:44Gibt es einen speziellen Grund, dass es nicht im DOIF-Namensraum definiert wurde?

War vermutlich damals in der WIKI-Liste der FHEM-Funktionen, wo ich nachgeschaut habe, nicht drin. Die Funktion kann ich aber beim nächsten Update aufnehmen.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF