RaspberryPi – Temperatur messen und in einer Android Application anzeigen – Teil 1

Nach dem vorläufigem Abschluss unserer LIRC App würde ich gerne mit einem neuem Projekt anfangen. Diesmal geht es um das Speichern von Temperaturdaten mithilfe unseres RaspberryPi’s in eine Datenbank. Diese Daten wandern dann in unsere neue Temperatur APP und werden in einem Diagramm dargestellt. Dieser zeigt dann die Daten zum gewünschtem Datum an. Durch Wisch-Bewegungen lässt es sich durch die verschiedenen Tage scrollen und beim Doppelklick auf das Diagramm mehr Informationen zu dem ausgewählten Tag anzeigen. Was muss also alles gemacht werden?

Ich werde erstmal kurz erläutern wie ich vorgegangen bin. Diese Reihenfolge würde ich dann gerne mit jeweils passendem Beitrag fortsetzen. Zuerst müssen wir einen Temperatursensor an unserem Raspberry anschließen und pro gewünschter Zeit die ausgelesenen Daten in eine Datenbank speichern. Die Datenübertragung vom Raspi zum Handy erfolgt wie bereits in unserer LIRC App über eine TCP Verbindung. Unser JAVA Server wird die Daten in Form von JSON an die APP schicken. Die APP wertet die Daten aus und zeigt diese in einem Diagramm an.

Manche Informationen beziehen sich auf die älteren Beiträge zu der Infrarot APP

Teil 1: Temperatursensor am RaspberryPi

Im Internet gibt es bereits viele Beschreibungen darüber wie man mithilfe des 1-Wire-Protokolls über einen Temperatursensor die aktuelle Temperatur auslesen kann. Deshalb verweise ich direkt auf paar Quellen die mir bei der Einrichtung des Ganzen geholfen haben:

http://www.kompf.de/weather/pionewiremini.html
http://www.einplatinencomputer.com/raspberry-pi-1-wire-temperatursensor-ds1820-ansteuern/
http://kopfkino.irosaurus.com/tutorial-ds18s20-temperatur-sensor-an-einem-raspberry-pi/

Ich denke bei solchem Angebot an Informationen ist es nicht nötig im Grunde das gleiche nochmal zu schreiben. Ich persönlich habe mich im Endeffekt für den DS 18S20 Sensor entschieden und habe den zusammen mit dem 4,7kOhm Widerstand bei Reichelt bestellt:

http://www.reichelt.de/index.html?ACTION=3;ARTICLE=7207;SEARCH=DS%2018S20
http://www.reichelt.de/1-4W-5-1-0-k-Ohm-9-1-k-Ohm/1-4W-4-7K/3/index.html?&ACTION=3&LA=2&ARTICLE=1425&GROUPID=3065&artnr=1%2F4W+4%2C7K

Ansonsten habe ich einfach die Artikeln von oben umgesetzt und bin ohne Probleme zu unserem gewünschtem Ausgangspunkt gelangt. Dieser ist nämlich da wo wir die Temperatur im Terminal auslesen können:

>nano /sys/bus/w1/devices/10-000802e76cae/w1_slave
27 00 4b 46 ff ff 03 10 71 : crc=71 YES
27 00 4b 46 ff ff 03 10 71 t=19562

Die Konsolen-Ausgabe von oben bezieht sich nur auf einen angeschlossenen Sensor. Das Programm zum schreiben in die DB wird aber auch mehrere angeschlossene Sensoren unterstützen.

Teil 2: Daten zeitgesteuert in die H2 DB speichern (JAVA und Cronjob)

Manchen ist die H2 Datenbank bereits bekannt. Diese haben wir benutzt um Zustände eines Buttons zentral speichern zu können. Diesmal wird uns die Datenbank dabei helfen die Temperaturdaten zu speichern. Wie schon früher erstellen wir erstmal einmalig ein Script der für die Erstellung der Datenbank zuständig ist. Wir erstellen also zuerst ein neues Java 1.7 Projekt und nennen es zum Beispiel „CreateTempDB“. Die „main“ Methode sieht so aus:

public static void main(String[] args) throws ClassNotFoundException, SQLException {

     Class.forName("org.h2.Driver");
     Connection conn = DriverManager.getConnection("jdbc:h2:~/RaspiH2");
 
     String stmt = "CREATE TABLE TEMPDATA "
            + "(DATE DATE NOT NULL,"
            + "TIME TIME NOT NULL,"
            + "TEMP REAL NOT NULL,"
            + "PRIMARY KEY (DATE,TIME))";
     PreparedStatement ps = conn.prepareStatement(stmt);
     ps.executeUpdate();
     conn.close();
}

So gehen wir einmal alles durch. Zuerst wird natürlich die passende H2 Bibliothek benötigt. Diese könnt ihr euch hier herunterladen: Treiber (eventuell auf neue Ver. achten). Wie die Bibliothek in das Projekt eingebunden wird könnt ihr hier nachlesen: H2 Database over JAVA. Am Anfang binden wir also die Klasse „org.h2.Driver“ über die forName Methode der Klasse ein und stellen mithilfe des DriverManager die Verbindung zu der Datenbank her. In diesem Fall wird die Datenbank entweder direkt im Verzeichnis des angemeldeten Raspberry oder Windows (%HOMEPATH%) Benutzers erstellt. Danach folgt die SQL Anweisung die wir im String „stmt“ speichern. Hier erstellen wir eine neue Tabelle und nennen sie zum Beispiel „TEMPDATA“. Diese soll vier Datensätze speichern können:
DATE vom Typ DATE : Hier speichern wir das Datum
TIME vom Typ TIME: Hier speichern wir die Uhrzeit
TEMP vom Typ REAL : Hier speichern wir die Durchschnittstemperatur der Sensoren (REAL entspricht dem Datentyp Float in Java)
Die Datensätze dürfen nicht NULL sein und DATE und TIME stellen den primär Schlüssel dar. Speichern wir nun die Daten, zB alle zwei Stunden ab, sieht die Datenbank so aus:

-|DATE <pk> |TIME <pk> |TEMP  |
0|2015-05-05|21:00     |16.543|
1|2015-05-05|23:00     |14.345|
usw.

Dem String geben wir an ein PreparedStatement weiter und führen das Update entsprechend aus. Danach wird die Datenbank Verbindung geschlossen. Damit hätten wir schon mal unsere Datenbank. Jetzt müssen wir ein Script schreiben welches nach einem bestimmten Zeitpunkt die w1_slave Datei der Sensoren ausliest und die Daten in die Datenbank speichert. Mein Projekt habe ich „TempWriter“ genannt. Gehen wir das Projekt nun Schritt für Schritt durch:

public static void main(String[] args) throws ClassNotFoundException{
     Class.forName("org.h2.Driver");
     
     BufferedReader br = null;
     File[] devices = new File("/sys/bus/w1/devices").listFiles();
     ArrayList <Float> temps = new ArrayList<Float>();
     float temp = 0;
}

Wie bereits oben im ersten Projekt geschehen brauchen wir hier auch die H2 Bibliothek. Die Klasse „org.h2.Driver“ wird genauso eingebunden. Danach erstellen wir ein Objekt vom Typ BufferedReader das später das Auslesen der Datei übernimmt. Zusätzlich erstellen wir ein Array mit Objekten vom Typ File und geben uns alle befindlichen Dateien und Verz. von „/sys/bus/w1/devices“ aus. Zuletzt brauchen wir noch eine Liste die uns die Temperatur von dem jeweiligen Sensor speichert und ein float Wert der am Ende die endgültige Temperatur speichert (Durchschnitt aus allen ausgelesenen Temperaturen).

public static void main(String[] args) throws ClassNotFoundException{
     Class.forName("org.h2.Driver");
     
     BufferedReader br;
     File[] devices = new File("/sys/bus/w1/devices").listFiles();
     ArrayList <Float> temps = new ArrayList<Float>();
     float temp = 0;
     try {
          for (int i = 0;i < devices.length;i++){
               if (devices[i].getName().startsWith("10-")){
                    br = new BufferedReader(new FileReader(devices[i] + "/w1_slave"));
                    String crc = br.readLine();
                    if (crc.endsWith("YES")){
                         temps.add(Float.valueOf(br.readLine().replaceAll
                                 ("^.*t=", ""))/1000);
                    br.close();
                    }
               }
          }
     } catch (IOException e) {
          e.printStackTrace();
     }
}

Die For – Schleife läuft alle gefundenen Verz. und Dateien durch. Fängt der Name mit „10-“ (10 ist der Familycode des Sensors vom Typ Typ DS1820 und DS18S20) an wird die „w1_slave“ Datei aus diesem Verzeichnis in den BufferedReader geladen. Jetzt wird in dem String „crc“ die erste Zeile der Datei gespeichert. Endet diese mit dem Wert „YES“ war die Temperaturmessung erfolgreich und wir fügen die Temperatur der Liste „temps“ hinzu. Dazu wird ein Float Wert aus der zweiten Zeile des Dokuments ermittelt nachdem alles nach *t= durch nichts ersetzt wurde. Somit bleibt nur der gemessene Wert übrig der dann nochmal durch 1000 geteilt wird.

public static void main(String[] args) throws ClassNotFoundException{
     Class.forName("org.h2.Driver");
     
     BufferedReader br;
     File[] devices = new File("/sys/bus/w1/devices").listFiles();
     ArrayList <Float> temps = new ArrayList<Float>();
     float temp = 0;
     try {
          for (int i = 0;i < devices.length;i++){
               if (devices[i].getName().startsWith("10-")){
                    br = new BufferedReader(new FileReader(devices[i] + "/w1_slave"));
                    String crc = br.readLine();
                    if (crc.endsWith("YES")){
                         temps.add(Float.valueOf(br.readLine().replaceAll
                                 ("^.*t=", ""))/1000);
                    br.close();
                    }
               }
          }
          if (temps.size() > 0){
               for (int i = 0;i <temps.size();i++){
                    temp += temps.get(i);
               }
               temp = temp / temps.size();
 
               SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
               SimpleDateFormat st = new SimpleDateFormat("HH:00:00");
 
               Date d = new Date();
               String date = sd.format(d);
               String time = st.format(d);
 
               Connection conn = DriverManager.getConnection
                        ("jdbc:h2:~/RaspiH2"); 
               String stmt = "INSERT INTO TEMPDATA (DATE,TIME,TEMP) VALUES (?,?,?)";
               PreparedStatement ps = conn.prepareStatement(stmt);

               ps.setString(1,date); 
               ps.setString(2,time); 
               ps.setFloat(3,temp); 
               ps.executeUpdate(); 
               conn.close(); 
           } 
     } catch (IOException | SQLException e) { 
           e.printStackTrace(); 
     } 
}

Wenn die For-Schleife durchgelaufen ist, d.h es gibt keine weiteren Dateien oder Verz. im Verz. „/sys/bus/w1/devices“, wird die Größe der Liste „temps“ überprüft. Ist diese >0 (es wurden also Temperaturwerte gespeichert) wird eine zweite For-Schleife gestartet die alle Werte summiert und in die Variable „temp“ speichert. Nach der Schleife wird der Wert der Variable „temp“ durch die Anzahl der Elemente aus der Liste „temps“ in die Variable „temp“ gespeichert. Somit erhalten wir unsere Durchschnittstemperatur. Nun werden die Daten für die Datenbank vorbereitet. Zuerst brauchen wir zwei Objekte vom Typ SimpleDateFormat. Die Datenbank erwartet das Datum im Format „YYYY-MM-DD“ und die Uhrzeit im Format „HH:MM:SS“. Danach holen wir uns das aktuelle Datum über das Objekt Date und formatieren es einmal in das passende Format für das Datum und die Uhrzeit. Diese Werte werden in die String Variablen „date“ und „time“ gespeichert. Nun das bekannte Spielchen. Wir verbinden uns mit der Datenbank  und erstellen unseren SQL Ausdruck in der String Variable „stmt“. Danach setzten wir die Parameter über ein PreparedStatement fest. Zuerst das Datum (YYYY-MM-DD) dann die Uhrzeit (HH:MM:SS) und zuletzt die Temperatur.Am Ende führen wir das Update durch und beenden die Verbindung zu der Datenbank.

Nun müssen wir uns einmal entscheiden wann die Werte ausgelesen werden sollen. Ich habe mich für alle 2 Stunden entschieden. Deshalb wird in dem Script oben nur die aktuelle Stunde ausgelesen (HH). Die Werte für die Minuten (MM) und Sekunden (SS) lasse ich automatisch auf null stehen. Damit die Werte alle 2 Stunden gespeichert werden können brauchen wir einen sogenannten Cronjob der diese Arbeit für uns übernimmt. Cronjobs werden in Tabellen gespeichert. Da unser Auftrag auch dann ausgeführt werden soll wenn wir nicht am Raspberry angemeldet sind müssen wir den Job in der Tabelle des Benutzers „root“ anlegen:

>sudo cronjob -e

Es erscheint die Erklärung der Syntax und wie man ein Cronjob genau definieren muss. Wir scrollen ganz nach unten und schreiben folgendes rein:

>0 */2 * * * /usr/bin/java -jar /home/pi/python_bobek/TempWriter.jar

Gehen wir die Zeile einmal durch. Am Anfang wird die Zeit definiert wann das Script ausgeführt werden soll.

0           */2       *       *        *
Minuten     Stunde    Tag     Monat    Wochentag

Wir haben also ein Cronjob erstellt das genau zu jeder zweiten Stunde ausgeführt wird. Das erste mal wird dieser Cronjob um 0 Uhr ausgeführt und ab da alle zwei Stunden. Solltet ihr es anders haben wollen könnt ihr es hier definieren. Im oberen Link (s.Cronjob) wird alles nochmal genau erklärt.

/usr/bin/java -jar /home/pi/java_bobek/TempWriter.jar

Hier wird die Aufgabe definiert die ausgeführt werden soll. Es wird also „java“ aus dem Verz. „usr/bin“ gestartet zusammen mit dem Parameter „-jar“ und dem Pfad zu der jar Datei. Den Pfad zu dem Programm müsst ihr selbstverständlich anpassen. Danach speichern wir das ganze mit STRG + S ab und hoffen das alles fuktioniert hat. Mit:

>sudo cronjob -l

können wir uns nochmal die Cronjobs des Benutzers „root“ anzeigen lassen. Wenn alles funktioniert hat müsste die Datenbank alle zwei Stunden um einen neuen Temperaturwert erweitert werden. Bei einer Query auf die DB könnte die Ausgabe so aussehen:

>Datum:2015-05-01-UhrZeit:00:00:00-Temp:10.75
>Datum:2015-05-01-UhrZeit:02:00:00-Temp:9.375
>Datum:2015-05-01-UhrZeit:04:00:00-Temp:8.062
>Datum:2015-05-01-UhrZeit:06:00:00-Temp:11.562
>Datum:2015-05-01-UhrZeit:08:00:00-Temp:15.937
>Datum:2015-05-01-UhrZeit:10:00:00-Temp:16.125
>Datum:2015-05-01-UhrZeit:12:00:00-Temp:14.937
>Datum:2015-05-01-UhrZeit:14:00:00-Temp:13.5
>Datum:2015-05-01-UhrZeit:16:00:00-Temp:12.564
>Datum:2015-05-01-UhrZeit:18:00:00-Temp:14.21
>Datum:2015-05-01-UhrZeit:20:00:00-Temp:13.879
>Datum:2015-05-01-UhrZeit:22:00:00-Temp:12.11

Ihr braucht euch keine Sorgen um Speicherverbrauch der DB machen. Ich nehme die Daten seit ca. 20 Tagen auf und meine DB ist 64kb groß und TEMPDATA ist nicht die einzige Tabelle. So wir sind am Ende angelangt zumindest vorerst.Im nächsten Beitrag kümmern wir uns um die TCP Verbindung.

TEIL 1TEIL 2TEIL 3

18 Gedanken zu „RaspberryPi – Temperatur messen und in einer Android Application anzeigen – Teil 1

  1. Sven Reitmeier

    bekomme eigenlich immer die fehlermeldung bei TempWrite in eclips

    Exception in thread „main“ java.lang.NullPointerException
    at TempWrite.main(TempWrite.java:25)

    Antworten
    1. BoBek Beitragsautor

      Es ist eine NullPointerException d.h irgendein Objekt ist null und kann deshalb nicht weiter verarbeitet werden. Kannst du mir die ganze Exception posten? Dein Temperatursensor liegt aber die Daten im oben angegebenen Verz. ab oder?

      Antworten
        1. BoBek Beitragsautor

          Ja dann ist ja klar das die Exception kommt wenn du alles am PC testen willst dann brauchst du auch die Datei auf dem PC. Die Exception wird geworfen wenn eine Methode fehlgeschlagen ist. Es ist die Meldung oder die Fehler die dir Eclipse ausgibt.

          Antworten
          1. Sven Reitmeier

            aber auf den pi bekomme ich in der datenbank nicht wie bei dir angezeigt!
            bei dir
            -|DATE |TIME |TEMP |
            0|2015-05-05|21:00 |16.543|
            1|2015-05-05|23:00 |14.345|
            usw.
            —————————–
            bei mir
            H:2,block:2,blockSize:1000,chunk:e,created:15217e3ec81,format:1,version:e,fletcher:ff4371a6
            H:2,block:2,blockSize:1000,chunk:e,created:15217e3ec81,format:1,version:e,fletcher:ff4371a6
            chunk:e,block:2,len:1,map:9,max:630,next:4,pages:3,root:38000009594,time:3ea365,version:e

            12345! &XSET CREATE_BUILD 186″ “
            CREATE USER IF NOT EXISTS „“ SALT “ HASH “ ADMIN#
            CREATE CACHED TABLE PUBLIC.TEMPDATA(
            DATE DATE NOT NULL,
            TIME TIME NOT NULL,
            TEMP REAL NOT NULL
            )$ !
            CREATE PRIMARY KEY PUBLIC.PRIMARY_KEY_D ON PUBLIC.TEMPDATA(DATE, TIME)% %
            ALTER TABLE PUBLIC.TEMPDATA ADD CONSTRAINT PUBLIC.CONSTRAINT_D PRIMARY KEY(DATE, TIME) INDEX PUBLIC.PRIMARY_KEY_D# !1″2#3$4%5h0chunk.bchunk.cchunk.dmap.1map.2map.3map.4map.5map.6map.7map.8map.9name.index.0name.index.4name.lobDataname.lobMapname.lobRefname.openTransactionsname.table.0name.table.3name.undoLogr
            usw
            muß jetzt schluß machen muß zum schach. melde mich morgen noch mal. thx für deine hilfe!

            LG Sven

          2. BoBek Beitragsautor

            Also das was du da gepostet hast ist nochmal von wo??? Ich blicke da echt nicht mehr durch 😀

          3. Sven Reitmeier

            das ist die datei RaspiH2.mv.db auf dem pi.
            wen ich /usr/bin/java -jar /home/pi/java_bobek/TempWriter.jar
            starte kommt nix es wir aber in diese datei geschrieben ! beim zweiten mal in der stunde kommt dan eine fehler meldung. weil es die selbe zeit und datum hat!? dan steht da das

            org.h2.jdbc.JdbcSQLException: Unique index or primary key violation: „PRIMARY_KEY_D ON PUBLIC.TEMPDATA(DATE, TIME) VALUES (DATE ‚2016-01-07′, TIME ’02:00:00‘, 1)“; SQL statement:
            INSERT INTO TEMPDATA (DATE,TIME,TEMP) VALUES (?,?,?) [23505-186]
            at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
            at org.h2.message.DbException.get(DbException.java:179)
            at org.h2.message.DbException.get(DbException.java:155)
            at org.h2.index.BaseIndex.getDuplicateKeyException(BaseIndex.java:102)
            at org.h2.mvstore.db.MVSecondaryIndex.add(MVSecondaryIndex.java:203)
            at org.h2.mvstore.db.MVTable.addRow(MVTable.java:637)
            at org.h2.command.dml.Insert.insertRows(Insert.java:156)
            at org.h2.command.dml.Insert.update(Insert.java:114)
            at org.h2.command.CommandContainer.update(CommandContainer.java:78)
            at org.h2.command.Command.executeUpdate(Command.java:254)
            at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:157)
            at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:143)
            at TempWrite.main(TempWrite.java:54)

          4. BoBek Beitragsautor

            Ok … Machen wir es so, füge hier bitte die ganze Klasse (also den ganzen Code vom Projekt TempWriter) ein. Ich werde mir das in Ruhe anschauen und hoffentlich die Fehler finden.

          5. Sven Reitmeier

            im endefeckt st das ja was bei dir oben steht! TempWrite.java

            import java.io.*;
            import java.sql.*;
            import java.text.SimpleDateFormat;
            import java.util.*;
            import java.util.Date;

            public class TempWrite {

            public static void main(String[] args) throws ClassNotFoundException{
            Class.forName(„org.h2.Driver“);

            BufferedReader br;
            File[] devices = new File(„/sys/bus/w1/devices“).listFiles();
            ArrayList temps = new ArrayList();
            float temp = 0;
            try {
            for (int i = 0;i 0){
            for (int i = 0;i <temps.size();i++){
            temp += temps.get(i);
            }
            temp = temp / temps.size();

            SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
            SimpleDateFormat st = new SimpleDateFormat("HH:00:00");

            Date d = new Date();
            String date = sd.format(d);
            String time = st.format(d);

            Connection conn = DriverManager.getConnection
            ("jdbc:h2:~/RaspiH2");
            String stmt = "INSERT INTO TEMPDATA (DATE,TIME,TEMP) VALUES (?,?,?)";
            PreparedStatement ps = conn.prepareStatement(stmt);

            ps.setString(1,date);
            ps.setString(2,time);
            ps.setFloat(3,temp);
            ps.executeUpdate();
            conn.close();
            }
            } catch (IOException | SQLException e) {
            e.printStackTrace();
            }
            }
            }

          6. BoBek Beitragsautor

            Nein ist es überhaupt nicht! Ich habe es dir gesagt das man ohne ein gewisses Hintergrundwissen das Projekt nicht so leicht umsetzen kann. Was mir alles aufgefallen ist:
            1.) Du liest überhaupt nicht die Temperatur aus !!!
            2.) Ohne die Temperatur hast du trotzdem zwei For-Schleifen drin, die erstens nichts durchlaufen und zweites sogar falsch sind (2.For-Schleife)

            Kopiere dir bitte genau die „main“ Methode von mir oben. GENAU! Du muss nur zwei Sachen beachten:
            1.) Liegen hier „/sys/bus/w1/devices “ deine Sensor-Temperatur-Dateien drin? Fangen die Dateinamen mit 10-… an? Steht in der Datei überhaupt die gemessene Temperatur?
            2.) Lösche die Datenbank und erstelle sie erstmal neu. Dann überprüfe bitte ob sich die Datenbank auch in deinem Homeverz. auf dem Raspberry befindet „~/RaspiH2“. Wenn nicht bitte das Verz. im Script anpassen.

          7. Sven Reitmeier

            Nach der eingabe in putty

            cat /sys/bus/w1/devices/10-000802e4d29c/w1_slave

            kommt

            32 00 4b 46 ff ff 0e 10 fa : crc=fa YES
            32 00 4b 46 ff ff 0e 10 fa t=24875

            also ist das /sys/bus/w1/devices verzeichnis da und fängt mit 10- an.

            ich habe nur diese zwei dateien

            RaspiH2.mv.db

            RaspiH2.trace.db

            die liegen aber in /root nicht im /home

            zur main” Methode wen ich mit

            public static void main(String[] args)

            anfange bekomme ich fehler ich muß vorher

            public class schreiben?

            und dan die fehler anklicken wo dan das oben geschrieben wird

            import…..

          8. BoBek Beitragsautor

            Ok damit ist erstmal klar das die Temperatur gelesen wird 😉 Wo steckst du denn das es bei dir 24 Grad sind :D?
            Wenn die Datenbank im root Verz liegt dann muss das entsprechend im Script angepasst werden.
            Hier “~/RaspiH2” muss du dann den Pfad zu der Datei angeben in deinem Fall (nochmal überprüfen!) „root/RaspiH2“.
            Was ist das für ein Fehler wenn du „static“ lässt kannst du mir sagen was Eclipse ausgibt? Eventuell hast du gar nicht erst die Klasse erstellt?
            Wie heißt deine Klasse? Hier am Bild siehst du was ich meine : Klasse

  2. Sven Reitmeier

    ich komme trozdem nicht weiter
    weiß nicht ob das stimm?
    ———————————————————————
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;

    public class CreateTempDB {

    public static void main(String[] args) throws ClassNotFoundException, SQLException {

    Class.forName(„org.h2.Driver“);
    Connection conn = DriverManager.getConnection(„jdbc:h2:~/RaspiH2“);

    String stmt = „CREATE TABLE TEMPDATA “
    + „(DATE DATE NOT NULL,“
    + „TIME TIME NOT NULL,“
    + „TEMP REAL NOT NULL,“
    + „PRIMARY KEY (DATE,TIME))“;
    PreparedStatement ps = conn.prepareStatement(stmt);
    ps.executeUpdate();
    conn.close();
    }
    }
    ———————————————
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileReader;
    import java.io.IOException;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Date;

    public class TempWrite {

    public static void main(String[] args) throws ClassNotFoundException{
    Class.forName(„org.h2.Driver“);

    BufferedReader br;
    File[] devices = new File(„/sys/bus/w1/devices“).listFiles();
    ArrayList temps = new ArrayList();
    float temp = 0;
    try {
    for (int i = 0;i 0){
    for (int i = 0;i <temps.size();i++){
    temp += temps.get(i);
    }
    temp = temp / temps.size();

    SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
    SimpleDateFormat st = new SimpleDateFormat("HH:00:00");

    Date d = new Date();
    String date = sd.format(d);
    String time = st.format(d);

    Connection conn = DriverManager.getConnection
    ("jdbc:h2:~/RaspiH2");
    String stmt = "INSERT INTO TEMPDATA (DATE,TIME,TEMP) VALUES (?,?,?)";
    PreparedStatement ps = conn.prepareStatement(stmt);

    ps.setString(1,date);
    ps.setString(2,time);
    ps.setFloat(3,temp);
    ps.executeUpdate();
    conn.close();
    }
    } catch (IOException | SQLException e) {
    e.printStackTrace();
    }
    }
    }
    ————————————————————-

    eine daten bank wird glaube ich erzeugt aber das speichern ??????

    Antworten
    1. BoBek Beitragsautor

      Ich kann nicht viel damit anfangen 🙂 Hast du überhaupt die Treiber für die H2 Datenbank in dein Projekt implementiert? Du glaubst das die Datenbank erstellt wird oder weißt du es? Der Code von oben ist doch einfach nur der Code von mir …

      Der Link für die Datenbank oben funktioniert nicht mehr, weil neue Version erschien ist.Hier der Link für die neuste Version : http://www.h2database.com/h2-2015-10-11.zip
      Außerdem findest du hier – http://blog.bobek-software.net/h2-database-on-raspberry-pi-over-java/ – wie man die Treiber einbindet einfach ab „H2 Database“ lesen.

      Antworten
      1. Sven Reitmeier

        ja ich hab die zei dateien
        RaspiH2.trace.db
        RaspiH2.mv.db

        aber ich glaube er liest nicht die temperatur

        —————–
        root@raspberrypi:~# sudo java -jar TempWriter.jar
        org.h2.jdbc.JdbcSQLException: Unique index or primary key violation: „PRIMARY_KEY_D ON PUBLIC.TEMPDATA(DATE, TIME) VALUES (DATE ‚2016-01-06′, TIME ’15:00:00‘, 2)“; SQL statement:
        INSERT INTO TEMPDATA (DATE,TIME,TEMP) VALUES (?,?,?) [23505-186]
        at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
        at org.h2.message.DbException.get(DbException.java:179)
        at org.h2.message.DbException.get(DbException.java:155)
        at org.h2.index.BaseIndex.getDuplicateKeyException(BaseIndex.java:102)
        at org.h2.mvstore.db.MVSecondaryIndex.add(MVSecondaryIndex.java:203)
        at org.h2.mvstore.db.MVTable.addRow(MVTable.java:637)
        at org.h2.command.dml.Insert.insertRows(Insert.java:156)
        at org.h2.command.dml.Insert.update(Insert.java:114)
        at org.h2.command.CommandContainer.update(CommandContainer.java:78)
        at org.h2.command.Command.executeUpdate(Command.java:254)
        at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:157)
        at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:143)
        at TempWrite.main(TempWrite.java:55)

        Antworten
        1. BoBek Beitragsautor

          Ne, das Problem ist du versucht einen bereits angelegten Datensatz zu ersetzen. Das geht aber nicht, weil DATE und TIME primäre Spalten in der Datenbank sind. Deshalb spuckt er dir die SQL Exception raus. Einfach den Datensatz löschen und nochmal testen. Im Umkehrschluss heißt es deine Daten werden gespeichert 😉

          Antworten
  3. Sven Reitmeier

    Hallo. Hast du mal einen link für Eclipse Java kenne das programm nicht und bekomme nur fehler!
    Exception in thread „main“ java.lang.NoClassDefFoundError: IOException
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
    at java.lang.Class.getMethod0(Unknown Source)
    at java.lang.Class.getMethod(Unknown Source)
    at sun.launcher.LauncherHelper.getMainMethod(Unknown Source)
    at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
    Caused by: java.lang.ClassNotFoundException: IOException
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    … 6 more

    THX

    Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.