Datenlogger mit Fernübertragung

Aus fablab Cottbus
Zur Navigation springen Zur Suche springen
ACHTUNG: Dieses Wiki dokumentiert die Anfangszeit des Fablab Cottbus e.V. und ist nicht aktuell. Für aktuelle Informationen, schau dich auf https://fablab-cottbus.de um oder schreibe uns eine Mail an info@fablab-cottbus.de!

Am Lehrstuhl an dem ich arbeite fahren die Kollegen regelmäßig raus, um Datenlogger auszulesen. Das ist natürlich aufwändig. Ausserdem, wenn man nur einmal im Monat die Daten abholt, oder einmal die Woche, kann man schonmal feststellen, dass der Logger oder das Messgerät irgendwann ausgefallen ist. Im schlimmsten Falle direkt nachdem man das letzte mal da war. Wenn dadurch Messreihen unterbrochen werden ist das immer ärgerlich.

Ich frage mich, warum in Zeiten, wo an den meisten Stellen UMTS verfügbar ist, solche fernübertragenden Datenlogger noch nicht installiert sind. Selbst nicht am Hühnerwasser, wo haufenweise Messgeräte stehen. Bestimmt liegt das daran, dass kommerzielle Datenlogger sehr teuer sind. Und dass die meisten nicht wissen, das es heute billige Minicomputer wie die den Raspberry Pi gibt, die prima für so eine Aufgabe geeignet sind. Und dann muss man sich natürlich ein bisschen reinfuchsen, wie man aus einem Raspberry Pi einen Datenlogger mit Fernübertragung macht.


An den Messstellen, die ich kenne, gibt es folgende Vorraussetzungen:

  • Messsignal über serielle Schnittstelle
  • Stromversorgung entweder 220V oder 12V aus Batterie, die mit einem Solarpanel aufgeladen wird


TODO

  • Raspberry Pi mit serieller Schnittstelle ausstatten (entweder über USB-Adapter oder über die GPIO-Pins) [erledigt]
    • habe ich jetzt mit einem USB-Adapter gemacht
  • Skript zum Ansprechen und auslesen des Messgerätes schreiben, dass automatisch gestartet wird, wenn der Raspberry bootet [50% erledigt, mit Fehlern]
    • Das automatische Starten der Seriellen Verbindung zum Messgerät nach Anschluss des USB-Serial-Adapters funktioniert noch nicht reibungslos. Das Auslesen brach immer wieder ab. Warum genau ist aber noch unklar. Eventuell haben andere USB-Geräte wie der UMTS-Stick die Kommunikation gestört, vor allem weil dieser sich immer wieder an- und abzumelden scheint. Ich bräuchte vor allem mal ein Gerät, mit dem ich das in meinem Büro testen kann. Brauche nämlich die Nähe zum Internet, um nach möglichen Lösungsansätzen zu suchen ;-)
  • UMTS-Stick installieren [erledigt]
    • funktioniert mit sakis3G und läuft besser als die Vodafone-Software auf meinem Mac.
    • um UMTS-Kosten zu sparen sollte man sich überlegen, bei welcher Datenmenge sich der Verbindungsaufbau zur Dropbox lohnt. Es werden nämlich eine ganze Menge Daten verschickt, bevor die Verbindung überhaupt erstmal besteht. Eventuell wäre z.B. FTP auch weniger Datenintensiv.
  • Skript schreiben, dass die IP des Raspberry einem korrespondierenden Server bekannt macht (damit man im Notfall den Raspberry ansprechen per SSH kann, wenn der sich nicht mehr meldet oder Einstellungen vorgenommen werden müssen) [im Grunde erledigt, aber nicht ganz zufriedenstelltend]
    • Eine wirkliche IP-Adresse gibt es nicht im UMTS-Netz. Lösung war jetzt ein reverse ssh tunnel. Dazu braucht man allerdings wieder einen Server oder Computer, der über seine IP frei im Internet erreichbar ist. Also geht eine Verbindung direkt ins Uni-Netz leider nicht.
    • Eine gut funktionierende Lösung war, die Daten in eine Dropbox hoch zu laden. Das habe ich auch so eingerichtet, dass der Pi in der Dropbox nach einem Schell-Script mit einem bestimmten Namen schaut in die man den Befehl zum aufbauen des revers tunnel schreiben kann. Oder irgend ein anderes Wartungs-Script.
  • Skript schreiben, dass alle paar Minuten oder Stunden die Daten verschickt (Cron-Job) [erledigt]
    • Daten werden gezippt und unter dem Datum gespeichert. Dann wird die Zip in die Dropbox hochgeladen und nach erfolgreichem hochladen gelöscht. Wenn die Dropbox-Verbindung nicht aufgebaut werden kann, sammeln die Zip-Dateien sich im Ordner an und können z.B. über USB abgeholt werden. Wenn die Dropbox-Verbindung das nächste mal erfolgreich ist, werden alle Zip-Dateien im Ordner hochgeladen (auch die, die das letzte mal nicht geladen werden konnten).
    • Eventuell lieber Owncloud oder FTP auf dem fablab-Server benutzen. Dann müssen die Daten nicht nach Amerika geschickt werden ;-)
  • Routine für das Auslesen per USB schreiben (automatischer Datensync, wenn USB-Stick angeschlossen wird) [erledigt]
    • udev-Regel reagiert, wenn der USB-Stick angeschlossen wird und startet ein Skript zum Kopieren. Die udev-Regel kann auch nur auf einen bestimmten USB-Stick eingestellt werden (über dessen Seriennummer).
    • Auch auf den Stick kann ein Shell-Script gelegt werden, dass beim Anschluss des USB-Sticks ausgeführt wird.
    • Beim Anschluss des USB-Sticks werden bisher nicht die Daten vom Datenlogger gelöscht, da man nicht weiß, ob der USB-Stick nicht unterwegs verloren gehen könnte. Das Löschen der Dateien könnte man dann in das Shell-Script schreiben, sodass die erfolgreich Übertragenen Daten beim nächsten Abholen gelöscht werden.
  • 12V-Stromversorgung (Eventuell über Autonetzteil) [0% erledigt]

Der Datenlogger sollte eine hohe Redundanz haben, damit ja keine Daten verloren gehen.

  • Mehre Auslesewege (UMTS, USB-Stick, Auslesung mit Laptop über LAN)
  • keine Daten löschen, bevor nicht bestätigt wurde, dass sie ausgelesen wurden und sicher irgendwo angekommen sind

Dann sollte der Datenlogger automatisch Warnungen verschicken, wenn die Batteriespannung zu gering, der Datenspeicher voll ist oder das Messgerät nicht mehr arbeitet.

Man muss sich natürlich auch noch Gedanken machen, wie man den Raspberry wetterfest macht. Manchmal könnte man ihn in bestehende Kästen integrieren, manchmal bräuchte man aber auch ein Gehäuse wie z.B. dieses hier.


Was bringt das dem fablab?

  • Ein tolles Bastelprojekt
  • Ein Vorzeigeprojekt
  • Eine erste Bastelanleitung, die wir in unserem Wiki veröffentlichen können
  • Ein Ergebnis, dass einige Lehrstühle hier an der Uni gut gebrauchen können
  • Deswegen auch wahrscheinlich Unterstützung bzw. Spenden von entsprechenden Lehrstühlen
  • Ein Ergebnis, dass vielleicht auch woanders Interessenten findet
  • Folgeprojekte?

Diskussion

Ich habe schon einige Punkte erledigt (siehe Liste oben). Momentan verfolge ich das Projekt noch aus eigener Bastelleidenschaft. Bin aber sicher, dass wir Unterstützung von meinem Chef bekommen würden, wenn wir zeigen können, dass es funktioniert und auch failsafe ist.

Ron hatte jemand angesprochen, dass an der Uni jede Menge Messgeräte herumstehen, die niemand nutzt. Vielleicht könnte man das damit verbinden und einige davon wieder in Betrieb nehmen.

Hat jemand einen UMTS-Stick, mit dem ich ein paar Tests machen könnte? Nanu (talk) 13:21, 25 January 2014 (CET)

Dominic hat freundlicherweise seinen UMTS-Stick dem Projekt zur Verfügung gestellt Nanu (Diskussion) 18:29, 9. Jul. 2014 (CEST)

Verwendete Skripte

Installation

 # make dropbox available systemwide:
 sudo ln -s /home/pi/Scripts/Dropbox-Uploader/dropbox_uploader.sh /usr/bin/dropbox
 # same for sakis3g
 sudo ln -s /home/pi/Scripts/sakis3g /usr/bin/sakis3g

Die UDEV-Regeln müssen als Datei in /etc/udev/rules.d angelegt werden. Man kann alle Regeln in eine Datei legen. Eventuell macht man auch einen Symlink in den Ordner wo man alle Skripte zentral zu liegen hat.

online upload

UDEV-Regel beim Anschluss des USB-Modems:

Einfach nur, um dem Gerät einen immer gleichen Namen zu geben:

 ATTRS{idProduct}=="1003", ATTRS{idVendor}=="12d1", ATTRS{bInterfaceNumber}=="00", ACTION=="add", SYMLINK+="umts0"

Um die Verbindung aufzubauen, sobald das Modem vollständig erkannt ist:

 #ATTRS{idVendor}=="Huawei Technologies Co., Ltd.", ATTRS{idProduct}=="E220 HSDPA Modem / E230/E270/E870 HSDPA/HSUPA Modem"
 #ATTRS{bInterfaceNumber}=="01",
 #KERNEL=="ttyUSB?", SUBSYSTEMS=="usb", ATTRS{idProduct}=="1003", ATTRS{bInterfaceNumber}=="01", ACTION=="add", RUN+="/home/pi/test.sh"
 
 KERNEL=="ttyUSB*", SUBSYSTEM=="tty", ATTRS{bInterfaceNumber}=="01", ACTION=="add", RUN+="/home/pi/Scripts/3Gconnect.sh"
 
 #, ATTRS{idProduct}=="1003", ATTRS{idVendor}=="12d1",

3Gconnect.sh

Aufbau der 3G-Verbindung

 #!/bin/bash
 
 logfile=/home/pi/logs/3Gconnect_$$.log
 exec > $logfile 2>&1
 #sleep 10s
 sudo sakis3g SIM_PIN=<vierstelligePIN> APN=internet.eplus.de connect

cron-job zum starten des Dropbox Sync

crontab -e zum editieren der cron-jobs. Folgende Zeilen einfügen:

 0 7-20   * * *   /home/pi/Scripts/cron-dropbox-sync.sh
 @reboot  /home/pi/Scripts/cron-dropbox-sync.sh

cron-dropbox-sync.sh

Syncronisiert mit der Dropbox

#!/bin/bash

logfile=/home/pi/logs/crontab-dropbox-sync_$$.log
exec > $logfile 2>&1 

cd /home/pi/Documents/Loggerdaten/ && 

timestamp=$(date +%Y_%m_%d-%H_%M_%S) &&

timestamp >> $logfile

file=Loggerdaten_$timestamp.txt

cp Loggerdaten.txt $file &&

echo Fortsetzung der Messung $(date +"%F %T %Z") > Loggerdaten.txt &&

gzip --best $file &&

sudo sakis3g SIM_PIN=1328 APN=internet.eplus.de connect

/home/pi/Dropbox-Uploader/dropbox_uploader.sh upload Loggerdaten_*.gz Loggerdaten/ &&

rm Loggerdaten_*

/home/pi/Scripts/cron-dropbox-execute.sh

sudo sakis3g disconnect

cron-dropbox-execute.sh

Führt das Shell-Script aus, dass von der dropbox geladen wurde

 #!/bin/bash
 cd /home/pi/executeScript &&
 
 /home/pi/Dropbox-Uploader/dropbox_uploader.sh download executeScript/execute.sh ../ &&
 
 chmod +x execute.sh &&
 
 ./execute.sh &&
 
 /home/pi/Dropbox-Uploader/dropbox_uploader.sh delete executeScript/execute.sh
 
 /home/pi/Dropbox-Uploader/dropbox_uploader.sh upload * executionLog/ &&
 
 rm *

execute.sh

Wenn man execute.sh in den Ornder "executeScript" in der Dorpbox legt, wird das Shell-Skript beim Dropbox-Sync ausgeführt und daraufhin in den Ordner "executionLog" gelegt, zusammen mit dem Log-File der execution.

Die folgende Datei ruft Beispielhaft einen reverse ssh tunnel auf, um den Raspberry live steuern zu können. Der reverse tunnel öffnet den Port 2222 auf dem Server und leitet eine eingehende ssh-Verbindung an den Pi weiter. Die Verbindung mit dem Raspberry stellt man also her mit ssh <benutzer>@<serverIP>:2222. Arbeitet man auf dem Server can "localhost" anstatt der IP verwendet werden.

 #!/bin/bash
 
 exec 1>> log.txt 2>&1
 echo $(date)
 
 #-f would be for background
 ssh -v -N -R 2222:localhost:22 <benutzer>@<ServerIP> &
 sshPID=$!
 # hold the connection open for some time, then close
 sleep 900
 kill $sshPID

USB download

UDEV-Regel:

Eventuell kann hier die Seriennummer auch weggelassen werden, wenn man mit jedem beliebigen USB-Stick zugreifen möchte

ATTRS{idVendor}=="0951", ATTRS{idProduct}=="1643", ATTRS{serial}=="<Seriennummer>", ACTION=="add", MODE="0755", GROUP="plugdev", OWNER="pi", SUBSYSTEMS=="usb", SYMLINK+="commandstick", RUN+="/home/pi/Scripts/mountCommandStick.sh"
ENV{DEVLINKS}=="/dev/commandstick", ACTION=="remove", RUN+="/home/pi/Scripts/unmount.sh"

mountCommandStick.sh

Mountet den Commandstick

#!/bin/bash
mkdir /media/commandstick
mount -o uid=pi,gid=plugdev /dev/commandstick /media/commandstick

/media/commandstick/command.sh

command.sh

Kommandodatei auf dem Stick:

#!/bin/bash

logfile=/media/commandstick/rsync.log
exec >> $logfile 2>&1

cd /home/pi/Documents/Loggerdaten/ &&

timestamp=$(date +%Y_%m_%d-%H_%M_%S) && 

echo -e "\nProtokoll Auslesung" $timestamp "\n"
df #to write free diskspace to log file
echo " "

file=Loggerdaten_$timestamp.txt

cp Loggerdaten.txt $file &&

echo Fortsetzung der Messung $(date +"%F %T %Z") > Loggerdaten.txt && 

rsync -r /home/pi/Documents/Loggerdaten/ /media/commandstick/Loggerdaten/ -v

unmount.sh

Unmountet den Commandstick

#!/bin/bash
logfile=/home/pi/logs/unmount_$$.log
exec >> $logfile 2>&1
umount /media/commandstick
rm -r /media/commandstick

Serielle Kommunikation

Viele Messgeräte besitzen eine serielle Schnittstelle (z.B. HeliosMini Wetterstation/Datenlogger). In diesem Aufbau wird ein USB zu Seriell Adapter verwendet, um die Kommunikation herzustellen. Wenn dieser angeschlossen wird, wird eine UDEV-Regel aktiviert:

UDEV-Regel:

# this contains the rules to execute serial comminication with the Parsivel
ATTRS{idVendor}=="067b", SUBSYSTEMS=="usb", ATTRS{manufacturer}=="Prolific Technology Inc.", ATTRS{product}=="USB-Serial Controller", ACTION=="add", SYMLINK+="USB-Serial-Port", RUN+="/home/pi/Scripts/usb-serial.sh"
 
ENV{DEVLINKS}=="/dev/USB-Serial-Port", ACTION=="remove", RUN+="/home/pi/Scripts/usb-serial-remove.sh"

#ATTRS{serial}=="Prolific_Technology_Inc._USB-Serial_Controller"

usb-serial.sh

Macht eine Pipe vom Seriellen Anschluss in die Datei "Loggerdaten.txt". Läuft noch nicht sauber.

#!/bin/bash

logfile=/home/pi/logs/usb-serial-log.log
#exec >> $logfile 2>&1

#sudo -u pi touch /home/pi/Documents/Loggerdaten/Loggerdaten.txt 

#for the HeliosMini:
stty -F /dev/USB-Serial-Port speed 9600 &&

#for Parsivel:
#stty -F /dev/USB-Serial-Port speed 19200 inlcr

cat /dev/USB-Serial-Port >> /home/pi/Documents/Loggerdaten/Loggerdaten.txt
#ttylog -d /dev/USB-Serial-Port >> /home/pi/Documents/Loggerdaten/Loggerdaten.txt 
#cat /dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller-if00-port0 >> /$

usb-serial-remove.sh

Wird aufgerufen beim abziehen des Seriellen Adapters. Garantiert, dass beim nächsten Anstecken die Verbindung wieder hergestellt werden kann

#!/bin/bash
sudo pkill usb-serial.sh

Real Time Clock

Damit der Raspberry auch ohne Internet-Verbindung die richtige Zeit behält, ist eine Real Time Cloc (RTC) notwendig, die man auf einem kleinen Chip kaufen kann, der auf die GPIO-Pins des Raspberrys aufgesteckt wird. Ich hab diese gekauft. Hier habe ich eine Anleitung gefunden, um den Raspberry auf die RTC einzustellen. Konkret habe ich verwendet:

# Remove the module blacklist entry so it can be loaded on boot
sudo sed -i 's/blacklist i2c-bcm2708/#blacklist i2c-bcm2708/' /etc/modprobe.d/raspi-blacklist.conf
# Load the module now
sudo modprobe i2c-bcm2708
# Notify Linux of the Dallas RTC device
echo ds1307 0x68 | sudo tee /sys/class/i2c-adapter/i2c-1/new_device
# Test whether Linux can see our RTC module.
sudo hwclock

Eine neue Real-Time-Clock muss man wahrscheinlich erstmal auf die richtige Uhrzeit einstellen. Dazu am besten den Raspberry einmal mit Internetverbindung booten, damit er sich die Zeit aus dem Internet holt. Dann mit folgendem Befehl die RTC einstellen:

sudo hwclock -w

Nun muss noch eingestellt werden, dass beim nächsten Booten die Systemzeit von der RTC geholt wird:

# Add the RTC device on boot
sudo sed -i 's#^exit 0$#echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device#' /etc/rc.local
echo "sudo hwclock -s" | sudo tee -a /etc/rc.local
echo exit 0 | sudo tee -a /etc/rc.local