
Abbildung 2: Der Testaufbau für das Display ist nicht besonders aufwendig. Sind die Komponenten einmal besorgt, haben Sie diese schnell verbunden.
TIPP
Wollen Sie die (sehr kräftige) Hintergrundbeleuchtung des Displays abschalten, schließen Sie einfach den Pin LED nicht an 3,3 Volt an.
Daten anzeigen
Bei dem Programm, das zu guter Letzt alles zusammenbringt, lag der Fokus unter anderem darauf, dass nur Bibliotheken aus dem Standardumfang von Java zum Einsatz kamen. Externe Bibliotheken erhöhen nur die Komplexität. Daher fiel die Wahl auf den SAX-Parser, der aber etwas eigenwillig im Einsatz ist.
Listing 6 zeigt einen Auszug aus dem ContentHandler, mit dem Sie das Verhalten des SAX-Parsers steuern. Dahinter steckt die Idee, die Methoden aus dem Default-Content-Handler durch eigene Methoden zu überlagern. Die Methode characters schneidet die aktuellen Werte für die XML-Elemente aus dem Dokument und speichert sie in der Klassenvariable currentValue.
Listing 6
public class ContentXML implements ContentHandler {
private String currentValue;
public String result="";
private boolean found=false;
@Override
public void endElement(String s, String s1, String s2) throws SAXException {
if (s1.equals("name")) {
result=result+"Ort:" + currentValue+"\n";
}
if (s1.equals("w")&& !found) {
result=result+"Wind:" + currentValue+"\n";
}
if (s1.equals("tx")&& !found) {
result=result+"Temp:" + currentValue+"\n";
found=true;
}
}
@Override
public void characters(char[] chars, int i, int i1) throws SAXException {
currentValue = new String(chars, i, i1);
}
Die Methode endElement speichert beim Auftreten der Tags die Werte in den String result. Das ist schon die ganze Magie. Sie haben natürlich die Möglichkeit, erheblich mehr daraus zu machen, aber für das kleine Beispiel genügt das schon.
Die Klasse Main (Listing 7) legt als Erstes alle Konstanten fest, die das Programm benötigt. An dieser Stelle verwenden Sie Ihren Projektnamen und den zugehörigen API-Key. Der Wert für die Variable contrast hängt vom Typ des Displays und dem persönlichen Empfinden ab.
Listing 7
import com.pi4j.io.gpio.Pin;
import com.pi4j.io.gpio.RaspiPin;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
import java.math.BigInteger;
import java.security.MessageDigest;
public class Main {
// Pin Belegung des Displays
final static Pin sclk = RaspiPin.GPIO_00;
final static Pin din = RaspiPin.GPIO_01;
final static Pin dc = RaspiPin.GPIO_02;
final static Pin cs = RaspiPin.GPIO_03;
final static Pin rst = RaspiPin.GPIO_04;
static byte contrast = 0x30;
// Login-Daten für Wetter.com
final static String url="http://api.wetter.com/forecast/weather";
final static String ort="DE0010306";
final static String projectName="Projektname";
final static String apiKey="API-Schlüssel";
public static void main(String[] args) throws Exception {
// HTTP-Request
String s=projectName + apiKey + ort;
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(s.getBytes("UTF-8"),0,s.length());
BigInteger i=new BigInteger(1,md.digest());
String checksum = (String.format("%1$032X", i)).toLowerCase();
String forecastUrl = url+"/city/"+ort+"/project/"+projectName+"/cs/"+checksum;
//XML-Verarbeitung
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
ContentXML cx =new ContentXML();
xmlReader.setContentHandler(cx);
xmlReader.parse(forecastUrl);
String result=cx.result;
// LCD initialisieren und löschen
PCD8544 pcd = new PCD8544();
pcd.LCDInit(sclk, din, dc, cs, rst, contrast);
pcd.LCDclear();
pcd.LCDdrawstring(0, 0, result);
pcd.LCDdisplay();
}
}//class
In der Methode main baut das Programm als Erstes die URL für den Aufruf zusammen. Das ist so weit nichts Besonderes, bis auf das etwas umständliche Erstellen des MD5-Hashes. Die URL übergeben Sie an den XML-Parser, der erledigt den Rest. Zurück bekommen Sie mit result eine Zeichenkette, die Sie direkt ans Display weitergeben. Dabei gilt es, darauf zu achten, dass die Strings nicht zu lang ausfallen: Das Display zeigt nur 14 Zeichen pro Zeile an, längere Zeichenketten quittiert es mit einer Fehlermeldung.
Das komplette Programm implementiert keinerlei Fehlerbehandlung, reicht also alle Fehler bis zur aufrufenden Konsole durch. Das ist für das Beispiel in Ordnung. Möchten Sie das Programm aber ausbauen, lohnt es sich, sich darüber Gedanken zu machen. Die PCD8544-Bibliothek ist direkt aus C übersetzt und wirkt daher an einigen Stellen etwas Java-untypisch.
Um die Klassen zu kompilieren und zu starten, kommt der Befehl pi4j zum Einsatz. Im Beispiel lagen die drei Java-Dateien in einem Verzeichnis (Listing 8).
Listing 8
$ pi4j -c Main.java + javac -classpath '.:classes:*:classes:/opt/pi4j/lib/*' -d . Main.java $ pi4j -r Main + sudo java -classpath '.:classes:*:classes:/opt/pi4j/lib/*' Main
Cronjob einplanen
Zum Abschluss legen Sie noch einen Cronjob an, der das Programm einmal pro Stunde aufruft. Dazu geben Sie auf der Konsole crontab -e ein und erstellen dann einen Eintrag. Die Sache hat noch einen kleinen Haken: Da der Cronjob komplett ohne Informationen über die Umgebung startet, findet der Befehl pi4j die Klassen nicht. Daher behelfen Sie sich mit dem Shell-Skript do.bash, das ins richtige Verzeichnis wechselt und dann die Software startet (Listing 9). Listing 10 zeigt den entsprechenden Eintrag in die Crontab. Nachdem Sie diesen gespeichert haben, aktualisiert die Software einmal pro Stunde die Anzeige.
Listing 9
#!/bin/sh cd /home/pi/Verzeichnis /usr/bin/pi4j -r Main
Listing 10
0 * * * * /bin/bash -r /Pfad/do.bash





