FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: TomLee am 24 Juli 2021, 12:54:46

Titel: [geklärt] split von $EVENT im notify
Beitrag von: TomLee am 24 Juli 2021, 12:54:46
Hallo,

gegeben ist folgender dummy, damit kann ich ein Reading Test setzen das keinen Inhalt hat (wenn zuvor was in dem Reading drin stand sonst ergibt der setter undefined)

defmod Demo dummy
attr Demo readingList Test
attr Demo room Test
attr Demo setList Test:noArg

setstate Demo Test Test1
setstate Demo 2021-07-24 12:17:36 Test


und ein notify:

defmod Demo_notify_1 notify Demo:Test:.* {my $ec = split(': ','$EVENT');;\
Log3(undef, 3, "Das ist $EVENT und $ec");;}


Wenn ich jetzt den setter Test ausführe steht im Log:
Zitat
2021.07.24 12:30:40 3: Das ist Test:  und 1

das deckt sich auch mit:

{my $ec = split(': ','Test: ');; return $ec;;}

aus der Kommandozeile, ergibt auch 1.

Führe ich ein

setreading Demo Test Test1

aus steht im Log:

2021.07.24 12:34:54 3: Das ist Test: Test1 und 1

in der Kommandozeile:

{my $ec = split(': ','Test: Test1');; return $ec;;}

aber 2.

Was mach ich hier falsch in dem notify/was übersehe ich/was hab ich nicht verstanden ?

Und es ist mir egal wieviele EVTPARTx es geben könnte, möchte nur eine Fallunterscheidung ob ein EVTPART1 existiert oder nicht erreichen.


Weitere Frage:

Nehme ich in dem notify eine Bedingung mit rein (jetzt mal unabhängig davon das wie oben gezeigt im notify immer 1 als Anzahl zurückkommt):

defmod Demo_notify_1 notify Demo:Test:.* {my $ec = split(': ','$EVENT');;\
return if $ec == '1';;\
set OG_Echo_Wohnzimmer speak bla;;
Log3(undef, 3, "Das ist $EVENT und $ec");;}


erfolgt wie erwartet wegen dem return nix keine Ausführung des Befehls oder der Logausgabe.

Ändere ich in dem obigen Beispiel die Sprachausgabe zu $EVTPART1

defmod Demo_notify_1 notify Demo:Test:.* {my $ec = split(': ','$EVENT');;\
return if $ec == '1';;\
set OG_Echo_Wohnzimmer speak $EVTPART1;;
Log3(undef, 3, "Das ist $EVENT und $ec");;}


erfolgt wie erwartet keine Sprachausgabe und Logausgabe, es kommt aber zu folgender Meldung im Log:

2021.07.24 12:47:29 1: ERROR evaluating my $EVENT=   $evalSpecials->{'%EVENT'};my $EVTPART0=   $evalSpecials->{'%EVTPART0'};my $NAME=   $evalSpecials->{'%NAME'};my $SELF=   $evalSpecials->{'%SELF'};my $TYPE=   $evalSpecials->{'%TYPE'};{my $ec = split(': ','$EVENT');
return if $ec == '1';
set OG_Echo_Wohnzimmer speak $EVTPART1;
Log3(undef, 3, "Das ist $EVENT und $ec");}: Global symbol "$EVTPART1" requires explicit package name (did you forget to declare "my $EVTPART1"?) at (eval 125142) line 3.

2021.07.24 12:47:29 3: Demo_notify_1 return value: Global symbol "$EVTPART1" requires explicit package name (did you forget to declare "my $EVTPART1"?) at (eval 125142) line 3.


Es sollte nach dem return nix doch eigentlich auch nix mehr passieren, warum nimmt das notify aber trotzdem eine "Auswertung" von $EVTPART1 vor ?

Gruß

Thomas
Titel: Antw:split von $EVENT im notify
Beitrag von: JensS am 24 Juli 2021, 13:12:22
Bei notify im Zusammenhang mit dummy hatte ich kürzlich ebenfalls ein seltsames Phänomen.
Aus einem Modul heraus wurde bei verschiedenen Devicetypen (Zigbee2MQTT, GHoma, FRM_OUT) mit "set <device> on" ein Event ausgelöst, beim Typ dummy aber nicht.
https://forum.fhem.de/index.php/topic,119447.msg1167212.html#msg1167212 (https://forum.fhem.de/index.php/topic,119447.msg1167212.html#msg1167212)
Sorry, wenn das dein Topic nicht direkt betrifft aber vielleicht gibt es einen Zusammenhang.

Gruß Jens
Titel: Antw:split von $EVENT im notify
Beitrag von: betateilchen am 24 Juli 2021, 13:13:00
Zitat von: TomLee am 24 Juli 2021, 12:54:46
Und es ist mir egal wieviele EVTPARTx es geben könnte, möchte nur eine Fallunterscheidung ob ein EVTPART1 existiert oder nicht erreichen.

Warum prüfst Du dann im notify nicht einfach auf $EVTPART1?


defmod demo_notify_1 notify demo:Test:.* {no strict;;return unless $EVTPART1;;Debug $EVTPART1;;}
Titel: Antw:split von $EVENT im notify
Beitrag von: Christoph Morrison am 24 Juli 2021, 13:49:23
Hallo Thomas,

Zitat von: TomLee am 24 Juli 2021, 12:54:46
Wenn ich jetzt den setter Test ausführe steht im Log:
das deckt sich auch mit:

{my $ec = split(': ','Test: ');; return $ec;;}

aus der Kommandozeile, ergibt auch 1.

Führe ich ein

setreading Demo Test Test1

aus steht im Log:

2021.07.24 12:34:54 3: Das ist Test: Test1 und 1

in der Kommandozeile:

{my $ec = split(': ','Test: Test1');; return $ec;;}

aber 2.

Zitat von: https://perldoc.perl.org/functions/splitSplits the string EXPR into a list of strings and returns the list in list context, or the size of the list in scalar context. (Prior to Perl 5.11, it also overwrote @_ with the list in void and scalar context. If you target old perls, beware.)

Du splittest einen String in ein bzw. zwei Listenelemente und sagst Perl, dass du das Ergebnis im skalaren Kontext haben willst → du erhältst die Anzahl der Elemente in der Liste, korrekterweise also 1 oder 2.


> perl -MData::Dumper -e '@p = split(q(: ),q(Test: Test1)); print Dumper(\@p)'
$VAR1 = [
          'Test',
          'Test1'
        ];

❯ perl -MData::Dumper -e '@p = split(q(: ),q(Test: )); print Dumper(\@p)'
$VAR1 = [
          'Test'
        ];


ZitatWeitere Frage:
Es sollte nach dem return nix doch eigentlich auch nix mehr passieren, warum nimmt das notify aber trotzdem eine "Auswertung" von $EVTPART1 vor ?

Der Code wird komplett übersetzt (dabei auf Fehler untersucht) und dann erst ausgeführt, wenn use strict verwendet wird.

❯ perl -e 'sub foo { return; print $not_declared}; foo()'

$not_declared existiert nicht, use strict ist nicht gesetzt -> keine Fehlermeldung, es passiert einfach gar nichts.

❯ perl -Mstrict -e 'sub foo { return; print $not_declared}; foo()'
Global symbol "$not_declared" requires explicit package name (did you forget to declare "my $not_declared"?) at -e line 1.
Execution of -e aborted due to compilation errors..


Boing. Deshalb verwendet betateilchen auch das no strict-Pragma, aber:


❯ perl -e '$t = 0; print q(wahr) unless $t'
wahr


Problematisch wird es, wenn $EVTPART1 mal 0 ist, denn unless 0 ist wahr. Besser ist defined.

ZitatUnd es ist mir egal wieviele EVTPARTx es geben könnte, möchte nur eine Fallunterscheidung ob ein EVTPART1 existiert oder nicht erreichen.

no strict; return if defined $EVTPART1

Titel: Antw:split von $EVENT im notify
Beitrag von: betateilchen am 24 Juli 2021, 13:56:09
Zitat von: TomLee am 24 Juli 2021, 12:54:46
my $ec = split(': ','$EVENT');

Was mach ich hier falsch in dem notify/was übersehe ich/was hab ich nicht verstanden ?

split liefert ein array zurück, also müsste es besser "my @ec" heißen und nicht "my $ec".
Man kann auch an ein scalar zuweisen, dann muss man aber wissen, was man tut und was das Ergebnis sein wird.

Übrigens: die einfachen Anführungszeichen um $EVENT sind nicht nur überflüssig, sondern falsch.

----

Edit: ok, Christoph hat die lange Version meiner Antwort geliefert :)
Titel: Antw:split von $EVENT im notify
Beitrag von: TomLee am 24 Juli 2021, 13:59:20
An dem Vorschlag hakt was.

Mit keinem Wert in dem Reading Test und diesem
defmod Demo_notify_1 notify Demo:Test:.* {no strict;;return unless $EVTPART1;;set OG_Echo_Wohnzimmer speak bla;;}

erfolgt keine Sprachausgabe und dem no script keine Meldung im Log, gut.

Mach ich ein setreading Demo Test Test1 steht im Log:

2021.07.24 13:54:47 1: ERROR evaluating my $EVENT=   $evalSpecials->{'%EVENT'};my $EVTPART0=   $evalSpecials->{'%EVTPART0'};my $EVTPART1=   $evalSpecials->{'%EVTPART1'};my $NAME=   $evalSpecials->{'%NAME'};my $SELF=   $evalSpecials->{'%SELF'};my $TYPE=   $evalSpecials->{'%TYPE'};{no strict;return unless $EVTPART1;set OG_Echo_Wohnzimmer speak bla;}: Can't locate object method "speak" via package "bla" (perhaps you forgot to load "bla"?) at (eval 131955) line 1.

2021.07.24 13:54:47 3: Demo_notify_1 return value: Can't locate object method "speak" via package "bla" (perhaps you forgot to load "bla"?) at (eval 131955) line 1.
Titel: Antw:split von $EVENT im notify
Beitrag von: TomLee am 24 Juli 2021, 14:02:31
Ich war am schreiben, muss mich mit den letzten zwei Beiträgen noch beschäftigen.
Titel: Antw:split von $EVENT im notify
Beitrag von: betateilchen am 24 Juli 2021, 14:04:47
Zitat von: TomLee am 24 Juli 2021, 13:59:20
defmod Demo_notify_1 notify Demo:Test:.* {no strict;;return unless $EVTPART1;;set OG_Echo_Wohnzimmer speak bla;;}

Du vermischt perl Code und FHEM Befehl, das kann so nicht funktionieren.

Probier mal:

defmod Demo_notify_1 notify Demo:Test:.* {no strict;;return unless $EVTPART1;;fhem("set OG_Echo_Wohnzimmer speak bla");;}

Du scheiterst mal wieder an absoluten FHEM Basics...  8)
Titel: Antw:split von $EVENT im notify
Beitrag von: TomLee am 24 Juli 2021, 14:10:48
ZitatDu scheiterst mal wieder an absoluten FHEM Basics...

::)
Titel: Antw:split von $EVENT im notify
Beitrag von: TomLee am 24 Juli 2021, 14:25:27
ZitatÜbrigens: die einfachen Anführungszeichen um $EVENT sind nicht nur überflüssig, sondern falsch.

Ich weiß, das hab ich mittleweile inne, mehre Codestücke oben waren auch einfach zusammenkopiert (aus dem Kopf), weil ich den ganzen Text schon fertig hatte, mich neu anmelden musste und alles wieder weg war.

Übrigens heute bist ein Spatz, mein Spatz  :P

Danke.
Titel: Antw:split von $EVENT im notify
Beitrag von: Christoph Morrison am 24 Juli 2021, 14:32:56
Zitat von: betateilchen am 24 Juli 2021, 13:56:09
Übrigens: die einfachen Anführungszeichen um $EVENT sind nicht nur überflüssig, sondern falsch.

Das hier ist auch Käse:
Zitatreturn if $ec == '1';;\

Entweder in $ec is ein String, dann braucht man eq. Oder in $ec ist eine Zahl, dann braucht man keine Quotes um die 1.
Titel: Antw:split von $EVENT im notify
Beitrag von: Beta-User am 24 Juli 2021, 14:55:58
$EVTPARTn ist doch - afair - auch nur das Ergebnis aus einem split... Warum das dann nicht im Code selbst durch einen passenderen split so machen, wie man es braucht?

Bzgl. des anderen Threads würde ggf. einfach ein Punkt mehr reichen um sicher zu sein, dass part1 existiert.
Titel: Antw:split von $EVENT im notify
Beitrag von: TomLee am 24 Juli 2021, 15:21:19
Was ich jetzt nicht verstehe, das es mit return if defined $EVTPART1 zu der Meldung unten kommt beim löschen der Einkaufsliste und mit return unless $EVTPART1 keine kommt, habs jetzt so verstanden das das mit no strict in beiden Fällen abgefangen werden sollte.
Ich habs mehrfach getestet bevor ich hier Mist schreibe.

defmod not_Echo_Einkaufsliste notify Echo:list_SHOPPING_ITEM:.* {no strict;;\
return if defined $EVTPART1;;\
#return unless $EVTPART1;;\
return FileWrite({ FileName=>"/opt/fhem/einkaufsliste.txt", ForceType=>"file", NoNL => 0},split(/\,/,$EVTPART1));;}


2021.07.24 15:13:33 1: PERL WARNING: Use of uninitialized value $EVTPART1 in split at (eval 140328) line 4.
2021.07.24 15:13:33 3: eval: my $EVENT=   $evalSpecials->{'%EVENT'};my $EVTPART0=   $evalSpecials->{'%EVTPART0'};my $NAME=   $evalSpecials->{'%NAME'};my $SELF=   $evalSpecials->{'%SELF'};my $TYPE=   $evalSpecials->{'%TYPE'};{no strict;
return if defined $EVTPART1;
#return unless $EVTPART1;
return FileWrite({ FileName=>"/opt/fhem/einkaufsliste.txt", ForceType=>"file", NoNL => 0},split(/\,/,$EVTPART1));}
Titel: Antw:split von $EVENT im notify
Beitrag von: Beta-User am 24 Juli 2021, 15:34:19
evalSpecials wird ausgeführt, bevor no strict greifen kann... => selber splitten und in Variablen packen...

EDIT: via evalSpecials kann auch nur ersetzt werden, was da ist... Die restlichen Variablen bleiben stehen.
Titel: Antw:split von $EVENT im notify
Beitrag von: betateilchen am 24 Juli 2021, 15:37:36
Zitat von: Beta-User am 24 Juli 2021, 15:34:19
=> selber splitten und in Variablen packen...

Spätestens jetzt geh ich mal Popcorn holen und genieße das weitere Showprogramm hier...
Titel: Antw:split von $EVENT im notify
Beitrag von: TomLee am 24 Juli 2021, 15:42:07
Manege frei:

OK, mal nachgedacht:

return if !defined $EVTPART1
Titel: Antw:split von $EVENT im notify
Beitrag von: TomLee am 25 Juli 2021, 13:36:02
Zitat von: betateilchen am 24 Juli 2021, 13:13:00
Warum prüfst Du dann im notify nicht einfach auf $EVTPART1?


defmod demo_notify_1 notify demo:Test:.* {no strict;;return unless $EVTPART1;;Debug $EVTPART1;;}


Nur aus Interesse, hat Debug noch weitere Parameter sowas wie Loglevel, ist es irgendwo dokumentiert, hab das hier das erste mal gesehen ?
Titel: Antw:[Freier Eintritt] split von $EVENT im notify
Beitrag von: Otto123 am 25 Juli 2021, 15:43:40
sowas und andere feine Tools findest Du hier https://wiki.fhem.de/wiki/DevelopmentModuleAPI#Debug
Titel: Antw:split von $EVENT im notify
Beitrag von: betateilchen am 25 Juli 2021, 16:06:20
Zitat von: TomLee am 25 Juli 2021, 13:36:02
Nur aus Interesse, hat Debug noch weitere Parameter sowas wie Loglevel

Nein, Debug($msg) ist nur ein quick&dirty Aufruf von 'Log 1, "DEBUG>" . $msg;' und hilfreich zum Testen.

Dokumentiert ist das primär in der fhem.pl
Titel: Antw:[Freier Eintritt] split von $EVENT im notify
Beitrag von: TomLee am 30 Juli 2021, 17:28:59
https://forum.fhem.de/index.php/topic,112785.msg1168079.html#msg1168079 (https://forum.fhem.de/index.php/topic,112785.msg1168079.html#msg1168079)
Titel: Antw:split von $EVENT im notify
Beitrag von: TomLee am 08 August 2021, 15:41:07
Zitat von: Christoph Morrison am 24 Juli 2021, 14:32:56
Das hier ist auch Käse:
Entweder in $ec is ein String, dann braucht man eq. Oder in $ec ist eine Zahl, dann braucht man keine Quotes um die 1.

Hier:

Zitatsub fb_cmp {
my $NAME = shift;
my $EVTPART0 = shift;
my $EVTPART1 = shift;
my $lgtvs = shift;
my $sonoswz = shift;
my $echok = shift;
my $sonosps = shift;
chop($EVTPART0);
$EVTPART1 =~ s/&/und/;
my $extn = ReadingsVal($NAME,'external_name','unbekannt');
my $extnr = ReadingsVal($NAME,'external_number','unbekannt');
my $intnr = ReadingsNum($NAME,'internal_number','unbekannt');
my $intc = ReadingsVal($NAME,'internal_connection','unbekannt');
my $mcr = ReadingsVal($NAME,'missed_call','unbekannt');
my $echodb = qq(set $echok sounds tuerklingel_3);

   if ($EVTPART1 eq "ring") {
   return fhem("set $sonoswz playSound 20 Vibrating") if $extn eq 'unknown';
   return fhem("set $sonoswz playSound 20 Fax-Beep;set $echok speak Fax Eingang") if $intnr == '999999';
   return fhem("set $sonoswz speak 20 Es ist $extn;set $echok speak Es ist $extn;set tb_TelegramBot msg Es ist: $extnr ($extn)");
   }
}

muss ich die Quotes verwenden, sonst klappts nicht, was hab ich hier jetzt nicht verstanden ?
Titel: Antw:[geklärt] split von $EVENT im notify
Beitrag von: frober am 08 August 2021, 16:12:16
Ich kann dir zwar deine Frage nicht beantworten, aber ich sehe ein anderes Problem:
Zitatmy $extn = ReadingsVal($NAME,'external_name','unbekannt')
.
.
.
return fhem("set $sonoswz playSound 20 Vibrating") if $extn eq 'unknown';
Titel: Antw:[geklärt] split von $EVENT im notify
Beitrag von: TomLee am 08 August 2021, 16:23:45
Glaub zwar nicht das jemals der Fall eintritt das der Ersatzwert genommen wird, werds aber anpassen, Danke.
Titel: Antw:[geklärt] split von $EVENT im notify
Beitrag von: Christoph Morrison am 08 August 2021, 17:52:12
Was heißt denn "sonst klappts nicht"?

Hast du mal debuggt, was in $intnr drin steht?
Titel: Antw:[geklärt] split von $EVENT im notify
Beitrag von: TomLee am 08 August 2021, 17:59:22
Was heißt denn "sonst klappts nicht"?

Der Zweig

return fhem("set $sonoswz playSound 20 Fax-Beep;set $echok speak Fax Eingang") if $intnr == '999999';

wird halt nie ausgeführt ohne Quotes.

Zitat
Hast du mal debuggt, was in $intnr drin steht?

Schon, im Eventmonitor und als debug-Ausgabe ins Log und meine Faxnummer kenne ich.
Titel: Antw:[geklärt] split von $EVENT im notify
Beitrag von: TomLee am 08 August 2021, 18:37:49
Sry, ich merke gerade das es auch ohne geht, nachdem ich noch eine Telegram-Message dazu genommen habe, hab ich wohl im Log nicht richtig geschaut gehabt.
Das verwirrende war das nie playsound abgespielt wurde, das hing wieder damit zusammen das ich normal mute wenn ein call ist und unmute wenn ein disconnect ist, da ich aber vor Monaten rumgetestet hatte und das muten bei einem call rausgenommen hatte erfolgte zufällig immer bei meinem testen heute keine Ausgabe. Und da ich mich wegen einem anderen Thema mehrmals selbst angerufen habe, bei mir aber immer eine Umleitung (also nach einem call dann nochmal ein call  erfolgt) war der Sonosplayer beim testen immer "gemuted". Schwierig zu erkären  ::) , beim Sonosplayer nutz ich halt nur einen setter für mute zum Statuswechsel, kein mute on / off.
if ($EVTPART1 eq "ring") {
return fhem("set $sonoswz playSound 20 Vibrating") if $extn eq 'unknown';
return fhem("set $sonoswz playSound 20 Fax-Beep;set $echok speak Fax Eingang;set tb_TelegramBot msg Faxeingang $extnr ($extn $intnr)") if $intnr == 999999;
return fhem("set $sonoswz speak 20 Es ist $extn;set $echok speak Es ist $extn;set tb_TelegramBot msg Es ist: $extnr ($extn)");
}