Hello IoT World!

Internet of Things mit Java 8 und TinkerForge, Teil 1

Sven Ruppert
© S&S Media

Das Internet of Things (IoT) ist eines der neuen spannenden Themen in der Java-Welt. Mit Java 8 SE Embedded steht nun auch eine Alternative zur Java-ME-Version zu Verfügung. In dieser neuen Serie werden wir uns dem Thema IoT aus der Sicht eines Java-Entwicklers nähern.

Die Welt des IoT beginnt zu wachsen. Immer mehr Java-Entwickler fangen an, sich dort umzusehen und erste Experimente zu wagen. Wie kann man damit beginnen? Welche Möglichkeiten gibt es? Wir werden uns nun Schritt für Schritt diesem Thema zuwenden. Zum Einstieg habe ich mich für TinkerForge entschieden.      

Elektronik für Softwareentwickler

Elektronik hat für einen Softwareentwickler immer den Beigeschmack von Lötkolben und viel filigraner manueller Tätigkeit, bevor man mit dem Eigentlichen, der Softwareentwicklung, beginnen kann.

Es gibt aber auch so etwas wie einen Legokasten für den Java-Entwickler. Ich spreche hier von den Produkten von TinkerForge. Hier werden dem Entwickler verschiedene Elemente an die Hand gegeben, die kombiniert werden können – zum Beispiel, indem Sensoren an einen MasterBrick angeschlossen werden. Der MasterBrick selbst wiederum wird per USB mit Strom versorgt. Damit haben wir unseren ersten Testaufbau auch schon abgeschlossen. Zeit, die für den Aufbau benötigt wird: 3 Minuten. Nun können wir uns also direkt der Software zuwenden. Um die Hardware zu verwenden, müssen zwei Dienste auf dem Rechner installiert werden. Das ist zum einen der Dienst, der die Kommunikation zwischen MasterBrick, Sensor und Rechner ermöglicht. Zum anderen ist es ein Viewer, der für die Konfiguration, Updates von Firmware und ähnliches als auch zur ersten Auswertung der Sensordaten zu verwenden ist. Unter Windows 8 lief bei mir die Installation reibungslos. Dauer der Installation: 5 Minuten. Damit ist das Setup binnen 15 abgeschlossen, und man kann loslegen.

Hello IoT World!

Jeder beginnt ein neues Thema in der Softwareentwicklung mit einem HelloWorld. Wir wollen diese Tradition nicht brechen. Hierfür benötigen wir, wie gerade beschrieben, einen MasterBrick mit einem Sensor. Der Einfachheit wegen habe ich mich hier für einen Temperatursensor entschieden. Es stellt sich nun die Frage, wie die Inbetriebnahme erfolgen soll. Sobald die Verbindung zu dem USB-Port aufgebaut worden ist, wird die Kombination zum Leben erweckt. Der MasterBrick signalisiert mit einem blauen Licht, dass er lebt. Als erstes starten wir den Service, den wir im Vorlauf installiert haben. Jedes Element besitzt eine UID, die später für die Kommunikation benötigt wird. Um diese herauszubekommen, starten wir den Viewer (brickv), den wir ebenfalls installiert hatten. Dort werden nach einem „connect“ die benötigten Daten angezeigt. In meinem Fall besitzt der Sensor die UID dXj.

Abb. 1: BrickV – Viewer für TinkerForge Elemente

Unter [1] sind die Quelltexte passend zu diesem Artikel zu finden. In diesem Repository befinden sich auch die Sprachbindings die für die Kommunikation mit den TinkerForge-Komponenten benötigt wird. Das Ansprechen des Temperatursensors erfolgt nun in wenigen Schritten.

  • Erzeugen einer IPConnection
  • Erzeugen einer Instanz, die einen Temperatursensor repräsentiert
  • Konfigurieren des Sensors
  • Hinzufügen des ActionListeners

Der letzte Schritt ist für die weitere Verarbeitung der wichtigste. Die ermittelten Werte dieses Sensors werden hier in der inneren anonymen Klasse innerhalb der Methode temperature verarbeitet. Immer dann, wenn ein Zeitintervall vorüber ist und der Wert sich zu dem als letztes gelieferten geändert hat, wird diese Methode aufgerufen.

import com.tinkerforge.BrickletTemperature;
import com.tinkerforge.IPConnection;

public class ExampleCallback {
    private static final String host = "localhost";
    private static final int port = 4223;
    private static final String UID = "dXj"; 
    public static void main(String args[]) throws Exception {
        IPConnection ipcon = new IPConnection(); 
        BrickletTemperature temp = new BrickletTemperature(UID, ipcon); 
        ipcon.connect(host, port); 
        temp.setTemperatureCallbackPeriod(1000);
        temp.addTemperatureListener(new 
          BrickletTemperature.TemperatureListener() {
            public void temperature(short temperature) {
                System.out.println("Temperature: " 
                   + temperature/100.0 + " °C");
            }
        });
        ipcon.disconnect();
    }
}

Messwerte der Nacht aufzeichnen und darstellen

Der Beginn ist damit sehr einfach und schnell realisiert. Nun wollen wir als kleine Fingerübung die Messwerte der Nacht aufnehmen und sehen, ob die Heizung wie vorgesehen in die Nachtabsenkung geschaltet wird. Dazu wird der Sensor die gesamte Nacht über aktiv gehalten, die Messwerte in eine transiente Liste überführt und in einer kleinen JavaFX-Anwendung als LineChart dargestellt. 

public class HelloTinkerForge extends Application {

    private static final String host = "localhost";
    private static final int port = 4223;
    private static final String UID = "dXj"; 


    public static void main(String args[]) throws Exception {
        launch(args);
    }

    public static XYChart.Series series;

    @Override
    public void start(Stage stage) {
        stage.setTitle("Line Chart TinkerForge Sample");
        final DateAxis dateAxis = new DateAxis();
        final NumberAxis yAxis = new NumberAxis();
        dateAxis.setLabel("Time of Temp");
        final LineChart lineChart 
           = new LineChart<>(dateAxis, yAxis);

        lineChart.setTitle("Temp Monitoring");

        series = new XYChart.Series();
        series.setName("My temps");
        final ObservableList seriesData = series.getData();

        lineChart.getData().add(series);
        Scene scene = new Scene(lineChart, 800, 600);
        stage.setScene(scene);
        stage.show();
        new Worker(seriesData).start();

    }

    public static class Worker extends Thread {
        final ObservableList seriesData;
        public Worker(final ObservableList seriesData) {
            setDaemon(true);
            setName("Thread Temp");
            this.seriesData = seriesData;
        }

        @Override
        public void run() {
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    IPConnection ipcon = new IPConnection();
                    BrickletTemperature temp 
                        = new BrickletTemperature(UID, ipcon);
                    try {
                        ipcon.connect(host, port);
                        temp.setTemperatureCallbackPeriod(1000);
                        temp.addTemperatureListener(
                          new BrickletTemperature.TemperatureListener() {
                            public void temperature(short temperature) {
                                Platform.runLater(new Runnable() {
                                    @Override
                                    public void run() {
                                        final double temp 
                                           = temperature / 100.0;
                                        final int counter 
                                           = seriesData.size() + 1;
                                        final XYChart.Data data 
                                           = new XYChart.Data(
                                                 new Date(), temp);
                                        seriesData.add(data);
                                    }
                                });
                            }
                        });
                    } catch (IOException | 
                             AlreadyConnectedException | 
                             TimeoutException | 
                             NotConnectedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }
}

Abb. 2: Beispielhafte Messwerte

Fazit

Mit diesem einfachen Beispiel konnten wir den ersten Sensor ansprechen und die Daten visualisieren. Das Grundkonzept ist recht einfach, die Handhabung sehr robust. In den nächsten Teilen werden wir uns verschiedene Sensoren und Einsatzgebiete ansehen. Mögen die IoT – Spiele beginnen…..

Die Quelltexte zu diesem Text sind unter [1] zu finden. Wer umfangreichere Beispiele zu diesem Thema sehen möchte, dem empfehle ich einen Blick auf [2].

 

Geschrieben von
Sven Ruppert
Sven Ruppert
Sven Ruppert arbeitet seit 1996 mit Java und ist Developer Advocate bei Vaadin. In seiner Freizeit spricht er auf internationalen und nationalen Konferenzen, schreibt für IT-Magazine und für Tech-Portale. Twitter: @SvenRuppert
Kommentare

Hinterlasse einen Kommentar

3 Kommentare auf "Internet of Things mit Java 8 und TinkerForge, Teil 1"

avatar
400
  Subscribe  
Benachrichtige mich zu:
Oliver
Gast

Hilfreich wäre es zu wissen, welche Sensoren im Tutorial noch vorkommen werden. Dann könnte man die gesammelt bei Thinkerforge bestellen… 🙂

Sven Ruppert
Gast

Als nächstes kommen das Barometer und der DualButton.

Grüße
Sven

Theo Spalinger
Gast

Kann jemand erklären wie man die JavaFX Beispiele auf dem RED Brick zum laufen kriegt?