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

Super, jetzt muss ich mich zu einer Variante von dreien entscheiden, ...* , .{2,} oder !defined ?

Wenn keiner mehr was sagt entscheide ich mich wie meist für die kürzeste.

Beta-User

...die kürzeste dürfte Variante 4 sein: "..+"... ;)

Vielleicht eine generelle Anmerkung: Es ist hilfreich, wenn man auch nach Monaten (...) noch grob erkennen kann, ob etwas absichtlich so gemacht wurde, oder ob es ein potentieller Fehler war. Unter diesem Gesichtspunkt würde ich tendenziell was anderes der "...*"-Variante vorziehen.
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

frober

Danke, für die Erläuterung.

So ähnlich {3.1} habe ich es schon benutzt, um einen Pumpenlauf über die Leistung zu detektieren ~200.0W oder ~0.3W...da der Aktor immer "on" ist.
Raspi 3b mit Raspbian Buster 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...

TomLee

ZitatVielleicht eine generelle Anmerkung: Es ist hilfreich, wenn man auch nach Monaten (...) noch grob erkennen kann, ob etwas absichtlich so gemacht wurde, oder ob es ein potentieller Fehler war. Unter diesem Gesichtspunkt würde ich tendenziell was anderes der "...*"-Variante vorziehen.

Ich hatte mir einen Link schon zu dem anderen Thread in comment notiert und jetzt einen auf #134 hinzugenommen.

<a href="https://forum.fhem.de/index.php/topic,122196.msg1167670.html#msg1167670></a>
<a https://forum.fhem.de/index.php/topic,112785.msg1168108.html#msg1168108>bla</a>


Links mit HTML in comment darzustellen geht nicht, hab ich mal mitgenommen/mich mit beschäftigt, oder doch irgendwie ?

frober

Zitat von: TomLee am 28 Juli 2021, 16:50:06
Ich hatte mir einen Link schon zu dem anderen Thread in comment notiert und jetzt einen auf #134 hinzugenommen.

<a href="https://forum.fhem.de/index.php/topic,122196.msg1167670.html#msg1167670></a>
<a https://forum.fhem.de/index.php/topic,112785.msg1168108.html#msg1168108>bla</a>


Links mit HTML in comment darzustellen geht nicht, hab ich mal mitgenommen/mich mit beschäftigt, oder doch irgendwie ?

Ich hätte das direkt in der Perl- Funktion kommentiert, da hast du doch einen besseren Bezug. Kannst ja den Weblink mit einfügen.
Raspi 3b mit Raspbian Buster 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...

TomLee

Hey Beta-User,

kannst du bitte mal schauen, nur wegen dir hab ich schließlich den Code  :P ?

Warum kommt es zu der Meldung, von der Erklärung dazu versteh ich nur Bahnhof:

Subroutine "Nec32RemoteCodesHandlerFR" with high complexity score (21) at line 13, column 1. Consider refactoring.

package main;

use strict;
use warnings;

sub Remotes_Utils_Initialize {
  my $hash = shift//return;
  return;
}



sub Nec32RemoteCodesHandlerFR {
my $rcCode = shift // return;
my $frwl = shift;
my $kurl = shift;
my $kecho = shift;
my $dudev = shift;
my $echod = shift;
my $dudevstate = ReadingsVal($dudev,'state','Sonos');
my $kechocmd = qq(set $kecho sounds summer);
my $kechos = qq(set $kecho speak);

my %rcode2cmnd = (
'0x20df4eb1' => 'Gastzugang',
'0x20df8e71' => 'Wandlampen',
'0x20dfc639' => 'Rollo',
'0x20df8679' => 'Einkaufsliste');
my $gcmnd = $rcode2cmnd{$rcCode};

return fhem("set $dudev $gcmnd;set $kecho speak $gcmnd") if $gcmnd && $dudevstate ne $gcmnd;

if ($dudevstate eq 'Gastzugang') {

my $sound = sub {fhem("set $kecho sounds Glocken");};
my $a1 = sub { system('/opt/fhem/www/scripts/vouchergzg.sh vouchergzg &');};
my $a2 = sub { system('/opt/fhem/www/scripts/vouchergzg.sh vouchergzg1 &');};
my $a3 = sub { system('/opt/fhem/voucher4.sh &');};
my $a4 = sub { system('/opt/fhem/www/scripts/voucher.sh voucher_7d1x &');};
my $a5 = sub { system('/opt/fhem/www/scripts/voucher.sh voucher_21d1x &');};

my $sr2cmnd = {
'0x20df22dd' => \&$a1,
'0x20dfe01f' => \&$a2,
'0x20df02fd' => \&$a3,
'0x20df609f' => \&$a4,
'0x20df827d' => \&$a5
};
return if !$sr2cmnd->{$rcCode};
return fhem("set $kecho speak $dudevstate") if $rcCode eq "0x20df55aa";
return $sr2cmnd->{$rcCode}->().$sound->() if ref $sr2cmnd->{$rcCode} eq 'CODE';
return;
}

if ($dudevstate eq 'Wandlampen') {

# green button 1x -> Wandlampen

my $pctzu = "pct {(minNum(ReadingsNum('$frwl','pct','0')+10,100))}";
my $pctzd = "pct {(maxNum(ReadingsNum('$frwl','pct','0')-10,0))}";

my %code2command = (
'0x20df22dd' => 'toggle',
'0x20df40bf' => "$pctzu",
'0x20dfc03f' => "$pctzd",
'0x20df8e71' => "Deko",
'0x20df55aa' => "$dudevstate");
my $command = $code2command{$rcCode};

return if !$command;
return fhem("$kechos $command") if $rcCode eq "0x20df55aa";
return fhem("$kechos $command;set $dudev $command") if $rcCode eq "0x20df8e71";
return fhem("set $frwl $command");

}


if ($dudevstate eq 'Deko') {
my %code2command = (
'0x20df22dd' => 'toggle',
'0x20df55aa' => "$dudevstate");
my $command = $code2command{$rcCode};

return fhem("$kechos $command") if $rcCode eq "0x20df55aa";
return fhem("set it_Steckdose4 $command") if $rcCode eq "0x20df22dd";
}


if ($dudevstate eq 'Rollo') {

# yellow button 1x -> Rollo

my %code2command = (
'0x20df827d' => 'off',
'0x20dfe01f' => 'pct 38',
'0x20df609f' => 'pct 20',
'0x20df02fd' => 'on',
'0x20df22dd' => 'stop',
'0x20df40bf' => 'up',
'0x20dfc03f' => 'down',
'0x20df55aa' => "$dudevstate");
    my $command = $code2command{$rcCode};

return if !$command;
return fhem("$kechos $command") if $rcCode eq '0x20df55aa';
return fhem("set $kurl $command");
}
if ($dudevstate eq 'Einkaufsliste') {

# blue button 1x -> Einkaufsliste

my $sound = sub {fhem("set $kecho sounds Glocken");};
my $a1 = sub { system('lpr -P HL-2035 -o media=Custom.95x138mm /opt/fhem/einkaufsliste.txt &');};
my $a2 = sub {my @array = split(',',ReadingsVal($echod,'list_SHOPPING_ITEM',''));
foreach my $sk (@array) {fhem ("set $echod item_shopping_delete $sk")}};

my $sr2cmnd = {
'0x20df22dd' => \&$a1,
'0x20dfda25' => \&$a2};

return fhem("set $kecho speak $dudevstate") if $rcCode eq '0x20df55aa';
return $sr2cmnd->{$rcCode}->().$sound->() if ref $sr2cmnd->{$rcCode} eq 'CODE';
return;
}
}

1;


Ich hab bis jetzt nur festgestellt das wenn ich irgendeinen beliebigen if Zweig rausnehme die Meldung danach weg ist ?


Beta-User

Zitat von: TomLee am 21 Februar 2022, 16:23:34
Warum kommt es zu der Meldung, von der Erklärung dazu versteh ich nur Bahnhof:

Subroutine "Nec32RemoteCodesHandlerFR" with high complexity score (21) at line 13, column 1. Consider refactoring.
Aha, Perlcritic auf Stufe 3! Cool!!!

Mein persönlicher (unrühmlicher) Spitzenreiter:
ZitatSubroutine "handleIntentSetNumeric" with high complexity score (68) at line 4087, column 1. Consider refactoring.
(Fast) Unwartbar, das Ding, aber ich habe leider keine Idee, wie man es einfacher machen kann...

Dieser "complexity score" gibt einfach nur an, wie viele "Ausgänge" ein Code haben kann. Wie du gesehen hast: ein "if"-Zweig mit eigenem Ausgang (return) weniger, und das Ding sieht "sauber" aus, Perlcritic sieht "20" als "noch ok" an. Ob es wirklich "komplex" ist, ist damit noch lange nicht definitiv entschieden, dein Code hat ja eine trotz allem noch relativ überschaubare Strukutur.

"Refactoring" könnte bedeuten, einzelne if-Zweige in eigene Subs auszulagern, hier z.B. für jeden der "dudevstate" je eine Sub. Das "blöde" im Main-Kontext ist halt, dass einem dann irgendwann die "prägnanten Namen" für subs ausgehen, weswegen viele FHEM-Module intern auch eher selten solche Strukturierungen vornehmen (oder gar auf externe Hilfsmittelchen wie List::unique zurückgreifen), sondern manche "Schnipsel" an vielen Stellen "recycled" werden.

Klarer jetzt?

Wegen "21" würde ich mir jetzt noch nicht allzusehr den Kopf zerbrechen, das ist für solche "dispatch"-ähnlichen Strukturen relativ normal...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

TomLee

ZitatKlarer jetzt?

zögerliches ja, ab
Zitat... weswegen viele FHEM-Module intern auch eher selten ..
nicht wirklich und was unter "dispatch"-ähnlichen Strukturen, zu verstehen ist ehrlich gesagt auch nicht aber eine Ahnung, mach ich mich aber nicht verrückt wegen irgendwann kommt der Aha-Effekt schon.


Eine hab ich noch:

Darf man nicht beliebig viele Parameter übergeben ?

package main;

use strict;
use warnings;

sub Remotes_Utils_Initialize {
  my $hash = shift//return;
  return;
}

sub Nec32RemoteCodesHandler {
my $wzwl = shift;
my $wzdl = shift;
my $sija = shift;
my $tv = shift;
my $strzigu = shift;
my $miwl = shift;
my $sdev = shift;
my $dudev = shift;
my $rcCode = shift // return;
return;
}
1;


Beta-User

Zitat von: TomLee am 21 Februar 2022, 17:22:14
zögerliches ja, ab  [...] nicht wirklich
..ok, das versteht man vermutlich wirklich nur, wenn man mal "gewachsene Module" auseinandergenommen und wieder zusammengepuzzelt hat. Oder sich einzelne Module mindestens mal näher angeschaut.

Zitat
und was unter "dispatch"-ähnlichen Strukturen, zu verstehen ist ehrlich gesagt auch nicht
Das sind Funktionen, die so aufgebaut sind, dass abhängig von einem gewissen input irgendeine Funktion ausgeführt wird. In der Regel ist die jeweils komplett unterschiedlich, je nachdem, welche Vorbedingung erfüllt ist. Typisches Beispiel: set-Funktionen in FHEM. Für on/off ist es recht einheitlich, aber z.B. ein "mach farbig" oder "mach heller" ist dann doch was grundverschiedenes, was man eigentlich jeweils in eine eigene Unterfunktion auslagern könnte. In der Regel findet sich sowas aber halt irgendwo in einem if-Zweig der 4. Ebene...

ZitatDarf man nicht beliebig viele Parameter übergeben ?
Dürfen (im Sinne: es wird funktionieren) kann man schon, aber es ist unübersichtlich und fehleranfällig, zumal, wenn keine Kommentare im Code zu finden sind. Tendenziell wäre die Frage, ob man die Teil-Argumente in deinem Beispiel nicht besser in einen Hash verpackt, v.a., wenn nicht alle Argumente zwingend sind. (Es ist aber eher eine Art "Konvention" in FHEM, dass die Argumente in der Regel komma-separiert übergeben werden, soweit sie vom User bereitgestellt werden).
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

TomLee

Danke für das erläutern.

ZitatTendenziell wäre die Frage, ob man die Teil-Argumente in deinem Beispiel nicht besser in einen Hash verpackt, ...

Einen Hash zu übergeben kam mir beim schreiben der Frage in den Sinn und fragte mich insgeheim ob man es vlt. besser dann so macht  :)
Gut das du diesen Gedanken gleich mit der nächsten Antwort bestätigt hast  ;D

Beta-User

Zitat von: TomLee am 21 Februar 2022, 17:59:10
Danke für das erläutern.
Gerne. Vielleicht noch ein (kleines) Beispiel, wie das mit dispatch statt "elsif-Bandwurm" gemeint ist:
Wenn du https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/00_MYSENSORS.pm?rev=25007#L620 vergleichst mit der alten Fassung aus https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/00_MYSENSORS.pm?rev=21300#L298, wird es vielleicht an diesem Schnippsel klarer. Wobei es an der Stelle eben schon relativ "straight forward" war, weil nur "kurz" nach der passenden Funktion gesucht wurde und die dann aufgerufen. Das ist eher die Ausnahme...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

TomLee

Mir stellt sich gerade wegen dem Wochentag-Thread die Frage ob man bei der Übergabe von Parametern mit shift auch einen Default/Ersatzwert angeben kann statt die Funktion einfach mit return zu verlassen wenn shift leer ist ?

Wenn ich Code einfach an das return anhänge wird die Funktion ja danach beendet, mit einfach nur der Angabe des Codes bekommt man ein Can't modify defined or (//) in scalar assignment at ./FHEM/99_Calendar_Utils.pm line 14, near "];"

Wie macht man sowas mit shift, sry ist das erste mal das mir sowas bewusst auffällt und ich keinen Ansatz für eine Lösung habe (was das shift angeht).

frober

Raspi 3b mit Raspbian Buster 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...

betateilchen

Lese doch mal ein gutes perl Buch :)


sub test{
  my $wert = shift // "default";
  return $wert;
}

-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Beta-User

Ergänzend - für weiter hinten in einer Funktion:
$var //= 'kein Wert bis hier';
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files