Korrekte Syntax FHEM-Befehl in Perl im ...notify... in myUtils auslagern

Begonnen von TomLee, 10 Juli 2020, 12:34:40

Vorheriges Thema - Nächstes Thema

TomLee

Zitat
ja, das ist hier wirklich nichts mehr, was bei den Anfängerfragen gut aufgehoben ist...)
PS: Interessantes script, aber auf welcher Seite soll die Lösung stehen ;) ?

Um im richtigen Forumbereich zu posten versuche ich mich mit 'Tester' anzufreunden, warm werde ich aber nicht wirklich damit.




Hast du den Code getestet oder ist der aus dem Kopf ?

Zum nachzuvollziehen weshalb es noch nicht klappt möcht ich wissen ob ref $sr2cmnd->{$sr} wirklich CODE zurückgibt.

In Eclipse bekomme ich da zurück:

Can't return outside a subroutine at /home/tom/eclipse-workspace/First_Project/bla.pl line 15.

mit:

use strict;
    use warnings;
    use 5.010;
   
my $NAME = qq(bla);
my $echo = qq(bla1);
my $sr = qq(8);
my $sound = qq(set $echo sounds Glocken);
my $a3 = sub { my $r = qx(system ('/opt/fhem/vouchergzg.sh &)); $r .= ";".fhem($sound); return $r};

my $sr2cmnd = {
8 => \&$a3
};
my $ret;
return ref $sr2cmnd->{$sr};
#return $a3; <- damit auch





Bist dir sicher das das so klappen sollte ?

Beta-User

Zumindest auf meinem Testsystem (Win32@strawberryperl 5.32.1) kommt mit genau meinem Code was sinnvolles zurück, allerdings sieht das etwas anders aus als das, was ich gestern von meinen Linux-basierten 5.28-System her kannte ;) .

Versuch's mal damit:

my $NAME = qq(bla);
my $echo = qq(bla1);
my $sr = qq(8);
my $sound = q(set $echo sounds Glocken);
my $a3 = sub { qx(system ('/opt/fhem/vouchergzg.sh &')); fhem($sound);};

my $sr2cmnd = {
    8 => \&$a3
};
return $sr2cmnd->{$sr} if ref $sr2cmnd->{$sr} eq 'CODE';
return;
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

TomLee

Gleiches Ergebnis:

    use strict;
    use warnings;
    use 5.010;
   
my $NAME = qq(bla);
my $echo = qq(bla1);
my $sr = qq(8);
my $sound = qq(set $echo sounds Glocken);
my $a3 = sub { qx(system ('/opt/fhem/vouchergzg.sh &')); fhem($sound);};

my $sr2cmnd = {
    8 => \&$a3
};
return $sr2cmnd->{$sr} if ref $sr2cmnd->{$sr} eq 'CODE';
return;

Can't return outside a subroutine at /home/tom/eclipse-workspace/First_Project/bla.pl line 14.



Warum hast das jetzt geändert ?
my $sound = q(set $echo sounds Glocken);

Dann wird doch $echo nicht mehr aufgelöst ?



Beta-User

Doch, sollte schon aufgelöst werden.

Nur eben erst bei der Ausführung ;) .

Aber du hast mich drausgebracht, qx(system... ist natürlich Quark, und wo das genau eigebunden ist, wird aus dem Schnipsel leider auch nicht so klar...
Und der echte Name des Echo sollte schon dastehen.
Alle 3 ref-Codes sollten im Ergebnis dasselbe tun, testen kann ich nur leider nicht.

my $NAME = qq(bla);
my $echo = qq(bla1);
my $sr = qq(;
my $sound = q(fhem("set $echo sounds Glocken"));
my $sound2 = q(set $echo sounds Glocken);
my $a3 = sub { qx('/opt/fhem/vouchergzg.sh &'); $sound;};
my $a3a = sub { qx('/opt/fhem/vouchergzg.sh &'); fhem($sound2);};
my $a4 = sub { qx('/opt/fhem/vouchergzg.sh &'); fhem("set $echo sounds Glocken");};
my $sr2cmnd = {
   2 => \&$a4,
   4 => \&$a3a,
   8 => \&$a3
};
return $sr2cmnd->{$sr} if ref $sr2cmnd->{$sr} eq 'CODE';
return;
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

TomLee

Nee, kann jetzt auch 2-3 Stunden nicht danach schauen.

sub cube {
my $NAME = shift;
my $echo = shift;
my $sr = ReadingsNum($NAME,'side',0);
my $sound = q(fhem("set $echo sounds Glocken"));
my $sound2 = q(set $echo sounds Glocken);
my $a3 = sub { qx('/opt/fhem/vouchergzg.sh &'); $sound;};
my $a3a = sub { qx('/opt/fhem/vouchergzg.sh &'); fhem($sound2);};
my $a4 = sub { qx('/opt/fhem/vouchergzg.sh &'); fhem("set $echo sounds Glocken");};
my $sr2cmnd = {
0 => \&$a4,
1 => \&$a3a,
2 => \&$a3
};
return $sr2cmnd->{$sr} if ref $sr2cmnd->{$sr} eq 'CODE';
return;
}


Im Log steht bei den 3 verschiedenen Codes (Keys):

2021.03.01 17:27:34 3: not_MQTT2_Cube return value: CODE(0x8541608)
2021.03.01 17:29:06 3: not_MQTT2_Cube return value: CODE(0x85980d0)
2021.03.01 17:29:34 3: not_MQTT2_Cube return value: CODE(0x7b83208)

Beta-User

versuch's mal so:
return $sr2cmnd->{$sr}->() if ref $sr2cmnd->{$sr} eq 'CODE';
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

TomLee

Der Aufruf des Shellscript klappt mit qx nicht, auch nicht aus der Kommandozeile.

Mit system schon :

sub cube {
my $NAME = shift;
my $echo = shift;
my $sr = ReadingsNum($NAME,'side',0);
my $sound2 = qq(set $echo sounds Glocken);
my $a1 = sub { system('/opt/fhem/vouchergzg.sh &');fhem("$sound2");};
my $a2 = sub { system('/opt/fhem/vouchergzg1.sh &');fhem("$sound2");};
my $a3 = sub { system('/opt/fhem/voucher.sh &');fhem("$sound2");};
my $a4 = sub { system('/opt/fhem/voucher21.sh &');fhem("$sound2")};;

my $sr2cmnd = {
0 => \&$a1,
1 => \&$a2,
2 => \&$a3,
4 => \&$a4
};
return $sr2cmnd->{$sr}->() if ref $sr2cmnd->{$sr} eq 'CODE';
return;
}


Die Variante klappt auch:

sub { system('/opt/fhem/vouchergzg1.sh &');fhem("set $echo sounds Glocken")}

Was nicht klappen will ist $sound einfach anzuhängen


my $sound = q(fhem('set OG_Echo_Wohnzimmer sounds Glocken'));
sub { system('/opt/fhem/vouchergzg1.sh &');$sound}


Ob in qq,q,mit $echo Variable,einfachen oder doppelten Hochkommata im fhem-Befehl, es klappt nicht.

Meine favorisierte Lösung wär jetzt den fhem-Befehl in den subs wegzulassen und dafür im return anzuhängen, bspw:

sub cube {
my $NAME = shift;
my $echo = shift;
my $sr = ReadingsNum($NAME,'side',0);
my $sound2 = qq(set $echo sounds Glocken);
my $a1 = sub { system('/opt/fhem/vouchergzg.sh &');};
my $a2 = sub { system('/opt/fhem/vouchergzg1.sh &');};
my $a3 = sub { system('/opt/fhem/voucher.sh &');};
my $a4 = sub { system('/opt/fhem/voucher21.sh &');};;

my $sr2cmnd = {
0 => \&$a1,
1 => \&$a2,
2 => \&$a3,
4 => \&$a4
};
return $sr2cmnd->{$sr}->().fhem("$sound2") if ref $sr2cmnd->{$sr} eq 'CODE';
return;
}


Klappt aber nicht, dann wird bei jedem Key immer $a1 ausgeführt.

Otto123

Zitat von: TomLee am 02 März 2021, 16:29:02

Was nicht klappen will ist $sound einfach anzuhängen


my $sound = q(fhem('set OG_Echo_Wohnzimmer sounds Glocken'));
sub { system('/opt/fhem/vouchergzg1.sh &');$sound}

Ich weiß ihr fandet meinen Einwand mit eval irgendwie eklig. Aber das Konstrukt oben kann mMn nicht funktionieren! Da wir der Inhalt der Variablen ausgegeben als Text!

my $sound = q(fhem('set OG_Echo_Wohnzimmer sounds Glocken'));
sub { system('/opt/fhem/vouchergzg1.sh &');eval $sound}
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Beta-User

Wenn immer der lookup nach "0" gemacht wird: Sicher, dass ReadingsNum das erwartete Ergebnis bringt?

eval ist eklig; aber auch $sound sollte eine anonyme sub werden können... Ungetestet:
my $sound = sub {fhem('set OG_Echo_Wohnzimmer sounds Glocken')};
sub { system('/opt/fhem/vouchergzg1.sh &'); $sound->()}
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

TomLee

Zitataber auch $sound sollte eine anonyme sub werden können...

Korrekt.

Ich hoffe hab nix übersehen, ich mein alles klappt, für die Zukunft:

sub cube {
my $NAME = shift;
my $echo = shift;
my $sr = ReadingsNum($NAME,'side',0);
my $sound = sub {fhem("set $echo sounds Glocken")};
my $a1 = sub { system('/opt/fhem/vouchergzg.sh &')};
my $a2 = sub { system('/opt/fhem/vouchergzg1.sh &')};
my $a3 = sub { system('/opt/fhem/voucher.sh &')};
my $a4 = sub { system('/opt/fhem/voucher21.sh &');};

my $sr2cmnd = {
0 => \&$a1,
1 => \&$a2,
2 => \&$a3,
4 => \&$a4
};
return $sr2cmnd->{$sr}->().$sound->() if ref $sr2cmnd->{$sr} eq 'CODE';
return;
}


DANKE (auch für die Geduld)

Otto123

Zitat von: Beta-User am 02 März 2021, 16:47:02
eval ist eklig; aber auch $sound sollte eine anonyme sub werden können... Ungetestet:
my $sound = sub {fhem('set OG_Echo_Wohnzimmer sounds Glocken')};
sub { system('/opt/fhem/vouchergzg1.sh &'); $sound->()}

Ich würde ja gerne noch wissen warum? Kürzer ist es ja auch nicht? Schöner - ist relativ? ;)
Was ist das Problem von eval und Vorteil dieser anonymen sub?
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Beta-User

Das "Problem" von eval ist, dass es dazu gedacht ist rauszufinden, ob Code funktioniert oder Fehler wirft.

Diese Art "Hosenträger" macht bei Code eigentlich keinen Sinn, von dem man weiß, dass er "immer" funktioniert (z.B., weil "fhem" seinerseits einen "Hosenträger" dranmacht...)

Meine Interpretation des perlcritic-Rückmeldung ist die: eval nur dann, wenn einen interessiert, ob Fehler aufgetreten sind. Und prinzipell: weg damit, wenn möglich...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

Otto123

Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

frober

Bevor ich auch einen Thread im Anfängerbereich bzgl. Perlcritic aufmache, hänge ich mich mal hier rein. Ich hoffe das passt.

Meine myUtils habe ich mal getestet, witzigerweise waren die größeren Codes alle ok, bis auf die prototypes 'sub', die aber schon in der Vorlage sind.

Bemängelt wurde hier 2x das open:
Zitatpackage main;

use strict;
use warnings;

sub
myUtils_Logdatei_Initialize($$)
{
  my ($hash) = @_;
}

# Logdatei zum debuggen
#
# $file = name.log;
# debuglog("blabla",$file);

sub debuglog($$) {

  my ($myState, $file) = @_;
  my $fileName = "/opt/fhem/log/$file";
   
   if($file eq "") {$file = "unnamed.log"};
   if(open (DATEI, ">> $fileName")) {
   print (DATEI Zeitstempel().$myState."\n");
   close (DATEI);
       }
      else
      {
       return "Can't open $fileName: $!";
      }
}
1;

Ich habe das dann so gelöst:
my $Datei = DATEI;  # Filehandler zuweisung in Variable
.
.
.
if(open ($Datei, '>>',  $fileName)) {


Perlcritic war zufrieden, nun mosert aber Fhem:
ZitatERROR:
Bareword "DATEI" not allowed while "strict subs" in use at ./FHEM/99_myUtils_Logdatei.pm line 26

Wenn ich das richtig verstehe, dann darf ich den Filehandler in der sub keiner Variablen zuweisen und nun?

Gruß und Danke
Bernd
Raspi 3b mit Raspbian Bullseye und relativ aktuellem Fhem,  FS20, LGW, PCA301, Zigbee, MQTT, MySensors mit RS485(CAN-Receiver) und RFM69, etc.,
einiges umgesetzt, vieles in Planung, smile

********************************************
...man wächst mit der Herausforderung...

Otto123

Hallo Bernd,

aus meiner Sicht sitzt Du auf dem falschen Pferd
https://metacpan.org/pod/Perl::Critic::Policy::InputOutput::ProhibitTwoArgOpen

Tipp Wenn Du das Buch nicht hast führt dieser String zum Ziel : "perlcritic Two-argument "open" used"

Wenn ich das richtig verstehe, dann darf ich den Filehandler in der sub keiner Variablen zuweisen und nun?
Nein Du darfst nicht einfach DATEI zuweisen, ein String ginge 'DATEI' aber wie gesagt, dass ist es sicher nicht was perlcritic bemängelt. Der will

(DATEI, ">>","$fileName")

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz