Hallo,
ich arbeite gerade an einem Modul und möchte als Internal die Versionsnummer ausgeben.
Wenn ich "$hash->{VERSION} = "0.95;" in der define-Funktion setze, wird das beim "reload" in FHEM nicht uebernommen, nur wenn ich das DEF z.B im Frontend aendere (Modify) oder beim neu anlegen eines Device funktionierts logischerweise, da define durchlaufen wird.
Wenn ich "$hash->{VERSION} = "0.95;" in der Initialize-Funktion aufrufe, wird die Version bei "reload" auch nicht gesetzt, obwohl die Funktion definitiv durchlaufen wird.
Was mache ich falsch ?
Gruss
Joe
Es gibt bereits ein version Befehl fuer sowas.
Wenn es unbedingt sein muss (Hinweis: muss vmtl. nicht), dann musst Du in .pm Code ohne Funktion schreiben, der alle $defs prueft, und sie korrigiert.
Ich finde die Version eines Moduls gehoert zum Modul selbst und sollte direkt dort sichtbar sein.
Für den Ersteller auch sehr hilfreich in der Entwicklungsphase, wenn ein LIST des Devices hier ins Forum gestellt wird, um zu sehen, welche Version wirklich verwendet wird.
Man koennte die vorhandene Version ja auch als Standard-Internal in jedes Modul schreiben ? Das waere perfekt ...
Das hier verstehe ich allerdings nicht :
, dann musst Du in .pm Code ohne Funktion schreiben, der alle $defs prueft, und sie korrigiert.
Gruss
Joe
Kann das sonstwer erklaeren? Ich komme immer wieder auf die gleiche Formulierung.
Ich habe auch schon öfters die Versionsangabe im list-Output vermisst. Eine genaue Analyse eines Problems lässt sich oft nur mit Hilfe der Interna des Moduls vornehmen. Nach dem Post des list-Ausdruck kommt dann aber immer die Frage .... und welche Version?
Gruß
Damian
Direkt nach einem version zu fragen ist zu anstrengend?
Zitat von: marvin78 am 21 November 2016, 16:53:24
Direkt nach einem version zu fragen ist zu anstrengend?
Evtl. sinnvolle Neuerungen totzureden, die Allen dienen, ist anstrengend ...
Was wäre denn das Argument dagegen, die Version als Internal im Device abzulegen ?
Gruss
Joe
my $version = "2.6.6";
sub Präfix_Initialize($) {
...
...
foreach my $d(sort keys %{$modules{TYPENAME}{defptr}}) {
my $hash = $modules{TYPENAME}{defptr}{$d};
$hash->{VERSION} = $version;
}
sub Prefäx_Define($$) {
...
...
$modules{TYPENAME}{defptr}{$hash->{EINDEUTIGESINTERNAL}} = $hash;
}
}
Es gibt einige Beispiele in Modulen. AMAD, HOMEBOT, NUKIBridge und so weiter. Das eindeutige Internal kann z.B. ein Host sein oder eine MAC
ZitatWas wäre denn das Argument dagegen, die Version als Internal im Device abzulegen ?
Information, was man auch sonst zur Verfuegung hat, zu duplizieren.
$hash wird weiter aufgeblaeht.
Benutzer interessiert es nicht.
CommandDefine/CommandReload/etc muss erweitert werden.
Will nicht sagen, dass, wenn ich ueberstimmt werde, es nicht einbauen werde, aber du hast nach Argumenten gefragt.
@CoolTux: dein Beispiel ist nicht "reload-safe" (wie urspruenglich gefragt), weil die Funktionen bei reload nicht ausgefuehrt werden.
Deswegen muss der Code ausserhalb von jeglicher Funktion sein.
Gäbe es ein globales Event 'RELOAD <module name>', dann könnte man so etwas in der NotifyFn neu setzen. Wäre auch hilfreich, wenn man bspw. einen set command hash dynamisch erweitert. Dieser hash ist nach einem reload auch zurückgesetzt.
Nur so ne Idee ;)
Zitat von: rudolfkoenig am 21 November 2016, 17:31:14
@CoolTux: dein Beispiel ist nicht "reload-safe" (wie urspruenglich gefragt), weil die Funktionen bei reload nicht ausgefuehrt werden.
Deswegen muss der Code ausserhalb von jeglicher Funktion sein.
Hallo Rudi,
Präfix_Initialize wird aber doch bei einem reload ausgeführt. Zu mindestens funktioniert es bei mir und das in mehreren Modulen.
Grüße
@CoolTux: sorry, du hast natuerlich Recht.
Wg. RELOAD Event: braucht das jemand?
Wie CoolTux das richtig sagt, Modulintern kann man sowas auch mit der Initialize Funktion erledigen.
Und ich finde das ist auch völlig ausreichend.
Was die Sinnhaftigkeit an geht. Nun das liegt denke ich mal am Stil des Entwicklers. Ich habe gerne eine eigene Versionierung meiner Module. Sie trennen unter anderem zwischen Devel und Stable. Speziell bei AMAD ist es sogar nötig. Ansonsten gebe ich Rudi Recht, wenn der Author selbst sowas nicht braucht oder gar das Modul. Ist es nur ein Klotz am Bein von $hash.
Grüße
eine echte versionsnummer (am besten inkl. releasedate) eines moduls finde ich wesentlich informativer, als eine laufende svn-id. ich freue mich auch über jedes modul, das mir solch eine nummer in den internals bereitstellt.
dadurch fällt zb ein zunächst verschobener und dann vergessener restart nach einem update wesentlich schneller auf. ;)
RELOAD: Wenn die InitializeFn abgearbeitet wird, dann sind die Attribute noch nicht gesetzt, wenn ich es richtig in Erinnerung habe. Das Beispiel mit dem cmd hash kann man aber z.B. am Anfang der SetFn überprüfen und ggf. setzen, wenn man den hash anhand von Attributen erweitert hat.
Ich fände das Event praktisch aber nicht unbedingt nötig.
Hi,
ich verstehe es noch nicht ganz.
Wenn ich z.B. $hash->{VERSION} = "0.95"; fest in der Initialize-Funktion am Ende setze, wird es bei reload
nicht uebernommen. (
Initialize wird aber definitiv durchlaufen)
Wenn ich dort ein Attribut hinzufuegen, ist es danach sofort vorhanden. Das verstehe ich eben nicht.
sub LevelJET_Initialize($) {
my ($hash) = @_;
Log3 $hash->{NAME}, 1, "$hash->{TYPE} $hash->{NAME}->*** Funktion Initialize ***";
require $attr{global}{modpath} . '/FHEM/DevIo.pm';
$hash->{SetFn} = 'LevelJET_Set';
$hash->{ReadFn} = 'LevelJET_Read';
$hash->{ReadyFn} = 'LevelJET_Ready';
$hash->{DefFn} = 'LevelJET_Define';
$hash->{UndefFn} = 'LevelJET_Undef';
$hash->{AttrFn} = 'LevelJET_Attr';
$hash->{AttrList} = 'PollingRate';
$hash->{VERSION} = $VERSION;
}
CoolTux hat dieselbe Anweisung immer
2 mal drin. Im Initialize
UND im Define. Warum das bei ihm funktioniert ist mir noch nicht klar. Doppelt finde ich aber nicht gut.
Zitat von: rudolfkoenig am 21 November 2016, 17:31:14
Information, was man auch sonst zur Verfuegung hat, zu duplizieren.
$hash wird weiter aufgeblaeht.
Benutzer interessiert es nicht.
CommandDefine/CommandReload/etc muss erweitert werden.
Die Argumente ziehen nicht wirklich ;)
Es gibt genuegend Parameter die den Benutzer noch weniger interessieren wie (FD), DeviceName (sogar doppelt wie im DEF) ...
Dass es einmalige Arbeit ist ist mir klar. Das ist immer so.
Mit dem aufblähen des Hash geb ich Dir Recht, aber ich fände es extrem gewinnbringend !
Jedes Programm im Internet hat eine eindeutige Versionsnummer und die steht meist ganz vorne auf jeder GUI oder zumindest im Info-Dialog für jeden Benutzer zugänglich.
Wäre schön wenn die Version als Internal umgesetzt werden könnte.
Andernfalls sollte mir nochmals jemand erklären, wie ich es schaffe das in meinem Modul im Initialize richtig einzubauen bzw. was fehlt :-[ ...
Gruss
Joe
Zitat von: cotecmania am 21 November 2016, 19:21:00
Hi,
ich verstehe es noch nicht ganz.
Wenn ich z.B. $hash->{VERSION} = "0.95"; fest in der Initialize-Funktion am Ende setze, wird es bei reload nicht uebernommen. (Initialize wird aber definitiv durchlaufen)
Wenn ich dort ein Attribut hinzufuegen, ist es danach sofort vorhanden. Das verstehe ich eben nicht.
sub LevelJET_Initialize($) {
my ($hash) = @_;
Log3 $hash->{NAME}, 1, "$hash->{TYPE} $hash->{NAME}->*** Funktion Initialize ***";
require $attr{global}{modpath} . '/FHEM/DevIo.pm';
$hash->{SetFn} = 'LevelJET_Set';
$hash->{ReadFn} = 'LevelJET_Read';
$hash->{ReadyFn} = 'LevelJET_Ready';
$hash->{DefFn} = 'LevelJET_Define';
$hash->{UndefFn} = 'LevelJET_Undef';
$hash->{AttrFn} = 'LevelJET_Attr';
$hash->{AttrList} = 'PollingRate';
$hash->{VERSION} = $VERSION;
}
CoolTux hat dieselbe Anweisung immer 2 mal drin. Im Initialize UND im Define. Warum das bei ihm funktioniert ist mir noch nicht klar. Doppelt finde ich aber nicht gut.
Du hast ja auch mein Beispiel gar nicht übernommen. Meine Initialize sieht jedenfalls anders aus wie Deine. Wo ist deine foreach Schleife über alle Devices Seines Types?
@cotecmania: Gegen tatsächlich für alle sinnvolle Änderungen habe ich nichts. Sehr wohl aber gegen Redundanz und bei denen nur aus einer bestimmten Sichtweise ein Sinn vorhanden ist. Es gibt schon version. Das wird auch seit Jahren für den Support verwendet. Wenige Module haben bisher eine eigene (redundante) Versionsanzeige und beim "Cross-Support" würde ich mich nicht darauf verlassen.
Grundsätzlich habe ich aber nichts gegen Neuerungen, für die nicht andere, als die, die sie sich wünschen, arbeiten müssen. ;)
Ein reload-Event fände ich allerdings schon interessant :)
sub LevelJET_Initialize($)
{
my ($hash) = @_;
Log3 $hash->{NAME}, 1, "$hash->{TYPE} $hash->{NAME}->*** Funktion Initialize ***";
require $attr{global}{modpath} . '/FHEM/DevIo.pm';
$hash->{SetFn} = 'LevelJET_Set';
$hash->{ReadFn} = 'LevelJET_Read';
$hash->{ReadyFn} = 'LevelJET_Ready';
$hash->{DefFn} = 'LevelJET_Define';
$hash->{UndefFn} = 'LevelJET_Undef';
$hash->{AttrFn} = 'LevelJET_Attr';
foreach my $d(sort keys %{$modules{LevelJET}{defptr}})
{
my $hash = $modules{LevelJET}{defptr}{$d};
$hash->{VERSION} = $VERSION;
}
# $hash->{VERSION} = $VERSION;
}
So gehts aber auch nicht. Eben getestet. oder hab ich was falsch übernommen ?
Hier muss man aber von Hand den eigenen Modulnamen eintragen, oder ?
Habs Gespeichert->reload->device neu in FHEM angezeigt
Im AMAD-Modul gehts, also muss noch was anderes fehlen ausserhalb Initialize ...
Gruss
Joe
Ja und zwar die Zeile im Define die ist das Ah und Oh und muss mindestens einmal ausgeführt werden.
$modules{AMAD}{defptr}{$hash->{HOST}} = $hash;
Zitat von: marvin78 am 21 November 2016, 19:51:37
@cotecmania: Gegen tatsächlich für alle sinnvolle Änderungen habe ich nichts. Sehr wohl aber gegen Redundanz und bei denen nur aus einer bestimmten Sichtweise ein Sinn vorhanden ist. Es gibt schon version. Das wird auch seit Jahren für den Support verwendet. Wenige Module haben bisher eine eigene (redundante) Versionsanzeige und beim "Cross-Support" würde ich mich nicht darauf verlassen.
Grundsätzlich habe ich aber nichts gegen Neuerungen, für die nicht andere, als die, die sie sich wünschen, arbeiten müssen. ;)
Ein reload-Event fände ich allerdings schon interessant :)
Nunja. Sichtweisen sind nun mal unterschiedlich ;)
Und dass nicht jeder, der sich was wünscht, dies auch in FHEM einbauen kann ist auch klar. Deshalb wirds ja hier diskutiert.
Wenn ich einen Patch hätte, würde ich ihn glatt zur Verfügung stellen :o
Die selbe Diskussion hatten wir beim AT-Befehl auch und der execNow-Erweiterung, die ich vorgeschlagen hatte.
Die hat Rudi dann, Gott sei Dank, eingebaut. Danke nochmals dafür. Ich benutze die ständig ;)
Gruss
Joe
Zitat von: CoolTux am 21 November 2016, 19:59:58
Ja und zwar die Zeile im Define die ist das Ah und Oh und muss mindestens einmal ausgeführt werden.
$modules{AMAD}{defptr}{$hash->{HOST}} = $hash;
AMAD durch LevelJET ersetzt und HOST durch DeviceName.
Dann musste ich aber noch einmal die define-Funktion durchlaufen. Jetzt gehts.
$modules{LevelJET}{defptr}{$hash->{DeviceName}} = $hash;
DeviceName -> /dev/serial/by-id/usb-FTDI_USB_Serial_Converter_FT9JQDYQ-if00-port0@19200
Ziemlich undurchsichtig für mich. Bin kein PERL-Kenner, komme aus der C-Welt.
Das "harte" Kodieren des Modulnamens im Initialize ist auch nicht gerade schön
Trotzdem mal Danke für deine Geduld ...
Hast Du es denn nun hinbekommen?
Du brauchst eine schleife über alle keys aus %defs. $defs{key} ist jeweils der $hash eines definierten devices. du schaust nach ob es von deinem TYPE ist. wenn ja änderst du was du brauchst. Das machst Du im LevelJET_Initialize.
Vorher musst Du defptr natürlich im Define noch setzen. Das habe ich Dir zwei Post vorher ja geschrieben.
Nimm nicht unbedingt den Devicenamen. Hast du noch eine andere Einmaligkeit als Internal?
Zitat von: CoolTux am 21 November 2016, 20:24:21
Nimm nicht unbedingt den Devicenamen. Hast du noch eine andere Einmaligkeit als Internal?
Ja es geht, wie oben geschrieben.
Leider hab ich sonst keine "Einmaligkeit". Der LevelJET liefert auch keine ...
Mein DeviceName ist eindeutig da "echter" FTDI, aber Du hast recht, bei einem "normalen" ttyUSBx kanns evtl Probleme geben bei reboot ...
Also keine universelle Lösung, wenn es keine eindeutige ID etc. gibt, oder ?
Gruss
Joe
Korrekt. Aber du kannst ja eine zur Not machen. Wäre nicht fein aber würde das Problem erschlagen. ;D