EIBD und Linux

Einleitung

Ich versuche mal zu dokumentieren wie man den eibd unter linux/debian zum Laufen bekommt.

Installation

Debian

Ich starte immer mit der Debian Visitenkarten CD. Zu debian findet man viele Howtos im Netz, aber keine Angst. Es ist eigentlich ganz einfach. Wenn man weiss was eine IP Adresse ist, dann kommt man mit den default Einstellungen in ca 30min zum Ziel.

Ich wähle für meinen Rechner nur die Minimalkonfiguration. Keine X-windows, kein Druckerserver. Nur Datei-Server und ein Basis-System. Das sei aber jedem selbst überlassen.

SSH

Wenn ihr soweit durch seid, dann habt ihr eine console. Jetzt gilt es das System noch so zu erweitern, dass wir von einem anderen Rechner darauf zugreifen können. Dazu laden wir den SSH Daemon.

# apt-get update
# apt-get install ssh

Jetzt brauchen wir auf dem anderen Rechner noch Putty und es kann losgehen.

Wenn ihr Monitor und Tastatur an dem Rechner habt, dann könnt ihr euch Putty natürlich sparen.

eibd

Erweitern der sources.conf.

# vi /etc/apt/sources.list

[oder mit einem anderen Editor eurer Wahl zB nano]

und folgende beiden Zeilen am Ende hinzufügen.

deb http://www.auto.tuwien.ac.at/~mkoegler/debian eib main
deb-src http://www.auto.tuwien.ac.at/~mkoegler/debian eib main

Das Repository von der TU Wien ist nur mit einem Key zu nutzen. Den müsst ihr noch installieren. Ihr bekommt ihn hier. Dazu kopiert ihr den Schlüssel in eine Datei beliebigen Namens zB ~root/qw und gebt danach folgendes ein.

Danach ein

#cd ~root
#apt-key add qw
#apt-get update
#apt-get install bcusdk

 

OpenSuse

Automatische Installation:

Fertige RPMs für OpenSUSE 10.2 (i568)

Manuelle Installation:

Für den Kernel passenden EIB Linux Kernel Driver herunterladen und in ein Verzeichnis, z.B. knxd, entpacken:

mkdir knxd
cd knxd
mkdir bcudriver
cd bcudriver
wget http://www.auto.tuwien.ac.at/~mkoegler/eib/drv/bcu1driver-0.2.6.4.3.tar.gz
tar -xf bcu1driver-0.2.6.4.3.tar.gz
make
cd ..
mkdir eibd
wget http://www.auto.tuwien.ac.at/~mkoegler/eib/drv/eib-0.2.6.4.1.tar.gz
tar -xf eib-0.2.6.4.1.tar.gz
make

Und das Modul laden:

cd ..
cd bcudriver
insmod eib.ko
cd ..
cd ..

Erste Schritte

Ich nutze ne FT1.2 zusammen mit einer BCU2. Damit funktioniert eibd problemlos. Es geht aber auch mit den meisten anderen Kombinationen (USB, BCU1, ...)

Für die Kommunikation mit dem Bus über FT1.2/BCU2 verbindet ihr die FT1.2 mit einem seriellen Kabel mit dem COM Port des Rechners.

Jetzt startet ihr eibd und gebt im den entsprechenden Port mit. Fuer COM1 /dev/ttyS0 und für COM2 /dev/ttyS1, usw.

# eibd -d -i ft12:/dev/ttyS1

Für die Kommunikation mit dem Bus über EIBnet/IP verbindet Ihr den Bus mit einem EIBnet/IP Router (z.B. den Siemens N148/21) und startet eibd mit der entsprechenden IP-Adresse des EIBnet/IP Routers.

# eibd -d -i ipt:192.168.178.200

So jetzt kommt der große Moment.

Mit dem folgenden Befehl schreibt ihr auf die Gruppenadresse 1/2/3 eine 1 und der entsprechende Aktor schaltet. Es muss sich um eine Gruppenadresse vom Typ EIS1 (an/aus) handeln.

# groupswrite ip:127.0.0.1 1/2/3 1

Mit einer 0 schaltet ihr den Aktor wieder aus.

# groupswrite ip:127.0.0.1 1/2/3 0

Mit

# ps -ef | grep eibd
root      2534  2268  0 00:06 pts/1    00:00:00 eibd -i ft12:/dev/ttyS1
root      2596  2537  0 00:19 pts/2    00:00:00 grep eibd

bekommt ihr die Prozess ID heraus (zweite Spalte) und killt den alten eibd mit

# kill -9 2534

Installation auf einem Router oder NAS

Package für OpenWRT basierte Router

Auf einem Router, der auf einem OpenWRT Linux System basiert, wie zum Beispiel:

  • Linksys WRT54G (OpenWRT Kamikaze)
  • Linksys WRT54GS v4 (OpenWRT WhiteRussian and Kamikaze)
  • Asus WL500G (OpenWRT WhiteRussian)
  • Asus WL500GP (OpenWRT Kamikaze)

können fertige IPK Pakete herunter geladen werden für WhiteRussian oder Kamikaze.

Package für Optware basierte NAS

Auf einem NAS, der auf einem Optware Linux System basiert, wie zum Beispiel:

  • Linksys NSLU2 (Optware)
  • Freecom FSG3 (Optware)
  • Synology DS101 (Optware)

können fertige IPK Pakete herunter geladen werden für die Synology DS101 oder die Freecom FSG3.

Wie geht es weiter?

Automatisches Starten von eibd beim Hochfahren des Rechners

Nachdem der eibd jetzt rudimentär läuft wollen wir eibd bei jedem hochfahren des Rechners automatisch starten.

Dazu nutzen wir die Standard Mechanismen von Debian und erstellen eine Datei /etc/init.d/eibd mit folgendem Inhalt:

#! /bin/sh

PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Description of the service"
NAME=eibd
DAEMON=/usr/bin/$NAME
DAEMON_ARGS="-D -T -S -d -i --pid-file=/var/run/eibd.pid ft12:/dev/ttyS0"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

#
# Function that starts the daemon/service
#
do_start()
{
        # Return
        #   0 if daemon has been started
        #   1 if daemon was already running
        #   2 if daemon could not be started
        start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
                || return 1
        start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
                $DAEMON_ARGS \
                || return 2
        # Add code here, if necessary, that waits for the process to be ready
        # to handle requests from services started subsequently which depend
        # on this one.  As a last resort, sleep for some time.
}
#
# Function that stops the daemon/service
#
do_stop()
{
        # Return
        #   0 if daemon has been stopped
        #   1 if daemon was already stopped
        #   2 if daemon could not be stopped
        #   other if a failure occurred
        start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
        RETVAL="$?"
        [ "$RETVAL" = 2 ] && return 2
        # Wait for children to finish too if this is a daemon that forks
        # and if the daemon is only ever run from this initscript.
        # If the above conditions are not satisfied then add some other code
        # that waits for the process to drop all resources that could be
        # needed by services started subsequently.  A last resort is to
        # sleep for some time.
        start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
        [ "$?" = 2 ] && return 2
        # Many daemons don't delete their pidfiles when they exit.
        rm -f $PIDFILE
        return "$RETVAL"
}

#
# Function that sends a SIGHUP to the daemon/service
#
do_reload() {
        #
        # If the daemon can reload its configuration without
        # restarting (for example, when it is sent a SIGHUP),
        # then implement that here.
        #
        start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
        return 0
}

case "$1" in
  start)
        [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
        do_start
        case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
  stop)
        [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
        do_stop
        case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
  #reload|force-reload)
        #
        # If do_reload() is not implemented then leave this commented out
        # and leave 'force-reload' as an alias for 'restart'.
        #
        #log_daemon_msg "Reloading $DESC" "$NAME"
        #do_reload
        #log_end_msg $?
        #;;
  restart|force-reload)
        #
        # If the "reload" option is implemented then remove the
        # 'force-reload' alias
        #
        log_daemon_msg "Restarting $DESC" "$NAME"
        do_stop
        case "$?" in
          0|1)
                do_start
                case "$?" in
                        0) log_end_msg 0 ;;
                        1) log_end_msg 1 ;; # Old process is still running
                        *) log_end_msg 1 ;; # Failed to start
                esac
                ;;
          *)

                # Failed to stop
                log_end_msg 1
                ;;
        esac
        ;;
  *)
        #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
        echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
        exit 3
        ;;
esac

Das Script machen wir ausführbar

# chmod a+x /etc/init.d/eibd

Jetzt müssen noch die entsprechenden symbolischen Links für die einzelnen Runlevel gesetzt werden. Aber Linux wäre nicht Linux, wenn es dafür nicht eine einfache Methode gäbe.

Mit

# apt-get install rcconf

installieren wir die Software und mit

# cd /etc/init.d/
# rcconf

setzen wir vor der Zeile eibd das entsprechende Häckchen mit Space und beenden mit Return. Evtl. müsst ihr weiter runter scrollen um die Zeile eibd zu finden.

Nach einem Reboot (den ihr bei Linux jetzt im Gegensatz zu Windows nicht braucht) läuft der eibd automatisch.

Wir sparen uns den Reboot und starten eibd mit

# /etc/init.d/eibd start

Die Rollläden fahren per crontab

Wir machen das ganze ja nicht zum Selbstzweck. Als erste Anwendung lassen wir die Rollläden nun automatisch fahren.

# Rollladen EG hoch
30 6 * * 1-5 /usr/bin/groupswrite ip:127.0.0.1 0/1/2 0
0 8 * * 6-7 /usr/bin/groupswrite ip:127.0.0.1 0/1/2 0

# Rollladen Eltern hoch
30 6 * * 1-5 /usr/bin/groupswrite ip:127.0.0.1 2/1/5 0

Die Zeit auf dem Bus

Die TS2+ brauchen in regelmässigen Abständen die Zeit auf den Bus. Dazu erstellen wir ein entsprechendes Script unter /usr/local/bin/eibtime

#!/usr/bin/perl

use Math::BaseCnv;

# right $len chars
sub rstr{
  my $s = shift;
  my $len = shift;
  # printf("DEBUG %s %i\n",$s,$len);
  return substr($s, length($s) - $len, $len);
}

# read local time
($second, $minute, $hour, $dayOfMonth, $month, $yearOffset, $dayOfWeek, $dayOfYear, $daylightSavings) = localtime(time);

# Mon is KNX 001 and Sun is 111 in Linux is Sun 1 und Sat 7
@weekDays = qw(111 001 010 011 100 101 110);

# calc $hour in bin with exact 5 digits
$bin_hour = rstr("000000".cnv( $hour, 10, 2) ,5);

@args = ("/usr/bin/groupwrite", "ip:127.0.0.1", "0/6/6",                  # change protocoll to your needs
         sprintf("%02X", cnv( $weekDays[$dayOfWeek] . $bin_hour, 2, 10)), # calc weekday and hour in hex
         sprintf("%02X", $minute),                                        # same for minute and second
         sprintf("%02X", $second));

# execute command
system(@args) == 0 or die "system @args failed: $?";

Auf meinem Basissystem war perl schon installiert.

Mit

# crontab -e

ergänzt ihr einfach folgende Zeilen:

# zeit auf den bus schicken
16 * * * * /usr/local/bin/eibsendtime

und schon habt ihr Stündlich um 16min nach jeder vollen Stunde die Zeit auf dem Bus.

ETS Zugriff über eibd

Wenn ihr den eibd mit den Optionen -D -T -S startet (ich hab es oben im init.d Script bereits angepasst), dann könnt ihr von der ETS aus über IP und den eibd euren Bus programmieren.

Dazu in der ETS eine neue Verbindung einrichten und Eibnet/IP verwenden. Als Port gebt ihr 3671 ein. Ganz wichtig ist, dass ihr in der Windows Firewall auf dem ETS Rechner die Ports 3671 und 3672 freischaltet!

Installation von misterhouse

Mit Misterhouse können richtige Logiken programmiert werden und es wird ein rudimentäre HTML Visu bereitgestellt. Nicht ganz so fancy und schick wie ein Homeserver, aber auch nicht so teuer. Ich weiss! Der HS ist nicht teuer, sondern preiswert ;).

Die Installation von misterhouse hat einen eigenen Artikel.

Installation von linknx

Mit linknx kann der Bus über eine XML-Schnittstelle gelesen und geschrieben werden. Ein Tutorial findet Ihr hier und die Sourcen, sowie fertige Pakete hier.