DOIF/Tools und Fehlersuche: Unterschied zwischen den Versionen

Aus FHEMWiki
(→‎Verhaltensanalyse des DOIF: Debug DOIF via Device Dump ergänzt)
K (nur ein Überschrift in der Zeile, sonst wird er nicht als solcher erkannt)
 
(9 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 25: Zeile 25:
</pre>
</pre>


=== FHEM aktuell halten ==={{Randnotiz|RNTyp=y|RNText=Die aktuelle FHEM-Software ist ein "nightly build", es gibt keine ausgewiesene "stable version".
=== FHEM aktuell halten ===
{{Randnotiz|RNTyp=y|RNText=Die aktuelle FHEM-Software ist ein "nightly build", es gibt keine ausgewiesene "stable version".


Um Überraschungen zu vermeiden, sollte vor einem Update im Forum nach Fehlerhinweisen zu den genutzten Modulen recherchiert werden.
Um Überraschungen zu vermeiden, sollte vor einem Update im Forum nach Fehlerhinweisen zu den genutzten Modulen recherchiert werden.
Zeile 52: Zeile 53:
durchführen.
durchführen.


==== Neustart nach Update automatisieren ===={{Randnotiz|RNTyp=y|RNText=Durch diese Automatik kann unter anderem die Anzeige der Änderungs-Informationen (CHANGED) zum Update, durch ein Neuladen der Browserseite, sofort wieder ausgeblendet werden, so dass die Änderungs-Informationen im Logfile oder svn/Forum gelesen werden müssen.}}
==== Neustart nach Update automatisieren ====
{{Randnotiz|RNTyp=y|RNText=Durch diese Automatik kann unter anderem die Anzeige der Änderungs-Informationen (CHANGED) zum Update, durch ein Neuladen der Browserseite, sofort wieder ausgeblendet werden, so dass die Änderungs-Informationen im Logfile oder svn/Forum gelesen werden müssen.}}
"shutdown restart" kann man per notify automatisieren mit
"shutdown restart" kann man per notify automatisieren mit
<pre>
<pre>
Zeile 96: Zeile 98:
</pre>
</pre>
gemeint.
gemeint.
* Nichtbeachtung des unterschiedlichen Verhalten von auslösenden und nicht auslösenden Readings.
* Nichtbeachtung des unterschiedlichen Verhalten von triggernden und nicht triggernden [[DOIF/Einsteigerleitfaden,_Grundfunktionen_und_Erläuterungen#Ausl.C3.B6ser|Auslöserangaben]].
* Ein unerwartetes Auslösen von DOELSE.
* Ein unerwartetes Auslösen von DOELSE.
* Unerwartete Ereignisse eines Gerätes, die in einer Bedingung nicht abgefangen werden.
* Unerwartete Ereignisse eines Gerätes, die in einer Bedingung nicht abgefangen werden.
* Falsche Angabe der Events eines beteiligten Gerätes.
* Falsche Angabe der Events eines beteiligten Gerätes.
* Es wir DOELSE mit einer Bedingung angegeben.
* Es wird DOELSE mit einer Bedingung angegeben.


===Besonderheit des Error-Reading===
===Besonderheit des Error-Reading===
Zeile 111: Zeile 113:
<pre>({my $var = 1;; 0})</pre>
<pre>({my $var = 1;; 0})</pre>
Die mit ";; 0" angehängte Null verhindert das Setzen des Error-Readings.
Die mit ";; 0" angehängte Null verhindert das Setzen des Error-Readings.
===Adressierung von Arrayelementen===
Die Adressierung von Arrayelementen <code>$myArray[4]</code> kann zu Fehlverhalten führen, weil die eckigen Klammern als DOIF-Syntax interpretiert werden. Das gilt nicht für den Block ''subs'' im Perl-Mode. Altervativ könnte z.B. ein numerierter Hash verwendet werden <code>$myArrayAsHash{4}</code>.


=== Fehler eingrenzen ===
=== Fehler eingrenzen ===
Zeile 125: Zeile 130:
===Bedingungen testen mit dem Befehl [[Trigger|trigger]]===
===Bedingungen testen mit dem Befehl [[Trigger|trigger]]===
Manche [[Event|Events]] lassen auf sich warten, um die Bedingung vorher zu testen kann der Befehl [[Trigger|trigger]] verwendet werden.
Manche [[Event|Events]] lassen auf sich warten, um die Bedingung vorher zu testen kann der Befehl [[Trigger|trigger]] verwendet werden.
<pre>trigger <Gerätename> &lang;<Readingname>: &rang;<Wert></pre>
  trigger <[[Gerätename]]> &lang;<Readingname>: &rang;<Wert>
Das funktioniert dort, wo die [http://fhem.de/commandref_DE.html#DOIF_Ereignissteuerung_ueber_Auswertung_von_Events Auslösung über Events] in der Bedingung genutzt wird.
Das funktioniert dort, wo die [http://fhem.de/commandref_DE.html#DOIF_Ereignissteuerung_ueber_Auswertung_von_Events Auslösung über Events] in der Bedingung genutzt wird.
=== Bedingungen testen mit dem Befehl setreading ===
Manche [[Readings]] Aktualisierungen lassen auf sich warten, um die Bedingung vorher zu testen kann der Befehl setreading verwendet werden.
  setreading <[[Gerätename]]> <Readingname> <Wert>
Siehe auch {{Link2CmdRef|Anker=setreading|Lang=de}}.
=== Operatoren loggen, die keine Bedingungsprüfung auslösen (triggern) ===
Operatoren, die keine Bedingungsprüfung auslösen, werden im Listing des DOIF nicht angezeigt.
Sie können geloggt werden, durch die Angabe eines Log-Befehls in der Bedingung.
==== Allgemein ====
  (<Bedingung>; Log <verbose level>, <content to log>)
==== Vorschlag ====
  (<Bedingung>; Log 1, "$SELF:"."\n<name1>:<reading1> ".ReadingsVal("<name1>","<reading1>","<default1>")."\n<name2>:<reading2> ".ReadingsVal("<name2>","<reading2>","<default2>")...)
Siehe auch: {{Link2Forum|Topic=99365|Message=927748|LinkText=alternativer Vorschlag}} oder [[DevelopmentModuleAPI#Log|Log-Befehl]]


== Hilfsmittel zu Fehleranalyse ==
== Hilfsmittel zu Fehleranalyse ==
Zeile 207: Zeile 226:
* Alle relevanten Fehlermeldungen
* Alle relevanten Fehlermeldungen
* Darstellen, was man selbst schon versucht hat und mit welchem Ergebnis, dann wird es nicht noch einmal vorgeschlagen.
* Darstellen, was man selbst schon versucht hat und mit welchem Ergebnis, dann wird es nicht noch einmal vorgeschlagen.
* Ein für andere ausführbares [[DOIF/Einsteigerleitfaden,_Grundfunktionen_und_Erläuterungen#Beispiel_A.29:_Ereignissteuerung|'''Testszenario''']] für [[Import_von_Code_Snippets|Raw definition]], mit Dummys als Ersatz für Sensoren, Schalter, Aktoren usw.
* Angabe der vollständigen Definition des DOIF (Name, Definition, Attribute) in Code-Tags (das Raute-Zeichen # im Forum-Editor)
* Angabe der vollständigen Definition des DOIF (Name, Definition, Attribute) in Code-Tags (das Raute-Zeichen # im Forum-Editor)
* Zusätzlich ein vollständiges '''[[List|Listing]]''' des DOIF
* Zusätzlich ein vollständiges '''[[List|Listing]]''' des DOIF

Aktuelle Version vom 9. August 2023, 07:20 Uhr

Anmerkung: Dieser Artikel wurde aus dem Forum übernommen.

Dies ist der Versuch einige Hilfen aufzuzeigen, damit ein fehlerhaftes DOIF selbst korrigiert werden kann und wenn dies nicht zum Ziel führt, notwendige Angaben für eine Anfrage im Forum zusammenzustellen.

Eine verlässliche Basis zur Fehlereingrenzung schaffen.

Standardisierte Geräteerstellung und Bearbeitung

Im Folgenden wird davon ausgegangen, dass zum Erstellen des DOIF und zur Befehlseingabe die Eingabezeile des Web-Frontends benutzt wird und mit dem DEF-Editor (auf DEF klicken) in der sich öffnenden Geräteübersicht (DeviceOverview) bearbeitet wird, ohne eine cfg-Datei zu editieren.

Nutzung des integrierten DEF-Editors mit Codemirror-Erweiterung, Codemirror einrichten und bedienen, siehe ergänzend DOIF: Tips leichtere Bedienung Syntaxhervorhebung Klammerprüfung Suchen&Ersetzen

Strukturierung der Definition

Eine einzeilige Definition, die über mehrere Seiten verschoben werden muss oder über mehrere Zeilen umgebrochen wird ist unübersichtlich. Der DEF-Editor bietet die Möglichkeit zur Strukturierung der Definition.

## 1
(<Bedingung>)
   (<Befehle>)
## 2
DOELSEIF (<Bedingung>)
   (<Befehle>)
## 3
DOELSEIF (<Bedingung>)
   (<Befehle>)
...

FHEM aktuell halten

Emblem-question-yellow.svgDie aktuelle FHEM-Software ist ein "nightly build", es gibt keine ausgewiesene "stable version".

Um Überraschungen zu vermeiden, sollte vor einem Update im Forum nach Fehlerhinweisen zu den genutzten Modulen recherchiert werden.

Die Änderungshinweise sollten beachtet werden, da die Änderungshinweise nicht verpflichtend sind, sollten auch die Hinweise in den FHEM Code changes gelesen werden.

Nach einem Update sollte immer das Logfile nach neuen Fehler- u. Warnmeldungen untersucht werden.

Eine Automatisierung des Updatevorgangs oder Teile davon ist -gerade auch für Einsteiger- nicht unbedingt empfohlen. Sie sollte nur unter genauer Kenntnis möglicher Folgen eingesetzt werden und geschieht immer auf eigene Gefahr.

Die Befehlsreferenz im Netz beschreibt die Eigenschaften des aktuellen Moduls. Möchte man die neusten Eigenschaften nutzen, ist eine Aktualisierung durchzuführen. Wird nur das Modul aktualisiert, kann das zu unerwartetem Verhalten des DOIF führen.

Prüfen ob ein Update für DOIF vorliegt mit

update check

FHEM aktualisieren mit

update

Nach einem "update" immer ein

shutdown restart

durchführen.

Neustart nach Update automatisieren

Emblem-question-yellow.svgDurch diese Automatik kann unter anderem die Anzeige der Änderungs-Informationen (CHANGED) zum Update, durch ein Neuladen der Browserseite, sofort wieder ausgeblendet werden, so dass die Änderungs-Informationen im Logfile oder svn/Forum gelesen werden müssen.

"shutdown restart" kann man per notify automatisieren mit

define shutdown_restart notify global:UPDATE save;shutdown restart

Modulversionen anzeigen

Der Befehl

version

liefert die "Latest Revision:" und die aktuell geladenen Modulversionen.

Fehlersuche

DOIFtools enthält einen Check für DOIF, der einige Dinge erkennt und Hinweise gibt, siehe DOIF_Prüfung_und_Empfehlungen.

Fehler in der Syntax der Definition

Diese Fehler werden durch die Benutzung des DEF-Editors mit Codemirror-Erweiterung reduziert.

Der Editor unterstützt:

  • farbliche Hervorhebung bekannter Befehle
  • Vervollständigung bekannter Begriffe
  • eine Prüfung auf unvollständige Klammerpaare
  • ggf. Fehlermeldung beim Erstellen einer Definition
  • Suchen&Ersetzen
  • uvm.

Einige Syntaxfehler werden im Frontend bei der Erstellung des Gerätes oder im globalen Logfile angezeigt. Das globale Logfile ist über den Menüpunkt "Logfile" im Hauptmenü des Frontends zu erreichen. Fehler oder Warnungen, die erst zur Laufzeit offensichtlich werden, stehen in der Geräteübersicht oder im globalen Logfile.

Logische Fehler

Diese Fehler werden erst zur Laufzeit sichtbar und das DOIF verhält sich nicht wie erwartet.

Die Fehler entstehen z.B. durch:

  • Angabe einer falsche Rangfolge von Operatoren in der Bedingung:
[A] and [B] or [C]

geschrieben, aber

[A] and ([B] or [C])

gemeint.

  • Nichtbeachtung des unterschiedlichen Verhalten von triggernden und nicht triggernden Auslöserangaben.
  • Ein unerwartetes Auslösen von DOELSE.
  • Unerwartete Ereignisse eines Gerätes, die in einer Bedingung nicht abgefangen werden.
  • Falsche Angabe der Events eines beteiligten Gerätes.
  • Es wird DOELSE mit einer Bedingung angegeben.

Besonderheit des Error-Reading

Das Reading "error" enthält Fehlermeldungen oder Rückgabewerte von Befehlen, die nicht 0, "", undef. also logisch "falsch" entsprechen. Die Ausführung des Befehls

({my $var = 1})

setzt das Error-Reading

error      {my $var =1 }: 1

Diese falsche Fehlermeldung kann vermieden werden, durch Erzeugen eines Rückgabewertes, der logisch "falsch" entspricht.

({my $var = 1;; 0})

Die mit ";; 0" angehängte Null verhindert das Setzen des Error-Readings.

Adressierung von Arrayelementen

Die Adressierung von Arrayelementen $myArray[4] kann zu Fehlverhalten führen, weil die eckigen Klammern als DOIF-Syntax interpretiert werden. Das gilt nicht für den Block subs im Perl-Mode. Altervativ könnte z.B. ein numerierter Hash verwendet werden $myArrayAsHash{4}.

Fehler eingrenzen

Wenn ein Hinweis in der Fehlermeldung nicht ausreicht, um den Fehler zu beseitigen, empfiehlt es sich die Definition des DOIF Schritt für Schritt neu aufzubauen und die Fehlermeldung zu beobachten, um den Fehlerort einzugrenzen. Der letzte Schritt, der zur Fehlermeldung geführt hat, muss dann genauer untersucht werden.
Auch wenn es keine Fehlermeldungen gibt, aber das DOIF sich nicht so verhält wie man es erwartet, kann es hilfreich sein die Bedingung Schritt für Schritt aufzubauen, bis sich ein unerwartetes Verhalten zeigt. Die letzte Änderung müsste dann im im Kontext der restlichen Bedingung genauer analysiert werden.

DOIF zum Testen

Eine weitere Möglichkeit wäre ein DOIF zum Testen anzulegen. Darin können Befehle, Bedingungen oder Bedingungsteile, verschiedene Schreibweisen oder alternative Operanden verwendet und ausprobiert werden, bis der eine Lösung gefunden wurde.

Befehlsteil testen

Die Ausführung der Befehle in den einzelnen Befehlszweigen lässt sich über den Set-Befehl anstossen.

set <DOIFname> cmd_<Nr des Befehlszweiges>

Wenn DOIFtools genutzt wird, dann sollten entsprechende Logeinträge im DOIFtoolsLog zu finden sein.

Bedingungen testen mit dem Befehl trigger

Manche Events lassen auf sich warten, um die Bedingung vorher zu testen kann der Befehl trigger verwendet werden.

 trigger <Gerätename> ⟨<Readingname>: ⟩<Wert>

Das funktioniert dort, wo die Auslösung über Events in der Bedingung genutzt wird.

Bedingungen testen mit dem Befehl setreading

Manche Readings Aktualisierungen lassen auf sich warten, um die Bedingung vorher zu testen kann der Befehl setreading verwendet werden.

 setreading <Gerätename> <Readingname> <Wert>

Siehe auch commandref/setreading.

Operatoren loggen, die keine Bedingungsprüfung auslösen (triggern)

Operatoren, die keine Bedingungsprüfung auslösen, werden im Listing des DOIF nicht angezeigt. Sie können geloggt werden, durch die Angabe eines Log-Befehls in der Bedingung.

Allgemein

 (<Bedingung>; Log <verbose level>, <content to log>)

Vorschlag

 (<Bedingung>; Log 1, "$SELF:"."\n<name1>:<reading1> ".ReadingsVal("<name1>","<reading1>","<default1>")."\n<name2>:<reading2> ".ReadingsVal("<name2>","<reading2>","<default2>")...)

Siehe auch: alternativer Vorschlag oder Log-Befehl

Hilfsmittel zu Fehleranalyse

Befehlsreferenz

Die Befehlsreferenz zum DOIF immer wieder problembezogen lesen.

Stacktrace

Zur Ursachenermittlung von Perl-Warnungen kann das globale Attribut stacktrace auf 1 gesetzt werden.

attr global stacktrace 1

Verboselevel

In manchen Fällen bekommt man hilfreiche Informationen, wenn der Verboselevel von betroffenen Geräten erhöht wird.

attr <gerätename> verbose 5

Event-Monitor

Der Event-Monitor ist über den Menüpunkt "Event monitor" im Hauptmenü des Frontends zu erreichen. Er enthält einen Filter, um die Anzeige der Events zu beschränken, um z.B. nur die Events eines Gerätes anzuzeigen, etwa des DOIF.

Wenn DOIFtools installiert ist. kann der Event-Monitor in der Detailansicht des DOIF angezeigt werden, siehe Zugriff_auf_den_Event-Monitor_in_der_Detailansicht_des_DOIF.

Der Event-Monitor kann über den Readings positioniert werden, so können Events und resultierende Readings-Änderungen gleichzeitig beobachtet werden, siehe Event-Monitor_im_DOIF_direkt_vor_den_Readings_anzeigen.

Detailansicht des DOIF

Das Schaltverhalten des DOIF kann in der Detailansicht (DeviceOverview) des DOIF und/oder im Eventmonitor beobachtet werden.

Bei der Detailansicht ist zu beachten, dass nicht alle sich ändernden Readings aktualisiert werden. Um diese geänderten Readings anzuzeigen, muss die Ansicht im Browser aktualisiert werden.

Gerätedefinition ausgeben

Eine Gerätedefinition einschliesslich der Attribute kann man sich mit dem Befehl "exportdevice" anzeigen lassen.

exportdevice <DOIFname>

Listing des DOIF

Eine Momentaufnahme vom Status des DOIF im Fehlerfall kann man sich mit dem Befehl list anzeigen lassen oder zum Posten verwenden.

list <DOIFname>

Verhaltensanalyse des DOIF

Mit DOIFtools kann automatisiert ein detailiertes Logfile erstellt werden, siehe DOIFtoolsLog.

In dem DOIFtoolsLog kann das Verhalten des DOIF und der dazugehörenden Operanden genau nachvollzogen werden, da auch ein Listing eingeschlossen werden kann, siehe Listings in DOIFtoolsLog einschliessen.

Wenn Abweichungen zum erwarteten Verhalten erkannt werden, hat man einen Anhaltspunkt für weitere Untersuchungen oder sogar den Auslöser gefunden.


Alternativ kann ein Logfile manuell erstellt werden. Dazu können alle Geräte einbezogen werden, die im DOIF enthalten sind; z.B. als tägliches Logfile.

define DOIF_Log FileLog ./log/DOIF_Log-%j.log <DOIFname>:.*|<Gerät 1>:.*|<Gerät 2>:.* ...

Mit dem Attribut mseclog lässt sich ein genauerer Zeitstempel einstellen, damit können zusammengehörende Events erkannt werden.

attr DOIF_Log mseclog 1

Bedingungen und Befehle zum aktuellen Zeitpunkt auszuwerten (Dump von DOIF)

Mit der Perl-Funktion dumpDevice($devspec) für die 99_myUtils.pm, kann der Zustand eines oder mehrerer DOIF geloggt werden. Es werden Operanden und Funktionen aufgelöst und deren Inhalte angezeigt. Die genaue Syntax einer Device-Spezifikation ($devspec) ist in der commandref/devspec erläutert.

Die Funktion kann im Log-Befehl verwendet werden und im Bedingungs- und Ausführungsteil genutzt werden.

(<Bedingungen> ;Log 1, dumpDevice("$SELF"))

oder

(<Befehle>,{Log 1, dumpDevice("$SELF")})

Die Funktion wird im Forum bereitgestellt: Debug DOIF via Device Dump

Qualifizierte Angaben zur Anfrage im Forum

Dem Helfenden sollten alle zum Problem gehörenden Informationen gegeben werden, die dem Fragenden auch zur Verfügung stehen.

Nicht immer sind alle Angaben notwendig, bei komplexen Problemen schon eher.

  • Hinweis, wenn FHEM und DOIF nicht aktuell sind.
  • Hinweis, wenn die cfg-Dateien direkt bearbeitet werden.
  • genaue Beschreibung des erwarteten Verhalten
  • genaue Beschreibung des beobachteten Verhalten
  • Alle relevanten Fehlermeldungen
  • Darstellen, was man selbst schon versucht hat und mit welchem Ergebnis, dann wird es nicht noch einmal vorgeschlagen.
  • Ein für andere ausführbares Testszenario für Raw definition, mit Dummys als Ersatz für Sensoren, Schalter, Aktoren usw.
  • Angabe der vollständigen Definition des DOIF (Name, Definition, Attribute) in Code-Tags (das Raute-Zeichen # im Forum-Editor)
  • Zusätzlich ein vollständiges Listing des DOIF
  • Die relevanten Stellen aus dem aufgezeichneten FileLog ,vorzugsweise DOIFtoolsLog mit Kommentar und Markierung der Probleme in Quote-Tags (das Zeichen rechts neben der Raute). In Quote-Tags kann die Zeichenformatierung zum Markieren genutzt werden, in Code-Tags nicht.
  • Auszug aus dem Event-Monitor mit Kommentar und Markierung der Probleme

Links