FHEM Forum

FHEM - Entwicklung => FHEM Development => Thema gestartet von: Sidey am 21 Februar 2019, 22:01:13

Titel: Update controls_fhem.txt
Beitrag von: Sidey am 21 Februar 2019, 22:01:13
Hi,

hab mir ein Bein gestellt und jetzt festgestellt, dass ich nicht weiss wie die controls_fhem.txt wirklich generiert wird.
Wobei, mittlerweile weiss ich es doch ein bisschen besser als ich vorher angenommen habe.

Ich habe mir erlaubt einen Konfigurationshash (ca 2000 Zeilen) in eine separate Datei auszulagern.

Den habe ich in das lib Verzeichnis gelegt.
FHEM/lib/signalduino_protocols.hash

Nun ist es aber so, dass diese Datei nicht in der controls_fhem.txt hinterlegt wird, da scheinbar nur definierte Dateitypen berücksichtigt werden.
Das Script, welche die controls_fhem.txt erstellt habe ich im SVN nicht ausfindig machen können.

Wäre es möglich das Script, welches die controls_fhem.txt erzeugt anzupassen?
Ich würde auch einen Patch erstellen, wenn ich wüsste wo ich das Script finde.

Grüße Sidey
Titel: Antw:Update controls_fhem.txt
Beitrag von: betateilchen am 21 Februar 2019, 22:24:01
./contrib/fhemupdate.pl
Titel: Antw:Update controls_fhem.txt
Beitrag von: betateilchen am 21 Februar 2019, 22:29:01
Wenn Du Deinen hash nach  ./FHEM/firmware/ verlegen würdest, muss man nix am update ändern, das Verzeichnis wird komplett berücksichtigt:

"FHEM/firmware/.*"
Titel: Antw:Update controls_fhem.txt
Beitrag von: Sidey am 21 Februar 2019, 22:31:37
@Betateilchen

Danke für beide hinweise.
Umlegen würde dazu führen, dass ich das Modul anpassen muss, was natürlich ebenso machbar wäre wie den Patch einzuspielen.

In Firmware würde ich so etwas halt nun eher nicht ablegen, weil es keine Firmware ist :)

Grüße Sidey
Titel: Antw:Update controls_fhem.txt
Beitrag von: betateilchen am 21 Februar 2019, 22:34:15
schon klar, es war nur ein Vorschlag für eine schnelle Lösung, die schon mit dem Update morgen früh greifen würde ;)
Titel: Antw:Update controls_fhem.txt
Beitrag von: Sidey am 21 Februar 2019, 22:36:29
Habe ich auch so verstanden.

Ich war mir auch generell unsicher, ob ich die Datei wirklich dort hinlegen soll, aber naja, es schien irgendwie passend.
Ich könnte die Datei auch dynamisch aus dem Internet nachladen, das war mit aber dann doch erst mal zu aufwändig.
Titel: Antw:Update controls_fhem.txt
Beitrag von: Ralf9 am 21 Februar 2019, 22:51:56
warum muß eigentlich die Endung bei einem Perl hash unbedingt .hash sein, wäre da .pm nicht passender?

Gruß Ralf
Titel: Antw:Update controls_fhem.txt
Beitrag von: Sidey am 21 Februar 2019, 22:56:35
Ich habe auf die Schnelle keine Spezifikation gefunden, wann etwas ein Perl Modul ist und wann nicht, aber es erscheint mir offensichtlich, dass ein Hash kein PerlModul ist, welches via use oder require geladen wird.



Grüße Sidey
Titel: Antw:Update controls_fhem.txt
Beitrag von: Ralf9 am 21 Februar 2019, 23:09:56
ich hab das gefunden:
https://stackoverflow.com/questions/12261525/can-i-use-hash-values-from-another-file
Titel: Antw:Update controls_fhem.txt
Beitrag von: rudolfkoenig am 22 Februar 2019, 09:48:33
Ich wuerde die Datei so modifizieren, dass die Daten einer Variable zugewiesen werden (analog zu HMCCUConf.pm) und sie in FHEM/lib/signalduino_protocols.pm umbenennen. Dann kann man die Datei mit use laden, die Leute stellen keine bloede Fragen, und man muss im Framework keine Ausnahmen einbauen.
Titel: Antw:Update controls_fhem.txt
Beitrag von: Sidey am 22 Februar 2019, 21:08:39
Zitat von: rudolfkoenig am 22 Februar 2019, 09:48:33
Ich wuerde die Datei so modifizieren, dass die Daten einer Variable zugewiesen werden (analog zu HMCCUConf.pm) und sie in FHEM/lib/signalduino_protocols.pm umbenennen. Dann kann man die Datei mit use laden, die Leute stellen keine bloede Fragen, und man muss im Framework keine Ausnahmen einbauen.

Hi Rudi,

ich habe die Daten einer Variable zugewiesen. Das funktioniert prinzipiell auch bereits seit Monaten. Nur leider wird die Datei nicht über den Update Befehl geladen.

Dein Vorschlag ist jetzt, dass ich mich von einer bewährten Methode des ladens von Daten aus einer Datei in einen Hash verabschieden soll.

sub SIGNALduino_LoadProtocolHash($)
{

if (! -e $_[0]) {
return %{ {"error" => "File does not exsits"}};
}

my $protocol_data = do {
open my $fh, '<', $_[0] ;
local $/; # Undefine $/ for this scope...
    <$fh>;    # so <> slurps up the entire file
};

my %evalret= eval $protocol_data ;
if (!%evalret) {
return %{ {"error" => $@}};
}
return %evalret;
}


Wie ich das nun mit use oder require hinbekomme eine Datei mit variablen Namen laden zu können müsste ich noch prüfen.
So wie ich HMCCUConf verstanden habe, wird dort ein Package definiert in dem wiederum die Variablen definiert sind. Um diese dann im Modul verwenden zu können, wird eine Variable im Modul als Referenz auf die Variable im Package angelegt.



Was die Ausnahmen des Frameworks angeht, verstehe ich die Regel aktuell leider nicht :-( .

Es gibt Verzeichnisse, in denen ist der Beginn des Dateinamens entscheidend. Z.B.:
"FHEM/FhemUtils/update-.*",

Es gibt Verzeichnisse, in denen ist alles erlaubt. Z.B.:
  "FHEM/firmware/.*",
  "FHEM/lib/SWAP/panStamp/.*",
  "FHEM/lib/SWAP/justme/.*",
  "www/pgm2/.*",
  "www/codemirror/.*",

Und dann gibt es noch Verzeichnisse in denen sind nur manche Dateiendungen erlaubt. Z.B:
  "FHEM/lib/.*.pm",
  "FHEM/lib/.*.xml",
  "FHEM/lib/.*.csv",
  "www/images/fhemSVG/.*.svg",

Was ist denn jetzt hier genau die Regel des Frameworks von der ich abweiche?

Wenn ich die Daten jetzt in einem JSON File speichern würde. Wäre es dann okay?

.gz Dateien liegen heute auch bereits im FHEM/lib/ Verzeichnis, aktualisieren lassen die sich aber wohl auch nicht.

Grüße Sidey
Titel: Antw:Update controls_fhem.txt
Beitrag von: rudolfkoenig am 22 Februar 2019, 21:50:50
ZitatWas ist denn jetzt hier genau die Regel des Frameworks von der ich abweiche?
Du willst eine Datei mit dem Namen .hash anlegen, und damit waerst du die Erste.
Deine Methode des Ladens ist auch unkonventionell.

Es reicht, wenn du deine Datei "FHEM/lib/signalduino_protocols.pm" nennst, vor dem ersten Klammer
use vars qw(%signalduino_protocols);
%signalduino_protocols =
schreibst, und die Datei mitrequire "lib/signalduino_protocols.pm";reinliest. Danach hast du Zugriff auf %signalduino_protocols.

Zitat.gz Dateien liegen heute auch bereits im FHEM/lib/ Verzeichnis, aktualisieren lassen die sich aber wohl auch nicht.
Hast Du dafuer ein Beleg?
Titel: Antw:Update controls_fhem.txt
Beitrag von: Sidey am 22 Februar 2019, 22:33:50
Ich habe mir diesen Weg zwar nicht selbst ausgedacht, aber es mag sein, dass es unkonventionell ist.

Ich bau mir erst mal einen kleinen Workaround. Das Laden via require muss ich mir genauer ansehen, ob das funktioniert.
Es ist halt nicht in allen Fällen die gleiche Datei die geladen werden soll, aber das ist mein Problem. Dazu muss ich mir erst mal die Karten legen.

Grüße Sidey
Titel: Antw:Update controls_fhem.txt
Beitrag von: Ralf9 am 23 Februar 2019, 11:25:07
ZitatEs reicht, wenn du deine Datei "FHEM/lib/signalduino_protocols.pm" nennst, vor dem ersten Klammer
use vars qw(%signalduino_protocols);
%signalduino_protocols =

Ich habe es damit mal versucht
In die signalduino_protocols.pm habe ich folgendes eingetragen:
package signalduino_protocols;
use vars qw(%ProtocolListSIGNALduino);
%ProtocolListSIGNALduino  = (


In die  00_SIGNALduino.pm habe ich folgendes eingetragen:
require "lib/signalduino_protocols.pm";
my %ProtocolListSIGNALduino = %signalduino_protocols::ProtocolListSIGNALduino;


Bis auf ein paar Ausnahmen funktioniert es damit.

"18" => ## Oregon Scientific v1
{
name => 'Oregon Scientific v1',
comment => 'temperature / humidity or other sensors',
id          => '18',
...
method          => \&SIGNALduino_OSV1   # Call to process this message
},
"35" => ## Homeeasy
{
name => 'HE800',
comment => 'Homeeasy',
id          => '35',
...
postDemodulation => \&SIGNALduino_HE800,
},


Damit
    my $method = $ProtocolListSIGNALduino{$id}{method};
    if (!exists &$method)
{
Log3 $name, 5, "$name: Error: Unknown function=$method. Please define it in file $0";
} else {
my ($rcode,$res) = $method->($name,$bitData,$id,$mcbitnum);

stürzt fhem mit folgender Fehlermeldung ab:

Undefined subroutine &signalduino_protocols::SIGNALduino_OSV1 called at ./FHEM/00_SIGNALduino.pm ...


und damit funktioniert es auch nicht:
($rcode,@retvalue) = SIGNALduino_callsub('postDemodulation',$ProtocolListSIGNALduino{$id}{postDemodulation},$name,@bit_msg);

sub SIGNALduino_callsub
{
my $funcname =shift;
my $method = shift;
my $name = shift;
my @args = @_;

if ( defined $method && defined &$method )   
{
#my $subname = @{[eval {&$method}, $@ =~ /.*/]};
Log3 $name, 5, "$name: applying $funcname, value before: @args"; # method $subname";

my ($rcode, @returnvalues) = $method->($name, @args) ;



Gruß Ralf




Titel: Antw:Update controls_fhem.txt
Beitrag von: rudolfkoenig am 23 Februar 2019, 12:58:15
Gibt es einen Grund, warum du in dieser Version auf package ("package signalduino_protocols;") bestehst?
In der .hash Version hast du es nicht verwendet, wenn du es haben willst, dann musst du es konsequent durchziehen.
Titel: Antw:Update controls_fhem.txt
Beitrag von: Ralf9 am 23 Februar 2019, 14:05:12
ZitatGibt es einen Grund, warum du in dieser Version auf package ("package signalduino_protocols;") bestehst?

Ich habe das package reingemacht, da es in der HMCCUConf.pm auch drin ist.

Ohne das "package signalduino_protocols;" und in der 00_SIGNALduino.pm
my %ProtocolListSIGNALduino = %signalduino_protocols::ProtocolListSIGNALduino;
bekomme ich z.B. bei
if (exists($ProtocolListSIGNALduino{$protocol}{format}) && $ProtocolListSIGNALduino{$protocol}{format} eq 'manchester')

diese Fehlermeldung

Global symbol "%ProtocolListSIGNALduino" requires explicit package name at ./FHEM/00_SIGNALduino.pm


Gruß Ralf
Titel: Antw:Update controls_fhem.txt
Beitrag von: Sidey am 23 Februar 2019, 14:22:51
Das SIGNALduino Modul liegt aktuell im Package main.
Jededes Modul muss meines Wissens nach in einem Package liegen.

Egal wo was liegt sind die Variablen aber auch erst mal lokal. Da helfen dann so Bezeichnet wie our.

Das meinte ich übrigens mit Karten legen
Das ist aus meiner Sicht nicht ganz so einfach die Sachen in ein Packages zu verpacken, wenn es Referenzen in beide Richtungen gibt.
Titel: Antw:Update controls_fhem.txt
Beitrag von: betateilchen am 23 Februar 2019, 14:44:18
von einem package hatte Rudi nie gesprochen. Er wollte einfach nur die Variable global verfügbar gemacht haben:

Zitat von: rudolfkoenig am 22 Februar 2019, 21:50:50
Es reicht, wenn du deine Datei "FHEM/lib/signalduino_protocols.pm" nennst, vor dem ersten Klammer

use vars qw(%signalduino_protocols);
%signalduino_protocols =

schreibst,

Ein bewährtes Verfahren, das auch an anderen Stellen in FHEM bereits seit langem verwendet wird.
Titel: Antw:Update controls_fhem.txt
Beitrag von: Ralf9 am 23 Februar 2019, 17:12:28
Wäre es eine Möglichkeit in der ProtocolListSIGNALduino in method anstatt einer Referenz der Subroutine
method          => \&SIGNALduino_OSV1,
den Namen der Subroutine als String zu speichern?
method          =>  "SIGNALduino_OSV1",

Wie müsste dann dies aussehen?
my $method = $ProtocolListSIGNALduino{$id}{method};
my ($rcode,$res) = $method->($name,$bitData,$id,$mcbitnum);

Titel: Antw:Update controls_fhem.txt
Beitrag von: Ralf9 am 23 Februar 2019, 18:12:14
habe was gefunden
https://stackoverflow.com/questions/30236740/generating-a-subroutine-reference-from-a-string
damit funktioniert es

my $method = \&{ $ProtocolListSIGNALduino{$id}{method} };

Titel: Antw:Update controls_fhem.txt
Beitrag von: Ralf9 am 24 Februar 2019, 08:35:53
Zitatvon einem package hatte Rudi nie gesprochen. Er wollte einfach nur die Variable global verfügbar gemacht haben:

Das Problem dabei ist, daß ich bis jetzt noch kein Beispiel gefunden habe wo das auch ohne package funktioniert.

Bei HMCCUConf.pm und UConv.pm werden auch package verwendet.

Gruß Ralf

Titel: Antw:Update controls_fhem.txt
Beitrag von: Sidey am 24 Februar 2019, 09:19:56
Was spricht denn gegen ein Package?

Das Package selbst verursacht doch ohnehin keine Probleme.

Das woran ich hänge ist, zur Laufzeit ein anderes Modul mit gleichem Namen zu laden und die vorhandenen Daten sauber zu ersetzen.
Titel: Antw:Update controls_fhem.txt
Beitrag von: Ralf9 am 03 März 2019, 19:00:35
Es funktioniert inzwischen alles soweit, es ist aber noch ein kleine Frage aufgetaucht.

Ich habe die Protokollhashliste damit in die 00_SIGNALduino.pm eingebunden:
require "lib/signalduino_protocols.pm";
my %ProtocolListSIGNALduino = %signalduino_protocols::ProtocolListSIGNALduino;


Nun wollte ich nach dem editieren der signalduino_protocols.pm diese mit reload neuladen:
Ich habe es mit
reload lib/signalduino_protocols.pm
versucht, bekomme dabei aber die folgende Fehlermeldung:
Can't read ./FHEM/libsignalduino_protocols.pm: No such file or directory
Gibt es eine Möglichkeit ein "/" in die commandline einzugeben?

Gruß Ralf

Titel: Antw:Update controls_fhem.txt
Beitrag von: Sidey am 03 März 2019, 19:14:19
Hi Ralf,

Das neuladen des Perl Modules, wenn es denn wie bei einem Fhem Modul funktioniert, würde dann aber noch immer nicht die Kopie der Variable erneuern.

Was für ein Problem gibt es denn mit der bereits implementierten Variante über

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


Titel: Antw:Update controls_fhem.txt
Beitrag von: Ralf9 am 03 März 2019, 19:44:23
Wie ich schon im github geschrieben habe, erscheint mir das mit dem Laden des Hashes über die Sub SIGNALduino_LoadProtocolHash recht aufwändig und umständlich. Wenn jemand mehrere signalduino Devices hat, wird bei jedem signalduino Device die signalduino_protocols.pm neu geladen und falls zukünftig weitere hashes in der signalduino_protocols.pm dazukommen, wird beim Laden jedes hashes auch signalduino_protocols.pm neu geladen.

sub SIGNALduino_LoadProtocolHash($)
{
if (! -e $_[0]) {
return %{ {"error" => "File does not exsits"}};
}
use Symbol 'delete_package';
delete_package 'SD_Protocols';
delete($INC{$_[0]});
if(  ! eval { require "$_[0]"; 1 }  ) {
return %{ {"error" => $@}};
}
return  %{SD_Protocols->getProtocolList};
}
Titel: Antw:Update controls_fhem.txt
Beitrag von: Sidey am 03 März 2019, 21:32:02
Zitat von: Ralf9 am 03 März 2019, 19:44:23
Wenn jemand mehrere signalduino Devices hat, wird bei jedem signalduino Device die signalduino_protocols.pm neu geladen und falls zukünftig weitere hashes in der signalduino_protocols.pm dazukommen, wird beim Laden jedes hashes auch signalduino_protocols.pm neu geladen.

Wieso meinst Du dass jede Definition das Laden auslöst? Das Laden wir genau 1x für das gesamte Modul ausgelöst.

Diese sub existiert, damit zur Laufzeit und nicht zur compile Zeit eine Perlmodul Datei geladen werden die das Package SD_Protocols und darin eine Funktion getProtocolList bereitstellt.

Was das Laden anderer Variablen angeht, kann ich dir nicht folgen. Die sind nach dem Laden des angegebenen Perlmodules über ihren vollqualifizierten Namen erreichbar und könnten auch über getter subs bereitgestellt werden.

Grüße Sidey