Sonntag, 29. März 2015

Browser Timeout und FHEM

Schon mal einen Befehl in FHEM ausgeführt und nach ca. zwei Minuten einen Time-out bekommen? Schon mal gewundert, dass ein Backup doppelt ausgeführt wurde?

Warum das so ist? Den Hinweis fand ich im Forum.
Mir sind zwei Situationen aufgefallen in denen der Browser beim Zugriff auf FHEM in einen Time-out gerät. Beim Backup und beim update force. In beiden Fällen bekommt der Browser keine Quittung für den Befehl und wartet eine Minute. Läuft der angeforderte Befehl länger als eine Minute sendet der Browser einmalig den Request neu. Damit erhält FHEM erneut den Request und führt ihn aus, der Browser zeigt nach der zweiten Minute einen Time-out.
Blöd ist: Man hat anschließend das Backup doppelt in kurzem Abstand. Das update force läuft unnötigerweise auch zweimal.
Nicht besonders schlimm, aber man kann das auch verhindern: Befehl ausführen und einfach Browser schließen.

Beim Backup gibt es noch die gute Idee es nicht manuell zu starten sondern automatisch auszuführen. z.B. vor dem Update:
attr global backup_before_update 1
Oder man richtet ein zyklisches Backup ein.

Perl Module dokumentieren

Vor ein paar Tagen sagte mir mein FHEM System "... FHEM/99_myUtils.pm: No document text found". Mich hat diese Meldung erstmal verwirrt, sah mir nach einem Fehler aus.

Hintergrund: Die Entwickler haben die Erzeugung der commandref, einer der wichtigsten und besten Dokumentationen von FHEM, auf die lokale Installation verlagert. Der Vorteil: Es wird beim Update weniger heruntergeladen und die Doku wird aus den lokalen Modulen erzeugt. Damit bekommt die Datei mit den eigenen Routinen, die Chance in die Offline-Dokumentation einzugehen.

Wahrscheinlich hat bisher kaum jemand seine Dokumentation für die eigenen Routinen aufgeschrieben, allenfalls Kommentarzeilen direkt im Code.
Ich habe mich schlau gemacht und will daher mal zeigen wie das geht. Irgendwo stand im Forum sinngemäß: "Ein Module ohne Dokumentation ist wertlos" :-)

Ich habe die vorhanden Module durchsucht, habe im Internet recherchiert und als Ergebnis gibt es gleich zu Beginn eine Art Grundbaustein:
=pod
=begin html
... hier steht die Doku in englisch
=end html
=begin html_DE
... hier steht die Doku in deutsch
=end html_DE
=cut
In den meisten Modulen habe ich diesen Doku Abschnitt einfach am Ende des Perl Modules gefunden, also nach der Zeile mit dem Inhalt 1;
Laut diesem Beitrag ist es aber egal, wo man diesen Abschnitt einfügt. Das allerwichtigste ist die "Klammer", die den Abschnitt für Plain Old Documentation darstellt.
=pod
...
=cut
Dazwischen gibt es Schlüsselwörter und Text. Im Falle FHEM gibt es dann zwei "Klammern" eine für englische Doku eine für Deutsche. Wenn die deutsche Klammer fehlt, wird in der commandref ein Link und ein Standardtext erstellt.
=begin html
...
=end html
FHEM erfordert innerhalb des hmtl Abschnittes dann mindestens zwei Tags:
<a name="myUtils"></a>
<h3>myUtils</h3>
Der <a> Tag stellt einen Verweis dar, der <h3> Tag kennzeichnet die Überschrift. Beide Tags müssen sein, ansonsten kann FHEM die Doku nicht in die commandref einbinden. Der Abschnitt für die deutsche Doku kann komplett fehlen. Das folgende Minimum erzeugt einen Link und eine Überschrift in der commandref.
=pod
=begin html

<a name="myUtils"></a>
<h3>myUtils</h3>

=end html
=cut
Die Beschreibungen der einzelnen Routinen werden mit <ul> Tags geklammert und eventuell mit <ul> Tags weiter untergliedert. Dabei entsteht ein eingerückter Text. Beispiele können mit dem <code> Tag formatiert werden.
So schaut es als Gerüst aus:
=pod
=begin html

<a name="myUtils"></a>
<h3>myUtils</h3>
<ul>
  <b>Name</b>
  <br>
  Text<br>
  Examples:
  <ul>
   <code>Example Code </code><br>
  </ul>
</ul>

=end html
=cut
Mit diesem Befehl in der FHEM Kommando Zeile:
{system("/usr/bin/perl ./contrib/commandref_join.pl")}
{qx(/usr/bin/perl ./contrib/commandref_modular.pl)}
Kann die Erstellung der commandref im laufenden Betrieb getestet werden. Allerdings erfolgt die Ausgabe von Fehlern im Logfile von FHEM. Will man die Ausgabe direkt sehen, kann man im Terminalfenster folgendes eingeben:
cd /opt/fhem
sudo /usr/bin/perl ./contrib/commandref_join.pl
Wenn man anschließend die Ansicht testet, darf man den Browsercache nicht vergessen (F5). 

Donnerstag, 26. März 2015

Angepasstes RaspBerryPi Image

Das Raspbian Image hat derzeit eine Größe nach dem entpacken des Downloads von 3,2 GB. Mir stellte sich die Frage: kann ich das was ich z.B. als Grundlage installiere für ein FHEM System, einmal tun und dann als Grundlage für weiter System aufheben? Klar werden jetzt alle sagen, ganz einfach! Aber ganz so simpel ist es nicht. Es geht damit los, dass es meines Wissen kein Tool gibt mit dem sich von einer SD Karte unter Windows ein Image der definierten Partitionen/Laufwerke machen lässt.
Also ganz praktisch: Man nimmt das USB Image Tool, schreibt das Raspbian Image (3,2GB) auf eine 16 GB SD Karte und zieht von dieser wieder ein Image. Ergebnis: Man hat ein 16 GB Image und, das USB Image Tool weigert sich diese auf ein 4 GB SD Karte zu schreiben, die ja reichen würde. Soviel zur Einleitung.

Wie kann man vorgehen?

  • Raspian Image auf eine 16 GB SD Karte schreiben.
  • Rein in den Raspberry und starten.
  • Jetzt kann man mit Raspi-config alles tun, blos nicht: Expand Filesystem
  • Jetzt können wir Updates fahren, Software installieren. Für eine FHEM Installation passt alles in das 3,2 GB Image. 

Mit dem Befehl "fdisk -l" kann man sich die Partitionen anzeigen lassen. der Befehl "df" zeigt die tatsächliche Belegung der SD Card an.
Ich hatte auf dem Original Image 183648 1K-Blöcke verfügbar. Nach dem Update/Upgrade und einem apt-get clean waren es 261564. Nach der FHEM Installation waren es 218112. Also ist der belegte Platz nach Bereinigung soweit verringert, dass FHEM das nicht aufholt.

Wenn das Master-System soweit fertig ist, fahren wir es herunter (sudo halt).
Die SD Karte kommt in einen USB Reader und wir begeben uns an einen anderen Raspi oder starten den einzigen Raspi mit einem anderen Image. Als Speicher für das Image brauchen wir noch einen USB Stick.
Meistens ist es ein gute Idee, die USB Stick's schon vor dem Start anzustecken. Die alten Raspi's stürzen wegen Spannungsproblemen ab, wenn man im laufenden Betrieb USB Sticks ansteckt, die neuen können das, wenn das Netzteil in Ordnung ist.

Nun kommt etwas Arbeit auf der Kommandozeile, also Terminal (putty) zum Raspi aufbauen und anmelden.
Meist muss der USB Stick erst gemounted werden, das kann aber von System zu System unterschiedlich sein.

sudo mkdir /media/usbstick
sudo mount -t vfat -o utf8,uid=pi,gid=pi,noatime /dev/sdb1 /media/usbstick

Mit dem Befehl lsblk kann man sich alle Geräte listen lassen. In meinem Beispiel sieht das so aus:

NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda           8:0    1  14,8G  0 disk
+-sda1        8:1    1    56M  0 part /media/boot
+-sda2        8:2    1     3G  0 part /media/f24a4...
sdb           8:16   1  29,4G  0 disk
+-sdb1        8:17   1  29,4G  0 part /media/TRANSCEND1
mmcblk0     179:0    0  15,1G  0 disk
+-mmcblk0p1 179:1    0    56M  0 part /boot
+-mmcblk0p2 179:2    0    15G  0 part /

Die "HDD" sda ist mein USB Reader mit SD Karte, sdb ist mein USB Stick. Das aktive System ist in mmcblk0.

Jetzt werden die ersten 3,2 GB mittels dd quasi von a nach b kopiert:

sudo dd bs=1M count=3125 if=/dev/sda of=/media/usbstick/raspbian.img

Das dauert übrigens ca 04:25 min. Der Wert war ziemlich konstant, unabhängig ob 4M oder 1M Blöcke oder ob beim kopieren unter Windows vom Stick auf  auf die SD Karte an USB3 Verbindungen.

Ergebnis ist wieder ein 3,2 GB großes Image welches auf eine beliebige SD Karte geschrieben werden kann. Mit Raspi-config und Expand Filesystem kann man jederzeit die gesamte SD Karte nutzen.
Erweitern geht immer einfach und ist ein zwei Schritt Prozess durch vergrößern der Partition und erweitern des Filesystems:

fdisk
resize2fs

Eine Verkleinerung ist schwieriger, deswegen sollte man eventuell überlegen, die Erweiterung manuell zu machen und nicht die gesamte SD Karte nutzen. Die nächste SD Karte könnte nämlich ein paar Bytes kleiner sein.