Author Archives: Patrick

Wieder online: „Was ist Web 2.0?“

Ich musste feststellen, dass bei O’Reilly leider nur noch der englische Originaltext zum Thema „Was ist Web 2.0?“ online ist. Meine Übersetzung ist wohl dem letzten Relaunch zum Opfer gefallen. Da der Text aber immer noch nachgefragt wird, habe ich ihn selbst wieder online gestellt: Was ist Web 2.0?

Und ich so in der c’t…

Mein Artikel zum Thema OTRS an Hochschulen ist in c’t 04/16 erschienen. Ich habe ihn zusammen mit Johannes Nickel von der Znuny GmbH verfasst. Es geht um die Optimierung der Konfiguration, organisatorische und technische Tipps und Tricks, unsere Extensions, zu erwartende Supportfragen und vieles mehr. Bislang gibt es erfreulicherweise nur positives Feedback. Und für die c’t zu schreiben ist schon etwas Besonderes. 🙂

Kampf dem Herzinfarkt – zu lauten Sound unter Linux beheben

Der kleine Quickie am Montagmorgen: Seit Jahren ärgert mich das Problem, dass unter Linux speziell USB-Soundkarten viel zu laut angesteuert werden. Entweder steigt die Lautstärke irgendwo zwischen Stufe 20 und 30 sprunghaft von „einsamer Bergsee bei Windstille“ auf „startender Düsenjet“ oder ist (mit dem altbekannten „ignore_dB=1“-Trick) schon bei Stufe 2 eigentlich viel zu laut.

Nun bin ich zufällig im Blog von Chris Jean über eine Alternativlösung gestolpert, die sehr einfach umzusetzen ist und einfach funktioniert. Es gilt in der Datei

 /usr/share/pulseaudio/alsa-mixer/paths/analog-output.conf.common

im Block

[Element PCM]

die Zeile

volume = merge

zu ersetzen durch

volume = ignore
volume-limit = 0.0075

Und schön lässt sich das Ganze wieder wunderbar regeln. Zuvor kann man im Alsamixer noch die Soundkarten feinjustieren, damit die Master-Ausgabe optimal die eigenen Bedürfnisse abdeckt.

Der Zoo wächst: Willkommen, Lotta und Max!

Wie sagte die Lieblingstochter doch kürzlich zu ihrem Lehrer: „Nein, ich habe keine Geschwister. Und ich bekomm auch keine. Aber dafür haben wir zuhause einen Zoo.“ Ja, über einen Mangel an Haustieren kann sie sich nicht beschweren. Und eigentlich waren wir uns einig, dass es allmählich mal genug ist. Wobei – mit dem einen oder anderen Tier liebäugel ich ja ständig…

Dann ergab sich die Möglichkeit, unsere inzwischen etwas einsamen Geckos in eine größere Gruppe zu integrieren, sodass wir uns entschieden sie abzugeben. Nun war der Platz, an dem das Terrarium stand, ja quasi sträflich leer. Bei einem Besuch im Aquatop in Würselen war es dann unvermeidlich, sich auch mal in der Terraristik-Abteilung genauer umzuschauen. Meine Aufmerksamkeit wurde sehr schnell auf eine kleine, grüne Schlange gelenkt, eine Grasnatter. Gleich daneben befand sich eine gebänderte schwarzgrüne Schlange, eine Strumpfbandnatter. Beide Arten gefielen mir sehr gut und passten auch von der zu erwartenden Endgröße und ihren Bedürfnissen in meinen Plan. Mit einer Ausnahme: Nach etwa 7 Jahren Geckohaltung wollte ich keine Lebendfutterbeschaffung mehr sicherstellen müssen, denn das ist für halbwegs ländlich lebende Menschen ein Graus. Damit fiel die Wahl zugunsten der Strumpfbandnatter.

Weitere Recherchen ergaben, dass man die Tiere nicht im Zoohandel, sondern besser bei einem privaten Züchter erwerben sollte. Ich beschaffte mir etwas Literatur (sehr zu empfehlen: Martin Hallmen und Jürgen Chlebowy, „Strumpfbandnattern“, Natur+Tier-Verlag) und lernte viel dazu. So wollte ich dann auch kein fix und fertiges Terrarium kaufen, sondern selbst eines zusammenstellen. Geplant wurde ein Holzterrarium, basierend auf OSB-Platten, mit einer Glasfront und einer Seitenbelüftung. Die erforderlichen Platten wurden im Netz bestellt, die Glasfront bereits vorgefertigt (ich wollte bei der Einschätzung meines handwerklichen Geschicks ja realistisch bleiben). Die Maße des fertigen Terrariums betrugen 100 * 50 * 50.

CAM00446

Weiter ging es mit dem Bodengrund. Sowohl Forenbeiträge als auch Fachliteratur widersprechen sich hier wirklich herzallerliebst. Eigentlich kann man nur alles falsch machen. Von Küchenkrepp über Sand, Kleinttierstreu, Buchenspäne, Rindenmulch und vieles mehr könnte ich inzwischen ewig über angebliche Vor- und Nachteile referieren. Gewählt habe ich schließlich Pinienrinde, Körnung 25 mm. Die Basis für die Dekoration bildeten Äste, Kokosnusshöhlen, Steinhöhlen, künstliche und echte Pflanzen (Tillandsien).

CAM00450

Den letzten Pfiff jedoch erhielt die Gestaltung durch das Hinzufügen von großen Stücken Baumrinde, die ich durch eine zufällig mit mir verwandte Floristin reichlich erhielt. Später sollten mir zudem die Schlangen dies danken und beide Rindenstücke zu ihren Lieblingsplätzen erklären.

CAM00451

Nun war ich fast fertig. Dachte ich. Die größte Herausforderung war jedoch nun die Auswahl und Installation der Licht- und Wärmetechnik. Hier galt noch viel schlimmer als beim Bodengrund: Man kann es nur falsch machen. Wenn man versucht, durch das Lesen von Forenbeiträgen das Optimum zu ermitteln, wird einem irgendwann klar, dass man seine Schlangen auf jeden Fall auf die eine oder andere Weise grausam misshandeln oder töten wird. Energiesparlampe? Zu kalt, die Schlange wird krank werden und sterben. Heizmatte? Nur für Glasterrarien. Heizstein? Das Terrarium wird abfackeln, ist außerdem unnatürlich. Heizlampe ohne Schutzkorb? Die Schlange wird sich daran verbrennen und verstümmeln. Heizlampe mit Schutzkorb? Die Schlange wird in den Schutzkorb kriechen und gegrillt. UV-Licht? Brauchen Strumpfbandnattern nicht. UV-Licht? Brauchen Strumpfbandnattern unbedingt.

Es blieb nur, nochmal mit gesundem Menschenverstand ganz neu an die Sache heranzugehen. Die Grundbeleuchtung realisierte ich schonmal über eine 15-W-Leuchtstoffröhre in einer Unterbauleuchte. Sie wird durch die obere Holzleiste in der Front verdeckt und leuchtet so ausschließlich nach innen. Das Kabel führte ich durch einen stabilen Kabelkanal an den linken Rand des Terrariums und dort durch eine passgenaue Bohrung hinaus.

Blieb die Heizlampe. Ich musste gestehen, dass die im Zoohandel erhältlichen Schutzkörbe viel zu weitmaschig waren, vor allem für junge Schlangen. Liebe Tierzubehör-Firmen: Da ist ne echte Marktlücke! Also kaufte ich erstmal eine Fassung. Statt einer 08/15-Keramikfassung nahm ich die „JBL TempSet basic“ (soviel Werbung muss mal sein), da sie sich viel leichter anbringen lässt. Nun probierte ich verschiedene Birnen aus, u.a. eine Energiesparlampe mit 13 Watt (in der Tat zu kalt und kein schönes Licht), verschiedene Kugellampen (schon nicht schlecht, aber unfokussiert) und einen 40-Watt-Strahler (je nach Tageszeit zu heiß und zu hell).

Meine Wahl fiel schließlich auf einen 28-Watt-Reflektorstrahler. Er erzeugte in der richtigen Entfernung die angepeilten Wärmeplätze um die 30 Grad und strahlte ein schönes warmes Licht als Kontrast zur Leuchtstoffröhre ab. Doch auch dieser wurde bei direkter Berührung zu heiß und stellte eine Gefahrenquelle dar. Der Zufall spielte mir schließlich die Lösung in die Hände. Beim Ausräumen der Spülmaschine entdeckte ich den absolut perfekten Schutzkorb in genau der richtigen Größe: Ein Spargelsieb!

Kurze telefonische Rückfrage bei der Frau des Hauses: „Kann ich das haben?“ – „Nein!“ – „Oh. Hmm, hab’s schon eingebaut.“ Genauer gesagt hatte ich es mit zwei Holzstücken als Halterung versehen, über die Lampe gestülpt und die Holzstücke am Terrarium festgeschraubt. Und man muss festhalten: Das passt wie A… auf Eimer!

CAM00469 CAM00473

Wie man zudem sehen kann, habe ich das Terrarium weiter abgedichtet. Strumpfbandnattern gelten als extreme Ausbruchskünstler. Die Glasscheiben wurden durch ein Schloss und einen abdichtenden Pappstreifen gesichert. Kabelführungen wurden mit Silikon abgedichtet. Eine große Keramikschale zum Baden, eine kleine als Fressnapf, ein Thermometer und eine weitere kleine Plattform aus Buchenholz vervollständigten das Ganze.

CAM00477

Die Bewohner konnten kommen! In der Zwischenzeit hatte ich bereits Kontakt zu einer wirklich sehr freundlichen Züchterin aus Aachen aufgenommen und mir ein Pärchen Karierte Strumpfbandnattern (Thamnophis marcianus marcianus) reserviert. Mit der aufgeregten Lieblingstochter im Schlepptau ging es eines Abends endlich auf die Reise, um die Zwerge (3 Monate alt) abzuholen. Die Namen wurden bereits im Voraus ausgehandelt: Lotta und Max.

DSCN1514 natter

Inzwischen kuscheln Lotta und Max in ihrem Terrarium miteinander, fühlen sich offensichtlich wohl und fressen gierig. Zu Futtern gibt es zur Zeit vor allem zerkleinerten Stint, bestäubt mit ein paar Vitaminen (insbesondere Vitamin B1). Später werde ich es auch mal mit Regenwürmern, Nacktschnecken etc. versuchen.

CAM00482

Projekt Mepevea – D’r Zoch kütt!

Als umweltbewusster oder zumindest geiziger Mitarbeiter des Öffentlichen Dienstes verzichtet man in der Regel bei längerer Anfahrt zum Arbeitsplatz auf den privaten PKW und nimmt freudig am öffentlichen Personennahverkehr (ÖPNV) teil. Sprich: Die Deutsche Bahn (und in Köln auch die KVB) ist unser Freund! Gerüchteweise sind die bereitgestellten Verkehrsmittel nicht immer dann vor Ort, wenn man es laut Fahrplan erwarten könnte. Damit man die daraus resultierende Wartezeit nicht am Bahnsteig, sondern am Frühstückstisch bzw. im bequemen Bürosessel verbringen kann, sind aktuelle Informationen über die Verspätungen unerlässlich.

Nun hat sich in der Vergangenheit der Service der DB dahingehend deutlich verbessert. So sind die Verspätungsinformationen inzwischen minutengenau und in Realzeit sowohl im Web als auch mittels der App „DB Navigator“ abrufbar. Der o.g. Mitarbeiter des Ö.D. ist allerdings nicht nur geizig (jaja, und umweltbewusst), sondern auch klickfaul und noch dazu ein Spielkind. So kam ich auf die Idee, sowohl in meinem trauten Heim als auch im Büro mittels ohnehin vorhandener Technik einen (für mich) optimalen Anzeigebildschirm zu basteln.

Dieser sollte nicht nur die aktuellen Verspätungen meiner Zugverbindungen, sondern auch weitere interessante Informationen anzeigen, genauer gesagt: Aktuelle Nachrichten, Wettervorhersage und (zuhause) zusätzlich das Kamerabild einer per WLAN verbundenen IP-Kamera. Als Hardware kamen ein günstiger und dank Notebook-Anschaffung ohnehin kaum noch gebrauchter PC-Bildschirm sowie zeitgemäß ein Raspberry Pi zum Einsatz. Das System sollte in jedem Fall ohne weitere Peripherie, speziell ohne Maus und Tastatur, auskommen. Softwareseitig setzte ich daher auf Google Chrome im Kiosk-Modus. Mittels der Erweiterung „Easy Auto Refresh“ kann man dafür sorgen, dass Chrome die angezeigte Seite automatisch einmal pro Minute neu lädt. Das Kamerabild läuft ohnehin im Streaming-Mode.

Der graphische Desktop des Raspi musste so eingestellt werden, dass er sich nicht automatisch abschaltet. Die Kontrolle über die Anzeige sollte ausschließlich per Ein/Aus-Knopf des Monitors ablaufen. Dies erreicht man über die eine Einstellung in LightDM.

Da ich mir die Installation und Konfiguration eines Webservers sparen wollte, verwende ich eine einfache lokale HTML-Seite auf dem Raspi. Die beiden gewünschten Elemente „Aktuelle Nachrichten“ und „Wettervorhersage“ sind sehr leicht über passende Widgets realisierbar. Ich habe hierzu die Angebote von wetterdienst.de und rp-online genutzt, es gibt jedoch zahlreiche weitere Anbieter.

mepevea

Richtig interessant wurde es dann bei der Einbindung der Verspätungsanzeige. Wie ich feststellen musste, bietet die Bahn leider keine geeignete API zu diesem Zweck. Mir blieb nichts anderes übrig als die entsprechende Webseite zu parsen. Diese Erkenntnis war die Geburtsstunde von Projekt „Mepevea“ (MEin PErsönlicher VErspätungsAnzeiger).

Wie erwähnt wollte ich auf die Installation und den Betrieb eines Webservers verzichten. Die Anzeige soll ja ohnehin nur für mich persönlich laufen. Daher musste ich die eigentliche Logik nebst Parser in ein Pythonskript packen, welches per Cronjob aufgerufen wird (ja, ich arbeite unter Linux und ignoriere Windows seit Jahren – die Portierung sollte aber kein großes Problem darstellen). Als Basismodul für den Parser dient natürlich „BeautifulSoup“, darüber hinaus werden urllib zum Abruf der Seite und einige weitere Module benötigt. Der Start lautet also:

#!/usr/bin/python
# -*- coding: utf-8 -*-
import bs4, urllib2, time, fileinput, sys, urllib

„fileinput“ verwende ich, um später den <div>-Block im HTML durch die korrekten Daten auszutauschen, z.B.:

for line in fileinput.FileInput("/home/pi/anzeige/bahnlinks.html",inplace=1):
if line.startswith('<div id="bahn">'):
   line = text
   sys.stdout.write(line)

Natürlich macht es Sinn, abhängig vom Wochentag und der Tageszeit die Anzeige zu variieren (Hinfahrt, Rückfahrt, Abend/Wochenende), also z.B.:

timestamp = time.localtime(time.time())
if timestamp[6] > 4:
   textlist.append("<b>Bahnanzeige erst am Montag wieder! Schönes Wochenende!</b>")

Hier wird schon klar: Individuelle Anpassung ist unerlässlich und ich kann die Beispiele nur anreißen. Keine Sorge: Am Ende werde ich als „großes Beispiel“ mein komplettes Skript bereitstellen.

Zentrales Element des Skriptes ist die Parserfunktion. Sie erhält als Parameter die URL der Bahn (dazu später) und jagt sie durch BeautifulSoup:

def parser(url):
   page = urllib2.urlopen(url).read()
   soup = bs4.BeautifulSoup(page)

Man möge mir an dieser Stelle glauben, dass wir die spannenden Inhalte erhalten, wenn wir nach den Keywords, genauer gesagt den <td>-Klassen „overview timelink“ und „overview tprt“ suchen:


zeilen = soup.find_all('td', {"class" : "overview timelink"})
verspaetungen = soup.find_all('td', {"class" : "overview tprt"})

Schon hier erkannt man, wo das größte Problem unserer schönen Bastelei liegt: Sollte die Bahn die Klassennamen aus irgendwelchen Gründen ändern, funktioniert natürlich nichts mehr. Das gleiche gilt für die URLs und die HTML-Struktur. Genau aus diesem Grund gibt es ja i.d.R. kapselnde APIs, aber die stehen hier wie gesagt nicht zur Verfügung.

Standardmäßig erhält man von der Bahn die nächsten drei Züge ab dem definierten Zeitpunkt. Ich habe die finale Version noch so erweitert, dass man dies variieren kann, aber das würde hier zu weit führen. Ebenso müsste ich nun eigentlich auf die Details von BeautifulSoup eingehen, um den folgenden Codeblock zu erläutern. Aber auch dies möchte ich mir sparen und auf die gute Online-Dokumentation des Moduls verweisen. Unsere Verbindungen sowie die aktuellen Verspätungen erhalten wir so:


parsedtext = ''
zaehler = 0
for zeile in zeilen:
   for zelle in zeile.children:
      parsedtext += zelle.contents[0]
   parsedtext += '<span style="color: red;">'
   for verspaetung in verspaetungen[zaehler].children:
      if str(verspaetungen[zaehler]).count("okmsg") > 1 or str(verspaetungen[zaehler]).count("red") > 1:
         parsedtext += verspaetung.contents[0]
         break
   parsedtext += '</span>'
   zaehler += 1

Ich bin mir zu 99% sicher, dass dies nicht die eleganteste Version ist, um die Informationen zu erhalten und aufzubereiten. Aber sie funktioniert. Wer das Ganze kürzer, schöner und verständlicher hinbekommt, ohne dass die Funktionalität leidet, möge sich bei mir melden.

Kommen wir nun zu den benötigten URLs. In einer ersten Version hatte ich pro Zug eine URL auf Basis des Bahntools „query2.exe“ verwendet, die auch deutlich einfacher zu parsen war (Anmerkung: Bitte von der Endung „.exe“ nicht täuschen lassen: Es handelt sich um einen Webservice, nicht um ein lokales Programm.). Leider musste ich feststellen, dass die Bahn bei jeder (geplanten) Mini-Fahrplanänderung die URL komplett verändert. Auf Dauer war das also leider keine Lösung. Stattdessen verwende ich nun die „Vorstufe“ namens „query.exe“. Diese hat klar definierte und – hoffentlich – dauerhaft beständige Parameter. Als Parameter benötigen wir den Code des Startbahnhofs, den Code des Zielbahnhofs und die Startzeit.

Während die Startzeit natürlich jedem selbst überlassen bleibt und einfach in der Form hh:mm verwendet wird, muss man sich die Codes (sog. IBNR) der Bahnhöfe einmalig heraussuchen. Dies geht zum Glück sehr einfach mittels einer Onlinesuche.

Lautet die IBNR des Startbahnhofs bspw. 8000208, die des Zielbahnhofs 8000133 und die gewünschte Startzeit ist 17:00 Uhr, lautet die gesuchte URL:

http://reiseauskunft.bahn.de/bin/query.exe/dox?S=8000208&Z=8000133&time=17:00&start=1

Damit lässt sich nun für jede beliebige Verbindung und Kombination von Tageszeiten ein passender Anzeiger (eben ein „Mepevea“) bauen.

Für weitere Ideen, Verbesserungsvorschläge etc. bin ich jederzeit dankbar. Und wenn jemand die Bahn überreden könnte, doch mal eine entsprechende API bereitzustellen, das wäre ein Traum. 😉

Wie versprochen: Den vollständigen Text des Skriptes sowie eine Beispiel-HTML-Seite findet man unter http://dl.distinguish.de/mepevea.zip