Fliegende Haifische dank MQTT und JUnit

Eclipse IoT: 'Real men release with #mqtt sharks.'

Klemens Edler, Florian Pirchner
©Shutterstock.com/davidpstephens

Das Eclipse IoT-Projekt lässt Haifische fliegen. Wie das technisch möglich ist, soll dieser Artikel zeigen. Die Überschrift steht stellvertretend für die vergangenen Aktivitäten von Sharky und wurde von @dobermai im Zuge eines Democamps in München getweetet.

Vor einigen Monaten erhielten wir eine Einladung, am Eclipse Testing Day in Darmstadt eine Keynote zu halten. Uns war klar, dass es sich dabei um etwas Innovatives im Bereich Testing handeln muss. Andererseits muss der Inhalt einer Keynote nicht zwangsläufig einen praktischen Hintergrund haben. Somit entschlossen wir uns, etwas Visionäres zu implementieren: einen fliegenden Haifisch (Sharky), der auf Basis der Eclipse-IoT-Projekte gesteuert wird. Bei diesem fliegenden Hai handelt es sich um einen ca. einen Meter langen funkferngesteuerten „Air Swimmer“, der mit Helium gefüllt wird und sich durch Bewegen der Schwanzflosse vorwärts bewegt. Steigen und Sinken erfolgt durch Verschieben eines Gewichts, wodurch sich der Hai nach oben bzw. unten neigt (Abb. 1).
Die Brücke zur Testing-Thematik schlugen wir mit Ultraschallsensoren, welche ebenfalls über das MQTT-Protokoll mit JUnit-Tests verbunden sind. Die Idee war, im JUnit-Test eine Route für Sharky vorzugeben. Sharky befolgt diese und passiert am Ende der Route die Ultraschallschranke. Ein Signal zurück an den JUnit-Test signalisiert das Eintreffen von Sharky, und der Test geht auf grün.
Nach Wochen der Arbeit war es dann endlich so weit, und Sharky konnte durch den JUnit-Test in seiner freien Wildbahn – dem Vortragsraum – erfolgreich getestet werden. Dieser Artikel gibt Ihnen einen Einblick darüber, wie Sharky auf Basis von Eclipse IoT zum Leben erweckt wurde.

Abb. 1: Sharky

Überblick

Abb. 2: Architektur

Abbildung 2 gibt einen Überblick über die gewählte Architektur. Zentrales Element ist ein M2M-Broker, in unserem Fall Mosquitto. Er dient als Dispatcher von MQTT-Messages. Dabei können sich Clients auf sog. „Topics“ registrieren. Sendet nun ein Client eine Message auf ein Topic, erhalten alle für dieses Topic angemeldeten Clients diese Nachricht zugestellt. Für den Livebetrieb in Kundenprojekten werden wir zukünftig HiveMQ als Broker einsetzen, da dieser über ein flexibles Plug-in-System verfügt und durch seine Clusterfähigkeit und sein Laufzeitverhalten optimal für große Datenmengen ist.
Für die Steuerung von Sharky verwenden wir ein BeagleBone Black, ein ARM-Cortex-basiertes Embedded-Device mit 512 MB RAM, 2-GB-internem MMC-Flash und – für uns interessant – 92 Pin-Ausgängen zur Anbindung von Sensoren und Aktoren. Das darauf vorinstallierte Ångström-Linux wurde durch eine Embedded-Variante von Debian GNU/Linux ersetzt, da diese über umfangreichere Software-Repositories verfügt.
Die grundlegende Architektur sieht Folgendes vor: Das Steuerungs-BeagleBone-Black registriert sich am MQTT-Broker auf das Controller-Topic und erhält die Steuersignale als MQTT-Messages. Diese werden verarbeitet und GPIO-Pins entsprechend den eintreffenden Befehlen auf High bzw. Low gesetzt. Diese Spannungslevel werden an die Fernbedienung übertragen, wodurch ein Tastendruck simuliert wird. Dazu haben wir eine kleine elektronische Schaltung gebaut und zusätzliche Kabel in die Fernbedienung eingelötet, durch die die Schalter überbrückt werden können. Transistoren schließen bei einem GPIO-High-Signal die entsprechenden Schalter der Fernbedienung kurz, sodass die Fernbedienung die jeweiligen Steuersignale per Funkübertragung an den Sharky-RC-Empfänger sendet. Durch diese Vorgehensweise mussten wir keinerlei Änderungen an der Elektronik des Sendeteils der Fernbedienung und des Sharky-RC-Empfängers vornehmen.

Software

Für die softwareseitige Umsetzung beschlossen wir, Technologien aus dem Eclipse-Umfeld einzusetzen – in letzter Zeit sind ja zahlreiche Eclipse-Projekte im Embedded-Bereich und für den M2M-Einsatz entstanden. Für den fliegenden Hai waren die Projekte Mihini, Koneki und Paho relevant: Das Mihini-Framework stellt auf der Embedded-Hardware eine Laufzeitumgebung für die M2M-Anwendungen bereit, Koneki bietet die entsprechenden Entwicklungstools, und Paho sorgt für die Kommunikation zwischen Device und MQTT-Broker.
Die Installation erfolgte bei Mihini durch Kompilieren des Sourcecodes auf dem Steuerungs-BeagleBone; Koneki ist als Eclipse-Plug-in verfügbar. Paho banden wir als Library ein, die die benötigten MQTT-Clients sowohl in Java als auch in Lua zur Verfügung stellt – im Mihini-Framework kommt nämlich die Skriptsprache Lua zum Einsatz.
In der ersten Version verwendeten wir ein Vaadin-Web-UI, um ein Controllerboard zu implementieren. Auf Basis von Eclipse Paho erzeugt der serverseitige Vaadin-Teil MQTT-Messages mit Steuersignalen und sendet diese an den MQTT-Broker. Dieser wurde zu Demonstrationszwecken auf einem zweiten BeagleBone Black installiert (einfach aus den Debian-Repositories), um die räumliche Trennung von zentralem Broker und Embedded-Geräten sowie die Netzwerkkommunikation zwischen diesen simulieren und untersuchen zu können.

Sharky und Fernbedienung

Sharky besteht aus einer Kunststoffhülle und ist mit Helium gefüllt. Er enthält einen RC-Empfänger, um die Schwanzflosse und das Gewicht für die Neigung ansteuern zu können. Die Fernbedienung hat vier Taster:

• Schwanzflosse links: Bei Betätigung dieses Tasters bewegt sich die Schwanzflosse nach links.
• Schwanzflosse rechts: Bei Betätigung dieses Tasters bewegt sich die Schwanzflosse nach rechts.
• Steigen: Ein Gewicht am Bauch von Sharky wird über einen Servomotor nach hinten bewegt und somit der Schwerpunkt von Sharky verändert, was dazu führt, dass seine Nase nach oben zeigt.
• Tauchen: Das Gewicht wird nach vorne bewegt und Sharkys Nase zeigt nach unten.

Um Sharky nach vorne bewegen zu können, muss die Schwanzflosse abwechselnd nach links und rechts bewegt werden. Das bedeutet im manuellen Betrieb, dass der Taster für links und der Taster für rechts abwechselnd gedrückt werden müssen – bei der Ansteuerung über das BeagleBone übernimmt die Software diese Aufgabe, und es reicht die Angabe einer gewünschten Geschwindigkeit.

Aufmacherbild: Great White Shark von Shutterstock / Urheberrecht: davidpstephens

[ header = Seite 2: Web-Frontend]

Web-Frontend

Das Web-Frontend basiert auf Vaadin. Es ermöglicht die Steuersignale „Links“, „Rechts“, „Steigen“, „Tauchen“ und die Angabe einer gewünschten Geschwindigkeit. Um diese Befehle an das Steuerungs-BeagleBone zu senden, werden die Signale in MQTT-Messages verpackt. Die Commands sind sehr einfach aufgebaut und bestehen aus einfachen Strings wie „speed:3“, „rotate:-1“ usw. Somit ist die Größe der einzelnen Messages sehr gering, und die Übertragung erfolgt mit minimaler Latenz. Zusätzlich besitzt das Vaadin-UI eine Logtabelle, welche sämtliche versendeten MQTT-Messages anzeigt (Abb. 3).

Abb. 3: Vaadin-Web-UI

Steuersignale für links, rechts, Steigen und Tauchen werden relativ übertragen. Das bedeutet, dass nur +1 oder -1 gesendet wird. Weiterführende Berechnungen werden vom Controller-BeagleBone übernommen. Die Geschwindigkeit wird als absoluter Wert von 0 bis 5 übertragen. Für die Ansteuerung der Fernbedienung und damit des Hais ist ausschließlich der Controller-Beaglebone verantwortlich. Dieser berechnet aus den Befehlen „links:5“ und „speed:3“ die entsprechende Sequenz von Flossenschlägen und steuert anhand dieser die Fernbedienung an. So kann der Controller durch eine entsprechende Abfolge von Links- und Rechtsbewegungen der Schwanzflosse Sharky mit Geschwindigkeit 5 und Links 3 eine Kurve fliegen lassen.
Des Weiteren erlaubt es das Web-UI, einen „Alarmfence in cm“ zu definieren. Dies ist der Abstand, ab welchem die Ultraschallsensoren auslösen – das wird später für den Shark-Alarm benötigt.

Hardware

Als ersten Schritt der Implementierung nahmen wir den „Hack“ der Fernbedienung in Angriff: Diese ließ sich leicht öffnen und bot ausreichend Platz für Experimente mit Drahtbrücken, um die Funktionsweise der Schalter herauszufinden, und danach für das Einlöten von Kabeln, die das Überbrücken der Schalter von außen ermöglichen. Dabei stellte sich uns die Aufgabe, eine Transistorschaltung zu entwerfen und herzustellen, die bei Anliegen der 3,3 V, die ein GPIO des BeagleBone liefert, die 9 V der Fernsteuerung gegen Masse schaltet.
Die Verbindung zwischen dem Steuerungs-BeagleBone, dem zweiten BeagleBone, auf dem der MQTT-Broker läuft, und dem Rechner mit dem Vaadin-UI stellten wir über einen Router her. Die Platine mit unserer gelöteten Schaltung verbanden wir auf der Eingangsseite mit GPIOs des Steuerungs-BeagleBones und auf der Ausgangsseite mit den in die Fernsteuerung eingelöteten Kabeln zur Überbrückung der Taster.
Für das Setzen der Spannungslevel der GPIOs auf dem Steuerungs-BeagleBone schrieben wir kleine Bash-Skripte und setzten aus dem Mihini-Framework heraus Systemaufrufe ab, und das Embedded Debian übernahm den Rest, so z. B.:

cmd = "sudo /opt/mihini/gpiohigh "..LEFT_PIN
os.execute(cmd)

Durch diesen Aufruf konnten wir am entsprechenden Pin eine Spannung von 3,3 V anlegen, die über unsere Eigenbautransistorschaltung den Befehl für einen Flossenschlag nach links übermittelte.

Er fliegt!

Mit diesem Rüstzeug konnten wir uns an die ersten Flugversuche machen. Dazu war es nötig, eine Routine zu entwickeln, die die Befehle, die über MQTT hereinkommen, in Zeitdauern für High- bzw. Low-Spannung an den einzelnen Pins umrechnet und die jeweiligen Schaltungen vornimmt. Dabei stießen wir auf die Herausforderung, dass Lua (und mit ihm das Mihini-Framework) aus Gründen der Portabilität auf eine Vielzahl von Hardwareplattformen nur in ganzen Sekunden rechnen kann, wir für die Ansteuerung des Schwanzflossenmotors jedoch kleinere Zeiteinheiten benötigten. Als Ausweg bot sich der Einsatz der LuaSocket-Library, mit deren Hilfe theoretisch sogar Mikrosekunden verfügbar sind. Uns reichten Millisekunden, die wir folgendermaßen ermitteln konnten:

local socket = require("socket")
now = socket.gettime()*1000

Durch Setzen von Zeitpunkten für Aufrufe verschiedener Funktionen (Up/Down-Handler, Left/Right-Handler, MQTT-Client etc.) und Vergleich mit der wie oben ermittelten momentanen Systemzeit konnten wir so die gewünschte Genauigkeit erzielen. Dabei läuft, wie im Embedded-Bereich üblich, die Software im Normalfall in einer Endlosschleife, aus der sie nur im Bedarfsfall herausspringt. Die Endlosschleife der Sharky-Steuerung sieht aus wie in Listing 1 (udtim und fwtim sind die Zeitpunkte für den nächsten Aufruf von Up/Down- bzw. Forward-Handler).

-- a tiny scheduler to keep track of up/down 
-- and left/right movements at the same time
while running == true do

  -- check for incoming commands
  mqtt_client:handler()

  -- perform actions that are due
  now = socket.gettime()*1000
  if now > udtim then ud_handler() end
  if now > fwtim then fw_handler() end

end

Für den MQTT-Client, der in dieser Schleife aufgerufen wird, verwendeten wir die Implementierung von Eclipse Paho, das auch einen Lua-Client für MQTT zur Verfügung stellt. Dazu mussten wir nur die Dateien mqtt_library.lua und utility.lua aus dem Git Repository von Paho in das Mihini-Verzeichnis auf unserem Steuerungs-BeagleBone kopieren. Die Verwendung des Paho-MQTT-Clients ist dann recht simpel und funktioniert wie in Listing 2.

local MQTT = require("mqtt_library")

-- setup and connect MQTT client
mqtt_client = MQTT.client.create(MQTT_SERVER_URL, MQTT_SERVER_PORT, callback)
mqtt_client:connect(MQTT_CLIENT_ID)
mqtt_client:subscribe({ MQTT_RECEIVE_TOPIC })

-- check subscribed topics for new messages
mqtt_client:handler()

-- publish a string to a topic
mqtt_client:publish(MQTT_PUBLISH_TOPIC, "Hello World!")

An dieser Stelle eine Randbemerkung für Lua-Neulinge: Die Schreibweise mit Doppelpunkt ist eine Kurzform für Objektaufrufe und spart eine Selbstreferenz ein. Hat man z. B. mqtt_client als Instanz von MQTT.client erzeugt, kann man anstelle von MQTT.client.connect (mqtt_client, MQTT_CLIENT_ID) kürzer mqtt_client:connect(MQTT_CLIENT_ID) schreiben.
Den ersten Testflug von Sharky veranstalteten wir in einer Turnhalle, wo sich die gewählte Implementierung grundsätzlich bewährte – Sharky ließ sich mittels des Web-UI steuern. Für die Zeitdauern, die die GPIOs gesetzt bzw. gelöscht sein müssen, um ein brauchbares Ergebnis zu liefern, waren bloß kleinere Kalibrierungsarbeiten nötig, und danach war Sharky flugtauglich und einsatzbereit.

Plus: Entfernungsmessung

Beim Eclipse Testing Day wollten wir nicht nur den Haifisch fliegen lassen, sondern auch etwas testen. Dazu hatten wir die Idee, Sharky mit Ultraschallsensoren zu orten und bei Unterschreiten eines gewissen Mindestabstands zu einem definierten „Strand“ Haialarm auszulösen. Durch die Möglichkeit, Befehlsabfolgen zu speichern, ist es möglich, Sharky einer definierten Flugbahn folgen zu lassen, die einen „Shark Alarm“ auslöst. Die Steuerbefehle können von einem JUnit-Test gesendet werden, der danach auf das Alarmsignal wartet.
Dazu war weitere Hardware nötig: Einerseits die Sensoren, andererseits ein Arduino (wir wählten das Modell Arduino Due, da dieser mit 3,3 V arbeitet und somit direkt mit dem BeagleBone verbunden werden kann). Den Arduino benötigten wir deshalb, weil zur Ortung mittels Ultraschall eine präzise Zeitmessung nötig ist und dies, wie oben berichtet, mit Mihini schwierig ist.
Eine zusätzliche Hürde war, dass die Ultraschallsensoren mit 5 V arbeiten – wir mussten also doch auf Pegelwandler zurückgreifen. Von der Softwareseite her war die Ultraschallmessung jedoch einfach; im Internet gibt es dazu zahlreiche Beispiele. Blieb uns die Frage der Übertragung der Messdaten auf den BeagleBone. Dabei entschieden wir uns schließlich für die Kommunikation über die serielle UART-Schnittstelle: Der BeagleBone sendet in gewissen Abständen (die wie oben in einer Endlosschleife gemessen werden) einen Character als Trigger an den Arduino, dieser nimmt die Messung vor und antwortet mit einem String, in den die Messwerte der einzelnen Sensoren verpackt sind.
Dieser String wird vom BeagleBone interpretiert; wenn ein Messwert die definierte Schwelle unterschreitet, wird Haialarm ausgelöst: Zum einen wird die Meldung „SHARK ALARM!!!“ an ein eigenes Topic gepusht, zum anderen wird über einen GPIO und eine weitere Transistorschaltung ein rotes Blinklicht aktiviert.
Damit war unser Setup komplett: Wir konnten den Hai über das Web-Frontend steuern, die Befehlssequenz aufzeichnen und von einem JUnit-Test wiederholen lassen, der einen Shark-Alarm auf dem Alarm-Topic erwartet. In der Praxis zeigten sich jedoch zwei Schwierigkeiten: Einerseits reagiert Sharky extrem empfindlich auf Luftströmungen und Temperaturschwankungen, sodass die exakte Wiederholung einer Flugbahn etwas wohlwollende Vorstellungskraft erforderte. Andererseits sind die Ultraschallsensoren in großen Räumen nicht sehr verlässlich, da sie mitunter kein Echo empfangen bzw. das Signal eines anderen Sensors als eigenes Echo interpretieren.
Bei der Vorführung am Testing Day nutzten wir daher einen Flipchart als Reflektor für das Ultraschallsignal und suchten eine genaue Ausrichtung der Sensoren, bei der es zu keinen Fehlmessungen kam. Mit etwas Hilfe schaffte Sharky dann sogar die gewünschte Flugbahn, sodass der Alarm ausgelöst wurde und der JUnit-Test grün aufleuchtete.

[ header = Seite 3: Plus: Gestensteuerung]

Plus: Gestensteuerung

Die Gestensteuerung stellt eine Möglichkeit dar, um Sharky mittels Bewegung von Händen zu steuern. Eine 3-D-Kamera (ASUS Xtion PRO) ähnlich der Microsoft Kinect erzeugt Bilder inkl. Tiefeneigenschaften von der steuernden Person. Durch Kopplung mit dem Open-Source-Produkt OpenNI (Open Natural Interface) zur Transformation der Bilder in Koordinaten der Hände konnten Bewegungen in Zahlen ausgedrückt werden.
OpenNI liefert zu jedem Frame die räumlichen x/y/z-Koordinaten der Hände. Um diese in Gesten wie „Sharky tauchen“, „Sharky links“ … umwandeln zu können, benötigte es ein Projekt, um die Koordinaten bzw. deren Veränderung in Abhängigkeit von der Zeit als Gesten auszuwerten. Dafür verwenden wir das Open-Source-Projekt JNect. Dieses stellt ein Body-Model auf Basis von EMF zur Verfügung, des Weiteren eine Implementierung, um Gesture-Detectors registrieren zu können. Wird eine Geste erkannt, so wird diese in Form der oben definierten MQTT-Messages an den M2M-Broker gesendet und kann so zur Steuerung von Sharky verwendet werden.
In diesem Fall haben wir die Implementierung des Sharky-Controller-BeagleBone geändert, um absolute Werte für Befehle verwenden zu können. JNect sendet bspw. „left:5“ im Gegensatz zum Web-UI, das nur relative Werte wie „rotate:-1“ sendet.
Für die Gestenerkennung wurde ein dritter BeagleBone eingesetzt, um zeigen zu können, dass Equinox auch auf der beschränkten Hardware eines BeagleBone gestartet werden kann und auch JNect, EMF … dort einwandfrei laufen. Es zeigten sich keinerlei Probleme in Bezug auf die Performance, sodass wir Sharky mit Gestensteuerung auf der EclipseCon Europe zeigen konnten.

Plus: Release-Trigger

Die nächste Erweiterung des Sharky-Projekts ergab sich, als wir zum Eclipse Democamp München eingeladen wurden, um ihn dort zu präsentieren. Dort besteht bereits die Tradition, mithilfe eines Embedded-Geräts („MakeyMakey“) ein EMFStore-Release zu triggern. Dabei wird das Schließen eines Stromkreises – etwa mittels eines Buzzer-Knopfs oder der Flüssigkeit in einem Weißbierglas – von MakeyMakey in einen entsprechenden Befehl umgesetzt. Nun lag es auf der Hand, diesmal Sharky den Release anstoßen zu lassen.
Dazu löteten wir schon wieder eine Transistorschaltung, die bei Anliegen einer Spannung an der Basis einen Kurzschluss zwischen zwei Kontakten herstellt. An dieses „Interface“ konnte das MakeyMakey mit Krokodilklemmen angeschlossen werden. Auf unserer Seite modifizierten wir den Sharky-Controller so, dass bei „Shark-Alarm“ die beiden Klemmen kurzgeschlossen wurden.
Im vollen Vertrauen auf Sharky und ohne zu testen, bauten wir in München eine Vorrichtung, die es dem Hai erlauben sollte, den Alarm auszulösen und so das Release anzustoßen. Dazu hängten wir einen Bogen Papier, auf den wir eine Zielscheibe gemalt hatten, zwischen zwei Stühle und richteten die Ultraschallsensoren von hinten darauf. Wir maßen die Entfernung zum Papier aus und stellten den „Alarmfence“ auf zwei Zentimeter weniger ein. Somit würde, wenn Sharky die Zielscheibe mit ausreichend Schwung treffen sollte, das Papier nach hinten schwingen und durch den verringerten Abstand den Haialarm auslösen – und über GPIO und Transistor würde das MakeyMakey kurzgeschlossen und somit das Release getriggert. Und unglaublich, aber wahr: Obwohl nie getestet, funktionierte das Arrangement auf Anhieb, und Sharky stieß das EMFStore-Release an.
Abb. 4: Sharky hits EMFStore Release Trigger (Quelle: http://bit.ly/1gSjWfR)

Abbildung 4 zeigt Sharky kurz nach dem Treffen der Zielscheibe im Sturzflug; das EMFStore-Release war somit ausgelöst.

Whats next? Mindwave control

Da Sharky auf der EclipseCon North America und der JAX 2014 seine nächsten Auftritte hat, stellte sich uns die Frage, wie wir die bisherigen Ergebnisse noch toppen können. Eine Brainstorming-Session brachte uns auf die Idee, dass es äußerst eindrucksvoll wäre, Sharky mittels Gedanken steuern zu können. Begeistert von dieser Idee befragten wir das Web, ob es finanzierbare Technologien gibt, mit denen wir dies umsetzen können.

Sofort ins Auge ist uns das EPOC-Neuro-Headset von Emotiv gefallen. Dieses Headset ist in Verbindung mit dem Emotiv-SDK in der Lage, Gehirnströme in Befehle umzuwandeln. Auf Basis einer Simulation lernt das System, die Gehirnströme des jeweiligen Users in Bezug auf eine zu erledigende Aufgabe zu interpretieren. Ein interessantes Video finden sie auf Youtube, welches das Training des Systems mittels eines schwebenden Würfels in einer Simulation zeigt.
Der nächste Schritt in der Evolution von Sharky wird es sein, mittels des Neuro-Headsets MQTT-Befehle erstellen und an den MQTT-Broker senden zu können. Der aktuelle Plan ist, Java-Wrapper für das SDK zu verwenden. Eine Java-Implementierung erhält die vom Emotiv-SDK erkannten Neuro-Befehle wie „up“, „down“, „rotate“, … und verwandelt diese in MQTT-Befehle, die per Paho versendet werden. Eine Anpassung des Sharky-Controller-BeagleBone ist dazu voraussichtlich nicht notwendig.
Dieses Projekt befindet sich allerdings noch in der frühen Startphase, und ob es wirklich möglich sein wird, Sharky auf der EclipseCon bzw. JAX mit Gedanken steuern zu können, wird man sehen … See you there!

Geschrieben von
Klemens Edler
Klemens Edler
Klemens Edler beschäftigt sich intensiv mit dem Bereich M2M und Embedded Devices. Sein großes Steckenpferd sind Verschlüsselungstechnologien. 2014 wird er 50 Prozent der Lunifera GmbH übernehmen und den Bereich M2M aufbauen.  
Florian Pirchner
Florian Pirchner
Florian Pirchner ist selbstständiger Softwarearchitekt, lebt und arbeitet in Wien. Aktuell beschäftigt er sich als Project Lead in einem internationalen Team mit dem Open-Source-Projekt „lunifera.org – OSGi-Services for Business Applications“. Auf Basis von Modellabstraktionen und der Verwendung von OSGi-Spezifikationen soll ein hoch erweiterbarer und einfach zu verwendender Kernel für Businessapplikationen geschaffen werden.
Kommentare

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu: