Neu: 98_fhemdebug.pm

Begonnen von rudolfkoenig, 30 Dezember 2016, 13:58:25

Vorheriges Thema - Nächstes Thema

rudolfkoenig

Da in der letzten Zeit die "Error: >< has no TYPE, but following keys: ><" Meldungen sich haeufen, moechte ich den Benutzer Tools in die Hand geben, um das Problem zu finden.

Ab sofort wird nach der Ausgabe dieser Fehlermeldung der Eintrag geloescht: es hilft ja nicht, den Benutzer mit der gleicher Meldung weiter zu nerven. Ausserdem wusste man nicht, ob der Eintrag nur ganz selten oder immer wieder erzeugt wird. Ich habe auch die Abfrage in fhemFork umgestellt, so dass die Warnung in der Zeile 4672 wohl nicht mehr auftreten wird. Im AnalyzePerlCommand wird ein Perl-Fehler mit ausgefuehrten Befehl geloggt, das wurde bisher nur als Text zurueckgeliefert, und es lag am Aufrufenden es auszugeben. Wenn das irgendwo zu Problemen fuehrt, bitte melden.

Weiterhin habe ich ein neues Befehl fhemdebug angelegt, was beim aktivieren (fhemdebug enable) ein Wrapper um CallFn aktiviert, und jeweils vorher und nachher %defs auf kaputte Eintraege untersucht. Im Gegensatz zu apptime kann man den Wrapper ohne Performance-Einbussen und FHEM-Restart deaktivieren, eine fhem.pl Aenderung war dazu auch nicht notwendig.

Falls jemand noch Ideen fuer weitere sinnvolle Pruefungen in fhemdebug hat: bitte melden.

Loredo

#1
Ich bin dem ganzen etwas mehr auf die Spur gekommen.

Es gibt Module, die prüfen auf die Existenz von INTERNALs, ohne vorher auf den Hash $defs{$devname} zu prüfen.
Folgendes erzeugt bei mir einen leeren Hash in $defs{$devname}:


my $devname = "non-existent-device-name";
if ( !defined($defs{$devname}{TYPE}) ) {
Dumper ($defs{$devname});
}


Ich schlage deshalb vor, dass man Modulautoren eine neue Funktion IsDevice() bereitstellt, die man anstelle von der defined() Prüfung verwenden kann und bei der man nicht jedes Mal die Hash-Hierarchie (also "defined($defs{$devname}) && defined($defs{$devname}{TYPE})" ) mit überprüfen muss.

In beiliegendem Patch habe ich noch einige andere Zusatzprüfungen mit eingebaut, die dann wirklich sicherstellen sollten, dass es ein bestimmtes Gerät in FHEM tatsächlich gibt und dass es ordnungsgemäß initialisiert wurde. Außerdem erschien es mir in diesem Zusammenhang sinnvoll dann auch noch die Funktion GetType() zu ergänzen.

Ich habe außerdem auch die Funktionen IsDummy(), IsIgnored(), IsDisabled(), IsIoDummy(), GetLogLevel() und GetVerbose() entsprechend angepasst.


Die Änderungen habe ich bei mir kurz getestet und konnte keine Schwierigkeiten damit feststellen.
Daher fände ich es prima, wenn der Patch so übernommen werden würde.



Gruß
Julian
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

Reinerlein

Hi Julian,

hmm.. was genau erzeugt denn dann diesen leeren Device-Eintrag?
Die Prüfung mittels "defined" oder das folgende Dumper()?

Die Prüfung mittels defined auf TYPE habe ich in meinem Sonos-Modul auch drin, und das wird haufenweise aufgerufen. Das müsste/sollte ich dann ja wohl umbauen...

Danke schon mal...

Grüße
Reiner

Loredo

Tatsächlich erzeugt der bloße Aufruf des defined() den leeren Hash.
Ich habe es gerade bei einer ganzen Reihe meiner Module korrigiert und in jedes eigene Subroutinen eingebaut. IsDevice() zentral einzubauen könnte sich also lohnen.
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

rudolfkoenig

Wenn man $hash{x}{y} hinschreibt, und $hash{x} nicht existiert, dann wird $hash{x} angelegt. defined() kommt erst spaeter, und ist unschuldig. Wenn man unsicher ist, ob $hash{x} existiert, dann muss man ($hash{x} && $hash{x}{y}) hinschreiben. Das gilt natuerlich auch fuer tiefere Datenstrukturen: bei der Pruefung auf $hash{x}{y}{z} wird $hash{x}{y} angelegt.

ZitatIch schlage deshalb vor, dass man Modulautoren eine neue Funktion IsDevice() bereitstellt, die man anstelle von der defined() Prüfung verwenden kann
Statt IsDevice zu verwenden sollten die Modulautoren lieber begreifen, wann perl einen Hash-Eintrag anlegt, sonst werden sie kaputte Hash-Eintraege anderswo anlegen ($attr, $defs{X}{READINGS}{bla}, $modules, etc).

Ich behaupte auch, dass ein IsDevice-Aufruf in IsDummy/IsIgnored/IsDisabled/GetVerbose ueberfluessig ist: diese Funktionen erzeugen keine leeren hash Eintrage. Und so billig ist IsDevice auch nicht, dass man sie wahllos ueberall aufrufen sollte.

Reinerlein

Hi,

damit wären meine Routinen aus dem Schneider, da ich sowieso nur über die vorhandenen Devicenamen iteriere, und somit niemals einen nicht vorhandenen Devicenamen prüfe :)

Hätte mich auch gewundert, da sie so seit mehreren Jahren in Betrieb sind...

Danke für die Aufklärung...

Grüße
Reiner

Loredo

Zitat von: rudolfkoenig am 01 April 2017, 21:11:28
Statt IsDevice zu verwenden sollten die Modulautoren lieber begreifen, wann perl einen Hash-Eintrag anlegt, sonst werden sie kaputte Hash-Eintraege anderswo anlegen ($attr, $defs{X}{READINGS}{bla}, $modules, etc).


Ist hiermit begriffen (falls das nicht schon deutlich geworden sein sollte).


Zitat von: rudolfkoenig am 01 April 2017, 21:11:28
Ich behaupte auch, dass ein IsDevice-Aufruf in IsDummy/IsIgnored/IsDisabled/GetVerbose ueberfluessig ist: diese Funktionen erzeugen keine leeren hash Eintrage. Und so billig ist IsDevice auch nicht, dass man sie wahllos ueberall aufrufen sollte.


Auch User können in ihren myUtils Scripten diese Fehler begehen. Würde man sie IsDevice() und GetType() benutzen lassen, würde man es vereinfachen.
Sie müssen aber nicht unbedingt in vorhandene Funktionen eingebaut werden, das war nur ein Vorschlag.


Ich würde deshalb gerne beantragen diese beiden Funktionen zumindest separat zentral bereitzustellen.




-Julian
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

rudolfkoenig

ZitatAuch User können in ihren myUtils Scripten diese Fehler begehen. Würde man sie IsDevice() und GetType() benutzen lassen, würde man es vereinfachen.

Sehen das andere auch so? Ich bin wg. der vielen Pruefungen in IsDevice etwas zurueckhaltend.
In welcher Situation moechte ein Benutzer IsDevice oder GetType aufrufen?

CoolTux

Hallo Julian, hallo Rudi

Ich denke und bin der Meinung wenn schon ein User so tief ins FHEM System oder eigentlich in Perl eintaucht, dann sollte er auch wissen oder spätestens dann lernen wie man existierende Hash's richtig ab fragt.
Dann lieber den User die Frage stellen lassen und wir wissenden beantworten es dann. Das ist doch schon tieferes Perl als das was man sonst für eine myUtils verwendet.



Grüße
Leon
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Benni

Zitat von: CoolTux am 02 April 2017, 09:05:06
Ich denke und bin der Meinung wenn schon ein User so tief ins FHEM System oder eigentlich in Perl eintaucht, dann sollte er auch wissen oder spätestens dann lernen wie man existierende Hash's richtig ab fragt.

Und irgendwoher wird ohne zu hinterfragen ein Codeschnipsel kopiert und geht auf reisen....

Loredo

#10
Die Bedenken im Bezug auf die Performance kann ich nachvollziehen.

Wie wäre es mit zwei separaten Subroutinen?
Beilegender Patch sollte die Performance von IsDevice() und GetType() deutlich erhöhen.

Die zweite Subroutine AnalyzeDevice() lässt sich zu Debugging-Zwecken temporär an Stellen im Code während der Modulentwicklung oder der Entwicklung von myUtils Subroutinen einbauen. Zu diesem Zweck habe ich auch einen Patch Vorschlag für 98_fhemdebug angehängt.

Ich würde IsDevice() und GetType() gerne so in meinen Modulen zur Codeoptimierung verwenden.




Gruß
Julian
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

Loredo

#11
Folgende Variante liefert die Logfile Ausgabe alternativ als Array zurück.



Gruß
Julian
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

rudolfkoenig

#12
ZitatFolgende Variante liefert die Logfile Ausgabe alternativ als Array zurück.
diese Aussage ist etwas irrefuehrend: es gibt eine _neue_ Funktion AnalyzeDevice (mit 90 Zeilen) die zum debugging dient, und optional die Fehler als Array zurueckliefert. Eine Fehlermeldung im Log ist nicht optional. Mir ist z.Zt. noch nicht klar, wann und wie man sie einsetzen soll, im Dauerbetrieb finde ich es nicht empfehlenswert.

Falls noch wer fuer die Aufnahme dieser Funktionen stimmt, dann werde ich sie einchecken. Wobei ich den Einsatz einer zusaetzlichen Funktion im AnalyzeDevice erwaege, um die Groesse zu reduzieren.

Edit: sorry, habe den Beitrag davor uebersehen. Den Text "diese Aussage ist etwas irrefuehrend" bitte streichen.

Loredo

#13
Zitat von: rudolfkoenig am 03 April 2017, 11:05:46
Eine Fehlermeldung im Log ist nicht optional.

Es wird davon ausgegangen, dass man entweder das Feedback im Log sehen oder alternativ selbst als Array weiterverarbeiten (und dann ggf. selbst loggen) will.
Für fhemdebug ist für eine bessere Performance eingebaut, dass die Abfrage frühestmöglich endet; ansonsten werden alle Prüfungen durchgeführt und dann eine gesammelte Rückmeldung entweder als einzelner Logfile Eintrag oder als Array gegeben. Gar kein Feedback oder Log schien mir wenig sinnvoll bzw. entspricht es so dem aktuellen Verhalten von fhemdebug.

Zitat von: rudolfkoenig am 03 April 2017, 11:05:46
Mir ist z.Zt. noch nicht klar, wann und wie man sie einsetzen soll, im Dauerbetrieb finde ich es nicht empfehlenswert.

Stimme ich zu. Man kann die Funktion gezielt an bestimmten Stellen im Modulcode temporär zur Qualitätssicherung einbauen und damit ggf. genauer einkreisen statt nur auf fhemdebug zu setzen.

Unabhängig von AnalyzeDevice() wäre ich fürs einchecken der Funktionen IsDevice() und GetType() dankbar.
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

rudolfkoenig

Will nicht bockig sein: habe die beiden Funktionen eingecheckt.

Gegen AnalyzeDevice haette ich auch nichts, wenn
- es einen sprechenderen Namen kriegen wuerde :)
- in einem optional geladenen Modul wie fhemdebug ausgelagert waere.

Loredo

Danke.


Ich hänge nicht an der Funktion AnalyzeDevice(), ich wollte der Community nur einen Gefallen damit tun...
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER