JInfoBox

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
    • Offizieller Beitrag

    Java InfoBox (JInfoBox)

    Hier wird eine klein Informationskiste zusammen gebaut, welche mich über aktuelle Nachrichten im Socialweb informieren soll.
    Zusätzlich wird es auch möglich sein, einen kleinen Timer via Webseite zu stellen.
    Die Idee von meinem Projekt findet ihr in meinem Blog.


    Vorbereitung

    Hardware
    Als erstes werde ich schauen was ich wo anschließen muss.
    Ich habe 3 LED´s, einen Buzzer, ein 4 Segement Display und 2 Taster.
    Die LEDs, beide Taster sowie den Buzzer können direkt an ein GPIO Port angehangen werden.
    Dazu gibt es auf dem LinkerKit Baseboard die Anschlüsse JP4 bis JP8. Wobei der JP4 Anschluss im Betriebssystem noch umkonfiguriert werden muss,
    da es sich da um einen Seriellenport handelt.
    Die 4 Segement Anzeige besitzt einen TM1637 Treiber, welcher über I2C betrieben wird.
    Daher muss die Anzeige an den Anschluss JP3 geklemmt werden.

    Blockplan.jpg
    Blockdiagram

    Software
    Die Software werde ich in Java schreiben. Einfach weil ich beruflich damit zu tun habe und
    immer gerne neue Bibliotheken ausprobieren will ;)
    Von meiner Projektidee ergeben sich folgende Funktionen:

    - einen Timer der in X Minuten ein Event wirft
    - einen Timer der um eine Uhrzeit ein Event wirft
    - Steuerung des Buzzer´s
    - Eingabe des Alarms über eine Webseite (für Smartphones)

    - Steuerung der LED´s
    - Email Postfach abfragen
    - Facebook API abfragen
    - Twitter API abfragen
    - Taster auslesen um die LED´s zurück zusetzen

    Jede einzelne Funktion wird ein eigenes Modul und wird später durch das Hauptprogramm vereinfacht
    abgefragt oder gesteuert.


    Die Entwicklung
    Alarm
    Zunächst habe ich erstmal gemeinsamkeiten von dem Alarm in Minuten und der Uhrzeit gesucht.
    Jeden Alarm muss ich in einem eigenem Thread halten und ablaufen lassen.
    Außerdem soll es möglich sein das sich jemand "anmelden" kann,
    um ein Event zu bekommen wenn der Alarm ausgelöst wurde (siehe Observer Pattern).
    Zusätzlich wird sich der Zeitpunkt gemerkt, wann der Alarm eingestellt wurde.
    Das wären alle gemeinsamkeiten :)
    Jetzt kann ich von dieser Klasse aus jeweils eine Ableitung erstellen für die jeweiligen Alarm Typen.

    Alarm in X Minuten
    Für diese Ableitung muss ich eine Minutenanzahl im Konstruktor übergeben.
    Im Konstruktor berechne ich mir auch die Uhrzeit wann der Alarm ausgelöst werden soll und speicher diese in einem Klassenattribut weg.
    Wenn nun der Thread gestartet wird, wird immer die aktuelle Uhrzeit vom System ausgelesen und mit der Zieluhrzeit verglichen. Wenn die Zieluhrzeit dabei hinter der aktuellen Uhrzeit liegt, wird der Thread interrupted und alle Klassen, welche sich für dieses Event eingetragen haben, werden benachrichtigt.

    Code
    System.out.println("Alarmiere mich in 5 Minuten");
    Alarm a1 = new AlarmIn(5);
    a1.addListener(new AlarmListener() {
    	@Override
    	public void alarm() {
    		System.out.println("!!Alarm Alarm Alarm!!");
    	}
    });

    Alarm um Uhrzeit
    Im gegensatz zu der Alarm in X Minuten Funktion brauche ich hier nur den Timestamp übergeben.
    Anhand diesem Timestamp kann ich dann meine Zieluhrzeit setzten und auch hier ein Alarm auslösen.

    Externer Inhalt www.youtube.com
    Inhalte von externen Seiten werden ohne deine Zustimmung nicht automatisch geladen und angezeigt.
    Durch die Aktivierung der externen Inhalte erklärst du dich damit einverstanden, dass personenbezogene Daten an Drittplattformen übermittelt werden. Mehr Informationen dazu haben wir in unserer Datenschutzerklärung zur Verfügung gestellt.

    Steuerung der LEDs
    Die LED´s gestaltet sich relativ einfach: In dem Datenblatt schauen an welchem GPIO Pin der jeweilige Anschluss beim baseboard geht, diesen Pin dann auf High setzen und schon leuchtet die LED.
    Eine Funktion um die LED´s zum blinken zu bringen folgt später ;)

    Code
    LEDControl led = new LEDControl();
    led.gelb(); // gelbe LED an
    led.gelb(); // gelbe LED aus
    led.gelb(true); // gelbe LED an
    
    
    led.blau(); // blaue LED an
    
    
    led.resetAll(); // alle LEDs aus

    Steuerung des Buzzers
    Ein Buzzer braucht ein wenig mehr als einfach den Pin auf High zu setzen. Um einen Ton rauszubekommen, muss der Buzzer Pin immer wieder von High auf Low und andersrum gesetzt werden. Dabei ist die zeitliche Abstand zwischen den Signalen ausschlaggebend für den Ton. Ohne Dokumentation war es sau schwer die Zeitabstände herraus zukriegen.
    Ich hab echt lange rumprobiert welche Zeiten am besten passen könnten aber zufrieden bin ich mit dem Ton nicht.
    Zusätzlich war ich mir nicht sicher ob Java viel zu langsam wäre, um den Buzzer richtig anzusteuern. Deshalb habe ich mir noch ein C Programm geschrieben aber leider führte das auch nicht zum Erfolg...

    Code
    BuzzerControl buzzer = new BuzzerControl();
    buzzer.piep(); // Buzzer macht geraeusche
    Thread.sleep(5000); // wartet 5 Sekunden
    buzzer.stopBeeping(); // Buzzer ist still

    Die API Abfragen
    Ich möchte zu unterschiedlichen Diensten eine Abfrage starten. Zum Beispiel möchte ich wissen ob ich neue EMails im Postfach habe oder ich eine Nachricht auf Facebook bekommen habe. Jede dieser Abfragen lässt sich wieder verallgemeinern. Ich möchte eine check() Methode für jede Abfrage haben und ich möchte auch dass die Abfrage mir ein Event liefert, wenn es etwas neues gibt. Zusätzlich sollen diese Abfragen in einem eigenen Thread laufen, um das Hauptprogramm nicht damit zu belasten.

    Abfrage eines EMail Postfaches
    Die Abfrage eines EMail Postfaches gestaltete sich einfacher als ich erst gedacht habe.
    Java bietet dazu eine Allround Bibliothek - Javax. Mit Javax erstellt man zunächst eine Session, verbindet sich mit dem Server und öffnet dann ein Ordner auf dem Konto.
    Die einzige Logik die implementiert werden musste ist, die Abfrage ob es neue EMails gibt. Von Haus aus gibt es sowas nicht (oder ich habs nicht gefunden ;) ). Daher merke ich mir die Uhrzeit / Datum wann ich das Postfach zuletzt abgefragt habe. Wenn ich danach eine neue Abfrage starte und da sind Mails bei, welche aktueller sind als das gemerkte Datum, dann handelt es sich dabei um eine neue Mail.

    Externer Inhalt www.youtube.com
    Inhalte von externen Seiten werden ohne deine Zustimmung nicht automatisch geladen und angezeigt.
    Durch die Aktivierung der externen Inhalte erklärst du dich damit einverstanden, dass personenbezogene Daten an Drittplattformen übermittelt werden. Mehr Informationen dazu haben wir in unserer Datenschutzerklärung zur Verfügung gestellt.

    Steuerung des 4 Segementen Display
    Zunächst muss im System die I2C Modul eingeschaltet werden.
    Als erstes wird das Modul von der Blacklist entfernt durch setzen einer # am Anfang:

    Code
    $ cat /etc/modprobe.d/raspi-blacklist.conf
    # blacklist spi and i2c by default (many users don't need them)
    # blacklist spi-bcm2708
    # blacklist i2c-bcm2708

    Danach muss noch i2c_dev und i2c-bcm2708 in die /etc/modules eingetragen werden.
    Zum Schluss den Pi neustarten oooooder für faule Socken reicht es das Modul per Hand zu laden ;)

    Code
    modprobe i2c_dev

    Damit wäre I2C einsatzbereit :)

    Das 4 Segement Modul habe ich an dem JP3 vom Baseboard angeschlossen - der einzige Port mit I2C. Dank der freundlichen Hilfe von sd582 und seinem Beispiel Script, konnte ich zum ersten mal etwas auf dem Display erkennen. Ohne das Beispiel wäre es mir sicherlich nicht so leicht gefallen - dafür vielen Dank! :)
    Das Script habe ich dann quasi 1:1 in Java übersetzt und in meine Alarm Klasse eingearbeitet. Letztlich sieht der Aufruf der Methode so aus:

    Code
    //diff ist die Differenz zwischen Start und End Zeit des Alarms.
    Date n = new Date(diff);
    show(n);


    und schon zeigt das Display die Uhrzeit an ;)
    Wenn die Zeit (die angezeigt werden soll) weniger als eine Minute beträgt dann werden die letzten Sekunden ausgegeben - um das Display ein wenig zu füllen.

    Steuerung über eine Webseite
    Zur Steuerung der Alarmzeiten über eine Webseite wollte ich das Dropwizard Framework ausprobieren. Dieses Framework besitzt viele kleine (und große) Tools für Entwickler um das Programmieren zu erleichtern. Allerdings ist das für mein Projekt ein wenig wie mit einer riesen Kanone auf Spatzen zu schießen - aber wie ich Anfangs schon schrieb: ich mag ein paar Bibliotheken ausprobieren ;)

    Dropwizard besitzt einen Jetty Webserver, welcher super simple zu benutzen ist.
    Es muss eine kleine ftl Datei angelegt werden (quasi eine normale html Seite). Um nun auch auf irgendwelche Formulare zu reagieren, muss zusätzlich eine Ressource Klasse eingebunden werden. Diese Klasse wird über diverse Annotationen eingestellt und ruft letztlich eine Methode über eine URL auf.

    Spoiler anzeigen

    Die Methode startAlarm würde dann mit folgender URL aufgerufen:
    IP-PI:8080/alarmIn/?minutes=1

    Derzeit bin ich echt begeistert von diesem Framework. Es ist super einfach ein REST Service zu programmieren oder wie ich jetzt rausgefunden habe, eine Webseite mit Java Funktionen. Und alles wohlgemerkt in einer Jar verpackt ;)


    Hauptprogramm
    Dank der einfachen Module, ist das Hauptprogramm super simpel ;)
    Das Hauptprogramm implementiert alle Listener die ich im Vorfeld definiert habe (AlarmListener, TasterListener, CheckerListener). Dort werden dann die unterschiedlichen Aktionen abgearbeitet.

    Spoiler anzeigen

    Um nun auch die Benachrichtigungen zu erhalten, muss sich das Hauptprogramm bei den jeweiligen Klassen "anmelden".

    Mehr muss das Hauptprogramm nicht machen ;)
    Durch Dropwizard wird das Programm nicht beendet - deswegen kann auf eine Endlos-Schleife verzichtet werden.

    Schluss
    Das Projekt hat mir super viel spaß gemacht - vor allem am Ende das Hauptprogramm zusammen zubauen. Da merkt man erst ob man einen Designfehler begangen hat und gar nichts klappt ;) Leider hat an verschiedenen Stellen an Dokumentation der Linksprite Bauteile gehapert... Wie schon geschrieben ohne das Beispiel Script für das 4 Segement Display wäre ein großer Teil des Projekts nicht realisierbar gewesen.
    Letztenendes haben die Linkspire Bauteile irgendwie das erreicht, was der Hersteller wollte - einfache Module, welche sich super simpel zusammenstecken lassen und mit denen man sehr schöne Projekte aufbauen kann (als Neuling).

    Java / Maven Projekt als Download: hier

    Ich bin ein gefallener Engel namens Turael.

    Einst vor langer Zeit rebelierte ich im Himmel bis Gott mich auf die Erde verbannte.

    Doch meine taten werden kein ende finden....

    Einmal editiert, zuletzt von Turael (17. März 2015 um 23:38)

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!