Sonntag, 12. November 2017

FHEM auf der Fritz!Box 7490 unter Freetz

Wie im vorherigen Beitrag beschrieben, läuft auf meiner Fritz!Box nun (wieder) Freetz. Nachdem AVM eine Zeit lang FHEM sogar als Labor Firmware mit anbot, entschied man sich, wohl aus Wartungs- und Sicherheitsgründen, diesen "Community" Weg nicht weiterzuverfolgen.
Aber offensichtlich ist die Idee aus Ressourcen-Sicht garnicht so abwegig, FHEM auf einer 7490 laufen zu lassen. Das herunterladbare Tar-Archiv auf der alten FHEM Fritz!Box Seite brachte unter FW 6.90 leider immer einen Segmentation Fault. Deshalb musste ich zunächst Perl für die Box Cross-Kompilieren und konnte dann FHEM installieren - inkl. JSON, IO::Socket::SSL/Net::SSLeay und sogar DBD::SQLite.

cross-compile PERL

Installationsbasis ist wie im letzten Post das VirtualBox Image von Freetz-Linux. Darin sollte auch bereits ein Freetz gebaut worden sein, denn die Bibliotheksverzeichnisse von OpenSSL und SQLite werden für den Paketbau benötigt.

Im Freetz-Image sollte je nach Bedarf OpenSSL und SQLite ausgewählt sein. Soll IO::Socket::SSL verwendet werden, so fehlt dem Standard-Freetz-OpenSSL eine Cipher, die hinzugepatcht werden muss (auch im vorherigen Post erläutert). Danach muss das Image nochmal neu gebaut werden...

Ich habe ein kleines Script gebastelt, welches die Quellcodes holt und alle benötigten Makefiles an die richtigen Stellen kopiert. Die Hauptarbeit erledigt das perl-cross Projekt.

Das Tar-Archiv mit Script und Perl Makefiles kann ins Home-Verzeichnis entpackt werden.
Evtl. müssen im Kopfteil noch die Pfade angepasst werden.
#!/bin/sh

PERL=5.26.1
FREETZ=$HOME/freetz-trunk

cd $HOME/
mkdir perl_install

wget https://github.com/arsv/perl-cross/releases/download/1.1.8/perl-cross-1.1.8.tar.gz
wget http://www.cpan.org/src/5.0/perl-${PERL}.tar.gz
tar xfz perl-${PERL}.tar.gz

wget http://search.cpan.org/CPAN/authors/id/I/IS/ISHIGAKI/JSON-2.94.tar.gz
tar xfz JSON-2.94.tar.gz
mv JSON-2.94 perl-${PERL}/cpan/JSON
cp JSON_Makefile.PL perl-${PERL}/cpan/JSON/Makefile.PL

if [ -n "$(grep '^FREETZ_OPENSSL_VERSION_1=y' ${FREETZ}/.config)" ] ; then
 wget http://search.cpan.org/CPAN/authors/id/M/MI/MIKEM/Net-SSLeay-1.82.tar.gz
 wget http://search.cpan.org/CPAN/authors/id/S/SU/SULLR/IO-Socket-SSL-2.052.tar.gz
 tar xfz Net-SSLeay-1.82.tar.gz
 tar xfz IO-Socket-SSL-2.052.tar.gz
 mv Net-SSLeay-1.82 perl-${PERL}/cpan/Net-SSLeay
 mv IO-Socket-SSL-2.052 perl-${PERL}/cpan/IO-Socket-SSL
 cp Net-SSLeay_Makefile.PL perl-${PERL}/cpan/Net-SSLeay/Makefile.PL
 cp IO-Socket-SSL_Makefile.PL perl-${PERL}/cpan/IO-Socket-SSL/Makefile.PL
fi

if [ -n "$(grep '^FREETZ_PACKAGE_SQLITE=y' ${FREETZ}/.config)" ] ; then
 wget http://search.cpan.org/CPAN/authors/id/T/TI/TIMB/DBI-1.637.tar.gz
 wget http://search.cpan.org/CPAN/authors/id/I/IS/ISHIGAKI/DBD-SQLite-1.54.tar.gz
 tar xfz DBI-1.637.tar.gz
 tar xfz DBD-SQLite-1.54.tar.gz
 mv DBI-1.637 perl-${PERL}/cpan/DBI
 mv DBD-SQLite-1.54 perl-${PERL}/cpan/DBD-SQLite
 cp DBD-SQLite_Makefile.PL perl-${PERL}/cpan/DBD-SQLite/Makefile.PL
 cat perl-${PERL}/cpan/DBI/Driver.xst | sed 's/~DRIVER~/SQLite/g' > perl-${PERL}/cpan/DBD-SQLite/SQLite.xsi
fi

cd perl-${PERL}
tar --strip-components=1 -zxf ../perl-cross-1.1.8.tar.gz

export PATH=$FREETZ/toolchain/target/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:
./configure --prefix=/var/InternerSpeicher/opt --target=mips-linux --target-tools-prefix=mips-linux- --mode=cross
make
make DESTDIR=$HOME/perl_install install

cd $HOME/perl_install
rm -rf var/InternerSpeicher/opt/share
tar cfz $HOME/freetz_perl-${PERL}.tgz var/
cd $HOME/

Wenn das Script nach ein paar Minuten fehlerfrei durchgelaufen ist, findet sich das fertige Perl-Archiv als freetz_perl-<Version>.tgz im Ausgangsverzeichnis. Das Paket ist bis auf's Löschen der Manual Seiten noch nicht auf Größe optimiert und belegt gut 50MB (die7490 hat 512MB Flash).

FHEM Installation

Außerdem benutze ich /var/InternerSpeicher/opt als Speicherort für die Installation auf der Box.
FHEM installiere ich nach /var/InternerSpeicher/fhem. Dafür kann das normale .tgz-Archiv der Download Seite verwendet werden.

Zum Starten verwende ich ein angepasstes Script des ursprünglichen FHEM-Fritzbox Images:
#!/bin/sh
# fhem Start Script
#

home=/var/InternerSpeicher

cd $home/fhem

trap "" SIGHUP
#modprobe cdc_acm
#modprobe ftdi_sio
#sleep 2


# add user fhem with uid of boxusr80/boxusr99 (== ftpuser)
# Comment/delete everything between START and END to run FHEM as root

## START:fhem-user
id fhem > /dev/null 2>&1
if test "$?" -ne "0"; then
  grep -q 1099 /etc/passwd;
  if test $? -eq "0"; then
    echo "fhem:any:1099:0:fhem:/home-not-used:/bin/sh" >>/var/tmp/passwd
  else
    echo "fhem:any:1080:0:fhem:/home-not-used:/bin/sh" >>/var/tmp/passwd
  fi
  chown -R fhem:users *
  chown fhem:users .
#  chown root dfu-programmer
#  chmod u+s dfu-programmer
fi
## END:fhem-user

rm -rf /tmp/fhem
mkdir /tmp/fhem
sqlite3 /tmp/fhem/fhem.db < create.sqlite
cp log.static/* log/
chown -R fhem /tmp/fhem
$home/opt/bin/perl fhem.pl fhem.cfg

Da ich einen CUBe verwende, habe ich die Hardwarespezifischen Module auskommentiert.
Um den Flash zu schonen, habe ich das log-Verzeichnis in log.static umbenannt und stattdessen einen symbolischen Link log nach /tmp/fhem angelegt (ln -s /tmp/fhem log). Das Startscript kopiert alle zwischengespeicherten Daten in den Temp-Speicher und das Stopscript kopiert alles wieder zurück.

Da ich die SQLite Datenbank nur für ein paar SVG-Plots verwende, verzichte ich auf die permanente Zwischenspeicherung und lege die Datenbank bei jedem Start neu an.
#!/bin/sh
# FHEM Stop Script
#
home=/var/InternerSpeicher

killall perl
cd $home/fhem
cp -f log/fhem.save log.static/
cp -f log/eventTypes.txt log.static/
cp -f log/weekprofile* log.static/
cp -f log/LightScenes.save log.static/

Verlinkt habe ich die Scripts in den Freetz rc.custom bzw, shutdown.