Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load Protocolhash from PerlModule instead from textfile #522

Merged
merged 25 commits into from
Feb 26, 2019

Conversation

sidey79
Copy link
Contributor

@sidey79 sidey79 commented Feb 23, 2019

  • Please check if the PR fulfills these requirements
  • Tests for the changes have been added / modified (needed for for bug fixes / features)
  • CHANGED has been updated (needed for bug fixes / features)
  • What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)

Protocol data ist moved to a fully compatible perl module and imported via standard perl operations.

  • What is the current behavior? (You can also link to an open issue here)

The protocol data ist stored in an text file and loaded at runtime into a hash variable.
Th file ending itself is not compatible with standard fhem Update.

  • What is the new behavior (if this is a feature change)?

Because the new approach uses a perl module for storing the data, it uses a file type that is supported bybstandard fhem Update procedure.

  • Does this PR introduce a breaking change? (What changes might users need to make in their application due to this PR?)

Currently there ist no known breaking Change.

  • Other information:

@sidey79 sidey79 changed the base branch from master to dev-r34 February 23, 2019 20:28
@sidey79
Copy link
Contributor Author

sidey79 commented Feb 23, 2019

@HomeAutoUser
@Ralf9

Ich hab mal was probiert. Es klappt aber irgendwas beim Syntaxcheck der Module nicht :(

@HomeAutoUser
Copy link
Contributor

Sehe ich das richtig, du möchtest das selbige wie Ralf machen, nur in einem eigenem Package?

@Ralf9
Copy link
Contributor

Ralf9 commented Feb 23, 2019

Mich würde es wundern, wenn es so funktionieren würde.
Warum machst Du es nicht vom Prinzip so wie es Rudi und betateilchen vorschlagen?
In der 88_HMCCU.pm und HMCCUConf.pm wird es auch so gemacht.
Bei mir funktioniert es inzwischen.

@sidey79
Copy link
Contributor Author

sidey79 commented Feb 23, 2019

@HomeAutoUser
Ich wollte mal schauen, was so alles an den Tests fehl schlägt. Daher habe ich das mal zusammengebaut um mal zu schauen wie man das machen könnte.

@Ralf9
Hast Du alle unittests laufen lassen oder was meinst Du mit "Bei mir funktioniert es inzwischen".

Bin jetzt nicht ganz sicher was Du mit "Variante von Rudi und betateilchen" genau meinst. Es im Package main zu belassen? Oder Die Variante mit "use" zu welcher ich folgendes in der Perldoku finde "the use of this pragma is discouraged" ?

@sidey79
Copy link
Contributor Author

sidey79 commented Feb 23, 2019

So, wenn man das Perl Modul nicht in die Perl Installation kopiert, dann kann es auch nicht funktionieren ..

Jetzt schlagen all die Tests fehlt, in denen eine andere Protocol Hash Datei geladen wird. Das habe ich mir bereits gedacht. Die müssten auch umgebaut werden.
Da man aber den Inhalt über eine Funktion Lädt sollte das eine überschaubare Anpassung sein. Wie würde das denn bei der Variante von "Rudi und Betateilchen" ablaufen? Da kann man ja nichts aus dem anderen Modul aufrufen, das einem die Daten zurückliefert?

@Ralf9
Copy link
Contributor

Ralf9 commented Feb 23, 2019

Ich brauche keine unittests laufen lassen um zu sehen ob es funktioniert.
Daß das Prinzip funktioniert lässt sich an einigen fhem Modulen anschauen.
Es funktioniert auch ohne die Verwendung von use.
Das Prinzip kannst Du z.B. hier sehen
88_HMCCU.pm und HMCCUConf.pm
und hier
UConv.pm
sind auch sub Routinen drin die von einigen anderen Modulen aufgerufen werden und Werte zurückliefern

@sidey79
Copy link
Contributor Author

sidey79 commented Feb 23, 2019

Keine Ahnung worum es jetzt geht. Was genau bei welcher Variante funktioniert und was nicht ist mir nicht transparent. Daher habe ich es halt mal ausprobiert.

Die Variante, ein Package zu erstellen und darin eine Methode zum holen der Daten zu platzieren, schien mir von den mir bekannten am besten geeignet.

Das initiale und einmalige laden des Packages ist im übrigen auch kein Problem. Ein bisschen tricky wird es, wenn man eine andere Protokolldefinition laden möchte.

@sidey79
Copy link
Contributor Author

sidey79 commented Feb 24, 2019

Problematisch ist aktuell, dass ich die Hashes die für die Tests geladen werden auch in einen Package mit gleichem Namen gepackt habe.

Das Überschreiben der Methode zum abholen der Daten klappt sogar auf diesem Weg und für den Test bekommt man dann die Daten aus dem Package was als 2. geladen wurde.

Was nicht klappt ist dann wieder das originale Package laden. Das ist ja bereits geladen und der Weg zurück klappt nicht.
Hier fehlt eine Methode um ein Package komplett zu entladen.

In dem Package könnte man vermutlich noch mit Versionen arbeiten:

http://blogs.perl.org/users/grinnz/2018/04/a-guide-to-versions-in-perl.html

Allerdings weiss ich nicht, ob wir über das Fhem Update überhaupt unterschiedliche Versionen bereitstellen können.

@Ralf9
Copy link
Contributor

Ralf9 commented Feb 24, 2019

Mir ist aufgefallen, daß Du bei filterfunc no strict "refs"; verwendest,
wäre es so my $methodRef = \&{ $method }; nicht sauberer,
oder ist in diesem Fall no strict "refs"; ok?

				my $method = $ProtocolListSIGNALduino{$id}{filterfunc};
		   		if (!exists &$method)
				{
					SIGNALduino_Log3 $name, 5, "$name: Error: Unknown filtermethod=$method. Please define it in file $0";
					next;
				} else {					
					SIGNALduino_Log3 $name, 5, "$name: for MU Protocol id $id, applying filterfunc $method";

				    #no strict "refs";
				    my $methodRef = \&{ $method };
					(my $count_changes,$rawData,my %patternListRaw_tmp) = $methodRef->($name,$id,$rawData,%patternListRaw);
				    #use strict "refs";

@sidey79
Copy link
Contributor Author

sidey79 commented Feb 24, 2019

Vermutlich habe ich noch structure refs verwendet, da Perl der Meinung war es wäre keine Referenz.

Ist mir damals aber schon nicht klar gewesen, wieso method nicht auf eine Referenz verweist, da doch auf eine sub Referenziert wird.

@Ralf9
Copy link
Contributor

Ralf9 commented Feb 24, 2019

Bei filterfunc steht in method ein string
filterfunc => 'SIGNALduino_compPattern',

@Ralf9
Copy link
Contributor

Ralf9 commented Feb 24, 2019

Damit das mit signalduino_protocols.pm und Package funktioniert müssen die Referenzen bei postDemodulation und method auch in strings umgewandelt werden.

@sidey79
Copy link
Contributor Author

sidey79 commented Feb 24, 2019

Bist Du der Meinung die Anpassung aus diesem PR funktioniert nicht?
Ich habe den Eindruck, dass es als Referenz funktioniert.

@Ralf9
Copy link
Contributor

Ralf9 commented Feb 24, 2019

wenn ich es so wie in 88_HMCCU.pm und HMCCUConf.pm mache, dann funktioniert es als
postDemodulation => &SIGNALduino_HE800,
nicht, es funktioniert nur als String

@sidey79
Copy link
Contributor Author

sidey79 commented Feb 24, 2019

Mit dem Auslagern in ein Package habe ich mich generell beschäftigt und nicht so sehr auf andere FHEM Beispiele geschaut.
Es scheint etliche Wege zu geben die alle vor und auch Nachteile haben.

Hast Du dir die Änderungen in diesem PR angesehen?
Der Teil funktioniert soweit ich das getestet hatte.
Nur das entladen des Packages ist noch ungelöst.

@Ralf9
Copy link
Contributor

Ralf9 commented Feb 24, 2019

arbeitest Du in diesem PR mit einer Referenz oder einer Kopie vom Protokollhash?

@sidey79
Copy link
Contributor Author

sidey79 commented Feb 24, 2019

Die korrekte Antwort lautet wohl beides.

Ich habe den Rückgabewert der sub SIGNALduino_LoadProtocolHash beibehalten.
Dadurch erreicht dieser PR auch eine hohe kompatibilitat.

Meiner Meinung auch der Zweck der Kapselung. Wo die Daten her kommen ist egal, solange das bereitstellen für das Modul sich nicht ändert.

Aus dem Package wird eine Referenz geladen, aber diese Referenz wird dereferenziert und dann von der Sub zurückgeliefert.

Ist also identisch zu dem bisherigen Verhalten.
Das ist meiner Ansicht nach auch notwendig um Defaults im Hash setzen zu können. Das Verändern von Daten eines anderen Packages wird wieder als unsauber erachtet und dem kann ich mich anschließen.

@Ralf9
Copy link
Contributor

Ralf9 commented Feb 24, 2019

Durch das beibehalten der sub SIGNALduino_LoadProtocolHash ersetzt Du meiner Meinung nach eine unkonventionelle Lösung durch eine andere unkonventionelle.
Ich kann da Nachteile für zukünftiges erahnen.
Kannst Du mit mit Deiner Lösung problemlos die signalduino_protocols.pm um weitere Hash und Subs erweitern?
Ein weiterer sinnvoller und notwendiger Hash ist VersionProtocolList

Für die Tests sehe ich bei einer Referenz auf den Hash keine größere unlösbare Probleme, es fällt sogar ein Test (Load Protocolhash) weg.

Das ist meiner Ansicht nach auch notwendig um Defaults im Hash setzen zu können. Das Verändern von Daten eines anderen Packages wird wieder als unsauber erachtet und dem kann ich mich anschließen.

Die Defaults können auch bei einer Referenz vom Hash gesetzt werden. Ich denke das Verändern von Daten eines anderen Packages ist nur ein kleine unsauberkeit, da der Hash ja zur 00_signalduino gehört.

@Ralf9
Copy link
Contributor

Ralf9 commented Feb 24, 2019

Als Referenz zum Hash sieht es so aus:

package signalduino_protocols;

# use vars qw(%ProtocolListSIGNALduino);
# use vars qw(%VersionProtocolList);

our %VersionProtocolList = (
		"version" => 'v3.4.0-dev_23.02.'
		);

our %ProtocolListSIGNALduino  = (
	"0"	=>	## various weather sensors (500 | 9100)

und in der 00_Signalduino:

require "lib/signalduino_protocols.pm";

my %ProtocolListSIGNALduino = %signalduino_protocols::ProtocolListSIGNALduino;
my %VersionProtocolList = %signalduino_protocols::VersionProtocolList;

@sidey79
Copy link
Contributor Author

sidey79 commented Feb 24, 2019

Durch das beibehalten der sub SIGNALduino_LoadProtocolHash ersetzt Du meiner Meinung nach eine unkonventionelle Lösung durch eine andere unkonventionelle.

Was ist daran unkonventionell? FHEM lädt Module auch über eine eigene Sub nach um z.B. auf Fehler reagieren zu können.

Ich kann da Nachteile für zukünftiges erahnen.

Welche?

Kannst Du mit mit Deiner Lösung problemlos die signalduino_protocols.pm um weitere Hash und Subs erweitern?

In das Modul kann man alles mögliche packen, ja das geht. Die sub SIGNALduino_LoadProtocolHash holt den den Protokoll Hash aus dem Modul was nicht zu verwechseln ist, dass sie das ganze Package oder sowas zurück gint.

Ein weiterer sinnvoller und notwendiger Hash ist VersionProtocolList

Perl hat für die Angabe der Version bereits einen Standard. Wieso sollten wir den nicht einfach verwenden?
https://perldoc.perl.org/perlmod.html#Perl-Modules

Für die Tests sehe ich bei einer Referenz auf den Hash keine größere unlösbare Probleme, es fällt sogar ein Test (Load Protocolhash) weg.

Das verstehe ich nicht. Der Test soll feststellen, ob das Laden der Protokolldaten funktioniert.
Wenn der wegfällt, wir es doch nicht mehr getestet und die Testabdeckung sinkt wieder.

Die Defaults können auch bei einer Referenz vom Hash gesetzt werden. Ich denke das Verändern von Daten eines anderen Packages ist nur ein kleine unsauberkeit, da der Hash ja zur 00_signalduino gehört.

Können kann man es aber ich würde das nicht machen wollen wenn es nicht notwendig ist.

@sidey79
Copy link
Contributor Author

sidey79 commented Feb 24, 2019

Als Referenz zum Hash sieht es so aus:

Mal abgesehen davon, dass ich das Package SD_Protocols benannt habe sehe ich das jetzt keinen Unterschied. Das Package gibt eine Referenz zu dem Hash zurück. Ich habe es über eine sub realisiert und bin nicht direkt auf die Variable im Package gegangen. Es ist allgemein eine good practice, auf Daten andere Module nicht direkt zuzugreifen, sondern das über Routinen zu machen.
Ist das gleiche, wie die subs attrVal readingsVal usw. zu verwenden und nicht direkt auf die Daten zuzugreifen.

return %{SD_Protocols->getProtocolList};

sub getProtocolList {
return \%signalduino_protocols; }
}

@sidey79 sidey79 marked this pull request as ready for review February 24, 2019 21:10
@sidey79 sidey79 changed the title Dev r34 protocols into hash Load Protocolhash from PerlModule instead from textfile Feb 24, 2019
@coveralls
Copy link

coveralls commented Feb 24, 2019

Pull Request Test Coverage Report for Build 1219

  • 7 of 8 (87.5%) changed or added relevant lines in 2 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage remained the same at 12.354%

Changes Missing Coverage Covered Lines Changed/Added Lines %
FHEM/00_SIGNALduino.pm 6 7 85.71%
Totals Coverage Status
Change from base Build 1191: 0.0%
Covered Lines: 264
Relevant Lines: 2137

💛 - Coveralls

@sidey79
Copy link
Contributor Author

sidey79 commented Feb 24, 2019

@Ralf9 @HomeAutoUser

Ich hab den PR mal so weit fertig, dass

  1. Die Protokolldaten in einem PerlModul liegen und nicht mehr in einer Datei.
    Damit könnte man die Protokolldatei über das "normale" FHEM Update aus dem SVN aktualisieren.
  2. Alle Tests wieder erfolgreich verlaufen
    Es ist also der Status wie zuvor hergestellt.

Wie allerdings die Protokolldaten unabhängig vom Modul aktualisiert werden könnten ist offen, da ja alles in einem Repository liegt. Aus #469 sind wir also damit bei der dort beschriebenen Variante 1.

Variante 1: Aktualisierung erfolgt über den Update Befehl von FHEM selbst. Also wie bisher

  • Es gibt nur wenige Kombinationen und die lassen sich auch testen

  • Wir können den Anwender nur schwierig über Aktualisierungen informieren

@sidey79
Copy link
Contributor Author

sidey79 commented Feb 25, 2019

@HomeAutoUser @elektron-bbs
Habe doch noch einen kleine Schwachstelle beim Laden des Protokoll Packages gefunden :) und behoben

@sidey79 sidey79 added this to the 3.4 milestone Feb 25, 2019
remove copy of hash files
@sidey79 sidey79 merged commit 868633a into dev-r34 Feb 26, 2019
@sidey79
Copy link
Contributor Author

sidey79 commented Feb 26, 2019

Ich habe die Anpassung in dev-r34 überführt.
Für mich ist das der Anfang auf dem wir noch aufbauen können.

@Ralf9 Du warst drauf und dran mit einer Referenz und nicht mit einer Kopie zu arbeiten.
Dafür müssten doch alle Zugriffe auf den Hash dann eine dereferenzierung vornehmen oder?
Was wäre denn deiner Meinung nach der Vorteil davon?

@sidey79 sidey79 deleted the dev-r34_protocolsIntoHash branch February 26, 2019 12:52
@Ralf9
Copy link
Contributor

Ralf9 commented Feb 27, 2019

Dafür müssten doch alle Zugriffe auf den Hash dann eine dereferenzierung vornehmen oder?

Wenn ich das richtig verstehe, ist das so wie ich es bei mir gemacht habe (s.u) das gleiche, als wäre der hash in der 00_SIGNALduino.pm

signalduino_protocols.pm

package SD_Protocols;

# use vars qw(%ProtocolListSIGNALduino);
# use vars qw(%VersionProtocolList);

our %VersionProtocolList = (
		"version" => 'v3.4.0-dev_ralf_24.02.'
		);

our %ProtocolListSIGNALduino  = (
	"0"	=>	## various weather sensors (500 | 9100)

00_SIGNALduino.pm

require "lib/signalduino_protocols.pm";

my %ProtocolListSIGNALduino = %SD_Protocols::ProtocolListSIGNALduino;
my %VersionProtocolList = %SD_Protocols::VersionProtocolList;

@Ralf9
Copy link
Contributor

Ralf9 commented Feb 27, 2019

Für mich ist das der Anfang auf dem wir noch aufbauen können.

Für mich scheint das, so wie Du es gemacht hast, nicht so richtig zukunftfähig zu sein.
Es sieht für mich nach einer unüblichen Sonderlösung aus.
Du machst eine Kopie vom hash obwohl dies nicht unbedingt notwendig ist.

Bei der bewährten Lösung, so wie es Rudi und betateilchen es vorgeschlagen haben, ist es recht einfach möglich weitere Hashes in die signalduino_protocols.pm hinzuzufügen.
Als weitere Hashes fallen mir z.B. ergänzungen zur client- und matchlist ein.

Die Version bei Deiner signalduino_protocols.pm ist mir zu einfach.
Ich hätte gerne den gleichen Aufbau wie bei der signalduino_protocols.pm
z.B. v3.4.0-dev_ralf_24.02.

Es ist auch zu überlegen ob wir die hash-Datei bei der Entwicklungsversion signalduino_protocols-dev.pm benennen.
Wir können davon ausgehen, daß einige Anwender, die die stable Version verwenden, auf die Idee kommen werden, die signalduino_protocols.pm aus der dev-r34 zu holen um die aktuellen Protokolle zu haben.
Außerdem kann dann die signalduino_protocols-dev.pm nachgeladen oder geupdatet werden ohne daß es beim updatecheck einträge gibt.

@Ralf9
Copy link
Contributor

Ralf9 commented Feb 28, 2019

Hab wegen der evtl umbenennung auf signalduino_protocols-dev.pm nochmals darüber nachgedacht, ist wahrscheinlich doch so keine gute Idee. Hat mehr Nachteile als Vorteile

@sidey79
Copy link
Contributor Author

sidey79 commented Feb 28, 2019

Was ist dabei die Sonderlösung? Kannst Du das genauer definieren?

Ich habe da einige Standard Perl Varianten recherchiert und nach best practices gesucht.
Die habe ich bei der Auswahl der Variante berücksichtigt. Diese Variante erschien mir passend. Bezüglich Sonderlösung brauche ich mehr Details welchen Punkt das betrifft.

Das Einfügen von weiteren Variablen ist hier auch nicht schwierig, oder wo siehst Du da Probleme?

Was die Bezeichnung der Version angeht, habe ich mich einfach an einen wohl definierten Standard gehalten:
https://metacpan.org/pod/distribution/version/lib/version/Internals.pod

Wenn das ganze Perl Universum damit arbeiten kann, wieso soll das bei uns nicht auch gehen?

@Ralf9
Copy link
Contributor

Ralf9 commented Feb 28, 2019

Sonderlösung ist, daß ich dies außer bei Dir noch nirgends gesehen habe. In fhem und in den Beispielen wo ich im Internet gefunden habe, wird es so gemacht wie es Rudi und Betateilchen empfehlen.

Wenn ich das richtig überblicke brauchst Du für jeden Hash eine eigene Methode um über die Loadroutine eine Kopie zu laden.
Dies sieht für mich komplizierter und aufwändiger aus. Du machst von jedem Hash eine kopie obwohl dies nicht notwendig ist.
Dies ist von mir nur so ein Gefühl, daß so wie Du es machst nicht optimal und zukunftsfähig ist.
Für mich hat sich das Thema erledigt.
Ich werde bei meiner Version die bewährte Methode einbauen die ohne eine Kopie auskommt.

@sidey79
Copy link
Contributor Author

sidey79 commented Feb 28, 2019

Sonderlösung ist, daß ich dies außer bei Dir noch nirgends gesehen habe. In fhem und in den Beispielen wo ich im Internet gefunden habe, wird es so gemacht wie es Rudi und Betateilchen empfehlen.

Das kommt eher aus der Richtung der Objekt orientierten Programmierung.
Ich hätte auch gleich auf Moose umstellen können, aber der Sprung war für mich gefühlt zu groß.

Wenn ich das richtig überblicke brauchst Du für jeden Hash eine eigene Methode um über die Loadroutine eine Kopie zu laden.

Brauchen nicht, aber sauberer ist es, um an die Daten zu kommen, vor allem wenn wir das Modul eher als Objekt sehen und nicht nur als Text Datei.

Dies sieht für mich komplizierter und aufwändiger aus. Du machst von jedem Hash eine kopie obwohl dies nicht notwendig ist.

Das mache ich, weil der Inhalt des Hashes im SIGNALduino Modul verändert wird. Das wäre unsauber und schwierig wartbar, wenn dann z.B. das SD_Tool auch noch auf den Hash Zugreift und daran was verändert. Am Ende ändert man besser keine Daten anderer Packages.

Offenbar kenne ich die Variante auch nicht, welche dir vorschwebt.
Der Beitrag von gestern legt auch eine Kopie der Variable aus dem Package an.
my %ProtocolListSIGNALduino = %SD_Protocols::ProtocolListSIGNALduino;

Dies ist von mir nur so ein Gefühl, daß so wie Du es machst nicht optimal und zukunftsfähig ist.

Optimal ist Abhängig von den Anforderungen. Dass wir die Daten auf dauer nicht kopieren müssen wäre durchaus denkbar, wenn wir in SD_Protocols ein paar Schnittstellen einbauen wie z.B.

	#=item getKeys()
	#This functons, will return all keys from the protocol hash

	#=item checkProperty()
	#This functons, will return a value from the Protocolist and check if the key exists and a value is defined optional you can specify a optional default value that will be reurned

	#=item getProperty()
	#This functons, will return a value from the Protocolist without any checks 

       #=item setDefault()
       # tbd : Hier habe ich noch keine gute Idee, wie man die Defaults speichert.

Für mich hat sich das Thema erledigt.
Ich werde bei meiner Version die bewährte Methode einbauen die ohne eine Kopie auskommt.

Verrätst Du mir bitte noch deine ohne Kopie Methode.

@Ralf9
Copy link
Contributor

Ralf9 commented Mar 1, 2019

Offenbar kenne ich die Variante auch nicht, welche dir vorschwebt.
Der Beitrag von gestern legt auch eine Kopie der Variable aus dem Package an.
my %ProtocolListSIGNALduino = %SD_Protocols::ProtocolListSIGNALduino;

Danke für den Hinweis, das war mir nicht bewusst, daß damit auch eine Kopie angelegt wird, demnach arbeite ich mit meiner Methode auch mit einer kopie.
Ich bin in der Perl Programmierung nicht so tief drin wie Du. Ich habe es mir durch suchen und nachlesen im Internet selbst begebracht.

Ich habe wegen den hash Referenzen nochmals im Internet gesucht und nachgelesen, nun ist es mir etwas klarer geworden.

Wollte ich ohne eine Kopie arbeiten, müsste ich es so machen:
my $ProtocolListSIGNALduino = \%SD_Protocols::ProtocolListSIGNALduino;
dann müsste ich aber alle $ProtocolListSIGNALduino{$id}{...} in
$ProtocolListSIGNALduino->{$id}{...} abändern

@Ralf9
Copy link
Contributor

Ralf9 commented Mar 1, 2019

Bei der Gelegenheit könnten wir auch dies bereinigen:

postDemodulation	=> \&main::SIGNALduino_lengtnPrefix,
filterfunc	=> 'SIGNALduino_compPattern',

Bei postDemodulation wird eine coderef verwendet und bei filterfunc ein String.
Wenn wir bei der postDemodulation auch einen String verwenden
postDemodulation => 'SIGNALduino_lengtnPrefix',
dann lässt sich im log auch der Name der Sub Routine ausgeben:

sub SIGNALduino_callsub
{
	my $funcname =shift;
	my $method = shift;
	my $name = shift;
	my @args = @_;
	
	my $methodRef = \&{ $method };
	if ( defined $methodRef && defined &$methodRef )   
	{
		#my $subname = @{[eval {&$method}, $@ =~ /.*/]};
		SIGNALduino_Log3 $name, 5, "$name: applying $method , value before : @args"; # method $subname";
		
		my ($rcode, @returnvalues) = $methodRef->($name, @args) ;	
			
		if (@returnvalues && defined($returnvalues[0])) {
			SIGNALduino_Log3 $name, 5, "$name: rcode=$rcode, modified after $method: @returnvalues";
		} else {
	   		SIGNALduino_Log3 $name, 5, "$name: rcode=$rcode, after calling $method";
	    } 
	    return ($rcode, @returnvalues);
	} elsif (defined $methodRef ) {
		SIGNALduino_Log3 $name, 5, "$name: Error: Unknown method $funcname $method Please check definition";
		return (0,undef);
	}	
	return (1,@args);			
}

Außerdem ist mir noch aufgefallen, daß nicht alle postDemodulation Subroutinen im Namen ein _postDemo_ enthalten:
SIGNALduino_lengtnPrefix vs SIGNALduino_postDemo_WS2000
Ich würde es besser finden, wenn alle postDemodulation Subroutinen im Namen ein _postDemo_ enthalten

@sidey79
Copy link
Contributor Author

sidey79 commented Mar 1, 2019

Ja, so könnte man es machen.
Alternativ verwendet man gleich die Variable aus dem anderen Package oder ruft die Werte über Methoden ab, was ich grob konzipiere.

@sidey79
Copy link
Contributor Author

sidey79 commented Mar 1, 2019

Die Referenz auf eine Sub ist der String Variable vorzuziehen, da im Falle der Referenz direkt auf die Speicheradresse verwiesen wird.

@Ralf9
Copy link
Contributor

Ralf9 commented Mar 1, 2019

Der String lässt sich auch noch nachträglich in eine Codereferenz wandeln:
my $methodRef = \&{ $method };

@sidey79
Copy link
Contributor Author

sidey79 commented Mar 1, 2019

Ja, aber wozu einen String im Speicher ablegen, wenn wir ohnehin am Ende eine Speicheradresse benötigen? Dann können wir doch gleich die Speicheradresse dort hinterlegen.

@Ralf9
Copy link
Contributor

Ralf9 commented Mar 1, 2019

Damit der Name der Subroutine im log ausgegeben werden kann.
Zu was hast Du bei der filterfunc einen String im Speicher abgelegt und keine Codereferenz?

@sidey79
Copy link
Contributor Author

sidey79 commented Mar 1, 2019

Das war Unwissenheit und ist eine Altlast.

Der Name kann auch über die Coderef herausgefunden werden, wenn der wirklich wichtig ist.
Perl hat dafür: svref_2object. Es gibt auch Module, die einem das kapseln und leichter machen.

@Ralf9
Copy link
Contributor

Ralf9 commented Mar 2, 2019

Ich habe es mit svref_2object versucht, es ist umständlicher und aufwändiger als wenn der String im Speicher abgelegt wird.
Zur wandlung von String zu Codefeferenz ist nur eine Zeile my $methodRef = \&{ $method }; oder ein no strict "refs"; erforderlich.
mit svref_2object ist auch ein use B qw( svref_2object ); notwendig.
Kann ich davon ausgehen, daß das svref_2object in allen Perl installationen enthalten ist?

@sidey79
Copy link
Contributor Author

sidey79 commented Mar 2, 2019

Das B Modul ist ein Core Modul.
Wenn man eine schöne Api will, dann muss man Module von CPAN laden.

Wieso packen wir den Code nicht einfach in eine Sub?
Die Logausgabe kommt ja vermutlich im Normalfall nicht zur Geltung.

@sidey79
Copy link
Contributor Author

sidey79 commented Mar 2, 2019

Würde es nicht auch reichen den Namen innerhalb der Sub zu kennen?
Das wäre mit der caller Funktion machbar:
https://perldoc.perl.org/functions/caller.html

@Ralf9
Copy link
Contributor

Ralf9 commented Mar 2, 2019

Wenn der Name der Subroutine im Speicher abgelegt wird, dann sieht die log Ausgabe (verbose 5) ungefähr so aus:

applying SIGNALduino_postDemo_HE_EU , value before :
rcode=1, modified after SIGNALduino_postDemo_HE_EU:

Wenn wie seither die Codereferenz abgelegt wird, dann sieht die log Ausgabe ungefähr so aus.
Das ausgeben des Namens der Subroutine wird zu aufwändig.
Wem der Name der Subroutine interessiert, der muss ihn dann über die ID aus dem Protokollhash holen.

applying postDemomudulation, value before :
rcode=1, modified after postDemomudulation:

Ich würde es sauberer finden wenn alle postDemodulation Subroutinen "postDemo" im Namen enthalten würden.

Damit alles gleich ist sollte dann auch bei der filterfunc die codereferenz abgelegt werden. Der Name der filterfunc Subroutine kann in einer log Ausgabe am Ende der Subroutine ausgegeben werden.

@Ralf9
Copy link
Contributor

Ralf9 commented Mar 2, 2019

Mein Vorschlag wäre dann:

  • Bei der postDemodulation es mit der codereferenz so lassen, wem der Name der Subroutine interessiert, der muss ihn dann über die ID aus dem Protokollhash holen.
  • Bei der filterfunc auch die codereferenz ablegen. Der Name der filterfunc Subroutine wird in einer log Ausgabe am Ende der Subroutine ausgegeben.
  • alle postDemodulation Subroutinen sollen "postDemo" im Namen enthalten.

@Ralf9
Copy link
Contributor

Ralf9 commented Mar 3, 2019

Ich bin gerade dabei das ganze bei mir einzubauen.
Nun habe ich das Problem, wie mache ich nach dem editieren der signalduino_protocols.pm ein reload?
ein
reload lib/signalduino_protocols.pm
ergibt
Can't read ./FHEM/libsignalduino_protocols.pm: No such file or directory

@sidey79
Copy link
Contributor Author

sidey79 commented Mar 3, 2019

Durch

{SIGNALduino_LoadProtocolHash("$attr{global}{modpath}/FHEM/lib/signalduino_protocols.pm");}

Wird der Protocol Hash neu geladen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants