GPS Tracker mit dem Raspberry Pi

Ziel des Ganzen

Mit einer SMS an den Raspi soll dieser seinen Standort preisgeben. Diese Beschreibung ist eine Fortführung des Projekts: Trumatic E2400 per SMS fernsteuern.

Verwendete Komponenten

GPS-Maus in Betrieb nehmen

um rauszufinden an welchem dev die GPS mouse hängt:

ls -la /dev/serial/by-id/
sudo stty 4800 -F /dev/ttyUSB2
cat /dev/ttyUSB2

Das liefert die Rohdaten von der GPS-Maus.  Ein Skript liefert direkt eine korrekt formatierte URL zu Google Maps mit der  jeweiligen Position:

#!/usr/bin/env python
import serial
import sys
import time

def getPosition():
        Zeichen = 0
        Laenge = 0
        Qualitaet = 0
        Satelliten = 0

        Hoehe = 0.0
        Breitengrad = 0.0
        Laengengrad = 0.0

        Input = ""
        Uhrzeit = ""
        Checksumme = ""

        Datenliste = []

        # UART oeffnen
        UART = serial.Serial("/dev/gps", 4800)
        #UART.open()

        # Startmeldung
        #print ""
        #print "+---------------------------------------------------------------------+"
        #print "| Dieses Programm empfaengt Daten einer Holux GPS-Maus,               |"
        #print "| die mittels GAA-Protokoll uebertragen wurden.                       |"
        #print "| Der empfangene Datensatz wird zerlegt und in der Konsole angezeigt. |"
        #print "+---------------------------------------------------------------------+"
        #print ""

        #while True:

        Zeichen = 0

        # String leeren
        Input = ""
        
        # Zeichen empfangen
        Zeichen = UART.read() 
        
        # Pruefen ob Uebertragung gestartet wurde
        if Zeichen == "$":

                # Zeichen 2-6 einlesen
                for Counter in range(4):

                        Zeichen = 0
                        Zeichen = UART.read()
                        Input = Input + str(Zeichen)
        
                # Pruefen ob das GGA Protokoll gesendet wird
                if Input == "GPGG":

                        # Zeichen empfangen bis ein LF als Abschluss kommt
                        while Zeichen != "\n":
                                Zeichen = 0
                                Zeichen = UART.read()
                                Input = Input + str(Zeichen)
                        
                        Input = Input.replace("\r\n", "")
        
                        # Datensatz nach jedem "," trennen und in einer Liste speichern
                        Datenliste = Input.split(",")

                        # Laenge des Datensatzes feststellen
                        Laenge_Daten = len(Input)

                        # Uhrzeit herausfiltern
                        Uhrzeit = Datenliste[1]
                        Uhrzeit = Uhrzeit[0:2] + ":" + Uhrzeit[2:4] + ":" + Uhrzeit[4:6]

                        # Laengen und Breitengrad herausfiltern und berechnen
                        Breitengrad = int(float(Datenliste[2]) / 100)
                        Laengengrad = int(float(Datenliste[4]) / 100)
                        
                        Breitenminute = float(Datenliste[2]) - (Breitengrad * 100)
                        Laengenminute = float(Datenliste[4]) - (Laengengrad * 100)

                        Breite = round(Breitengrad + (Breitenminute / 60), 6)
                        Laenge = round(Laengengrad + (Laengenminute / 60), 6)

                        # Signalqualitaet herausfiltern
                        Qualitaet = int(Datenliste[6])

                        # Anzahl der Satelliten herausfiltern
                        Satelliten = int(Datenliste[7])

                        # Hoehe herausfiltern
                        Hoehe = float(Datenliste[9])
                        
                        # Checksumme auslesen
                        Checksumme = Datenliste[14]

                        return "https://www.google.de/maps/@"+str(Breite)+","+str(Laenge)+",15.68z"

Mit diesem Befehlt kann man das Skript ausprobieren:

python GPS.py

UDEV

Es ist nicht vorhersagbar auf welchen /dev/ttyUSBx die GPS-Maus gemounted werden. Mit udev kann man rules erstellen, die nach bestimmten Kriterien die devices durchsucht und an festen mountpoints zur Verfügung stellt. Zunächst mit

ls -al /dev/serial/by-id

herausfinden welche Devices gerade wo gemounted sind. Dann mit

udevadm info --query=all --attribute-walk --name=/dev/ttyUSB0

Details zum jeweiligen device rausfinden, z.B. idProduct, idVendor.

Dann eine rules-Datei folgendermaßen anlegen.

sudo nano /lib/udev/rules.d/gps-mouse.rules

und z.B. das reinschreiben.

KERNELS=="1-1.1.3", SUBSYSTEMS=="usb", ATTRS{idProduct}=="2303", ATTRS{idVendor}=="067b", SYMLINK+="gps"

Danach Udev deamon neustarten mit

sudo /etc/init.d/udev restart

Jetzt sollte unter /dev/gps das device gemounted sein und es kann als solches in GPS.py referenziert werden.

Trumatic E2400 per SMS mit einem Raspberry Pi fernsteuern

Ziel des Ganzen

Es soll eine Trumatic E2400 Standheizung in einem VW T5 per Fernsteuerung an- und ausgeschaltet werden können.

Zu lösende Probleme

  • hoher Preis der von Truma angebotene Lösung (>250€)
  • geringe Reichweite gängiger Schlüsselfunknachrüstungen
  • Raspi muss 24/7 laufen (Mehr zum Thema headless und Dauerbetrieb)

Lösung

  • Raspberry Pi als Schaltzentrale
  • 2-Kanal Relais an GPIO des Raspi zur Steuerung der Heizung
  • GPRS/UMTS Stick und Steuerung via SMS für maximale Erreichbarkeit
  • ein bisschen Software, ein bisschen Konfiguration

Ich beschreibe im Folgende meine Vorgehensweise und fange prinzipiell bei Null an. Also fast bei Null. Der Raspi sollte betriebsbereit sein, also ein aktuelles Raspbian sollte installiert sein und die Verbindung via SSH steht.

Verwendete Komponenten

Hostnamen ändern

sudo nano /etc/hostname

Passwort des Standardusers ändern

passwd

Mehr zum Thema Benutzer absichern
Über den hostnamen auf den Raspi zugreifen

Energiesparmodus vom Edimax ausschalten

Der verwendete Wifi-Dongle EW-7811UN hat die Eigenheit nach einer gewissen Zeit der Untätigkeit in einen Dauerschlaf zu verfallen. Für den Dauerbetrieb muss das Teil natürlich „always on“ sein und dafür sind die folgenden Schritte nötig.

in der Datei

sudo nano /etc/modprobe.d/8192cu.conf

diese Zeile einfügen:

options 8192cu rtw_power_mgnt=0 rtw_enusbss=0

dann reboot mit

sudo shutdown -r now

Multiple WIFIs

Wenn das Auto vor der Türe steht soll es sich in mein WLAN einbuchen. Ich habe mehrere Netzwerke und eine kleinere Anpassung soll dafür sorgen, dass sich der Raspi automatisch in eines der Netwerke einklinkt. Diese Anleitung hat mir dabei geholfen.

Diese Datei zum editieren öffnen:

sudo nano /etc/wpa_supplicant/wpa_supplicant.conf

dort werden diese Zeilen eingefügt:

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
ssid="<SSID>"
scan_ssid=1
psk="<PASS>"
proto=RSN
key_mgmt=WPA-PSK
id_str="<SOME_ID>"
}

network={
ssid="<SSID>"
scan_ssid=1
psk="<PASS>"
proto=RSN
key_mgmt=WPA-PSK
id_str="<SOME_ID>"
}

Dabei sind natürlich die SSID, PASS an die eigene Umgebung anzupassen. SOME_ID kann irgendetwas sein, wichtig ist nur, dass sie sich unterscheiden falls man mehrere hat.

Weiter muss man noch diese Datei anpassen.

sudo nano /etc/network/interfaces

und mit diesem Inhalt füllen.

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

auto wlan0
allow-hotplug wlan0
iface wlan0 inet manual
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
iface <SSID> inet dhcp
address 192.168.0.49
netmask 255.255.255.0
gateway 192.168.0.1
iface <SSID> inet dhcp
address 192.168.0.49
netmask 255.255.255.0
gateway 192.168.0.1

Die Konfiguration besagt, dass für eth0, also das kabelgebunde Netzwerk eine IP über DHCP vergeben wird und für die beiden WiFis feste IPs inklusive Netmask und Gateway. Diese Parameter müssen natürlich an das eigene Netzwerk angepasst werden.

Direkte Verbindung von Raspi und Mac

Falls etwas mit dem Wireless-Netzwerk schiefläuft, hilft nur den Raspi per Netzwerkkabel direkt mit dem Computer (in meinem Fall ein Mac) zu verbinden.

Ethernet muss IP per DHCP beziehen.

bildschirmfoto-2016-10-23-um-20-56-04

Internetfreigabe muss aktiviert sein:

bildschirmfoto-2016-10-23-um-20-56-38

Standardmäßig bekommt der Raspi die IP 192.168.2.2. Diese kann jetzt verwendet werden um sich mit dem Raspi per SSH zu verbinden:

ssh -l pi 192.168.2.2

SMS per Raspi versenden

Dieser Artikel hat mir sehr dabei geholfen den UMTS-Stick in Betrieb zu nehmen und die erste SMS per Kommandozeile zu versenden. Zunächste also den UMTS Stick mit einer Simkarte bestücken (z.B. aus einem günstigen Pre-Paid-Tarif) und rausfinden wohin der Raspi das device gemounted hat. Das geht am besten mit:

lsusb

Der von mir verwendete Stick Huawei E303 Surfstick wird vom Betriebssystem offensichtlich sofort als GSM-Modem erkannt und entsprechend gemounted. Wenn man diese Kommando ausführt

ls -al /dev/

sieht man folgenden Eintrag:

lrwxrwxrwx   1 root root           7 Okt 21 20:17 gsmmodem -> ttyUSB1

Wir sollten zukünftig den Stick also über /dev/gsmmodem ansprechen und nicht über ttyUSBx, da sich das nach jedem Reboot ändern kann. Das wird insbesondere dann ein Problem wenn später noch die GPS-Maus angestöpselt wird.

Es gibt diverse Libraries mit denen man unter Linux SMSen versenden kann. Gammu hat den Vorteil, dass es recht weit verbreitet ist und es auch einen Python-Wrapper dafür gibt. Python werde ich nämlich verwenden um die GPIO-Pins des Raspis anzusteuern. Mit diesem Befehl wird gammu zusammen mit den entsprechenden Python libs installiert:

sudo apt-get install -y gammu-smsd gammu python-gammu

Gammu wird über ein Konfig-File parametrisiert.

sudo nano /etc/gammu-smsdrc

Diesen Inhalt reinkopieren:

# Configuration file for Gammu SMS Daemon
# Gammu library configuration, see gammurc(5)
[gammu]
# Please configure this!
port = /dev/gsmmodem
connection = at
# Debugging
#logformat = textall

# SMSD configuration, see gammu-smsdrc(5)
[smsd]
#pin = 9193
service = files
logfile = syslog
# Increase for debugging information
debuglevel = 0

# Paths where messages are stored
inboxpath = /var/spool/gammu/inbox/
outboxpath = /var/spool/gammu/outbox/
sentsmspath = /var/spool/gammu/sent/
errorsmspath = /var/spool/gammu/error/

RunOnReceive = sudo /home/pi/scripts/sms_relay.py

Beachtenswert ist hier der port, also wie erwähnt /dev/gsmmodem verwenden und die letzte Zeile. Diese besagt, dass jedesmal wenn eine SMS empfangen wird das angegebene Python-Skript ausgeführt werden soll. Zum Inhalt des Skripts später mehr. Nach den Änderungen wird die Konfiguration durch einen Neustart des gammu Daemons frisch eingelesen.

sudo /etc/init.d/gammu-smsd restart

Per Kommandozeile kann jetzt eine Test SMS versendet werden. Hierbei ist natürlich eine sinnvolle Mobilnummer einzugeben.

echo "Ich bin eine Test-SMS, versandt vom Raspberry Pi" | sudo gammu-smsd-inject TEXT "+49xxxxxxxx"

Gammu legt die SMSen standardmäßig in diese Verzeichnisse

inboxpath = /var/spool/gammu/inbox/
outboxpath = /var/spool/gammu/outbox/
sentsmspath = /var/spool/gammu/sent/
errorsmspath = /var/spool/gammu/error/

Berechtigungsproblem mit dem RunOnReceive-Skript

Das Kommando zeigt an, dass gammu unter dem user gammu läuft.

ps aux | grep -i gammu

Damit user “gammu” das Skript ausführen kann muss man ihn in die liste der sudoers aufnehmen und angeben, dass beim sudo kein passwort erforderlich ist. Dazu im File

sudo visudo

am Ende diese Zeile einfügen:

gammu ALL=(ALL) NOPASSWD: ALL

Die Lösung habe ich hier gefunden.

Weitere Gammu Dokus

https://wammu.eu/docs/manual/smsd/run.html#gammu-smsd-run
http://tech-blog.stuartwarren.com/2014/04/raspberry-pi-as-sms-gateway-using.html?m=1

GPIO schalten

Um die Standheizung einzuschalten müssen prinzipiell 2 Kabel aus der Zeitschaltuhr (das grüne und das weiße) auf Durchgang geschaltet werden. Das Durchschalten erledigt das Relais. Auf der Steuerstromseite wird das Relais mit dem Pin 11 (GPIO 17) des Raspberry verbunden. Geschaltet wird über Python-Skripte. Aber fangen wir mit ein paar Basics an.

Pinbelegung des Raspberry Pi:

raspberry-pi-15b

Im Nachfolgende einige Fingerübungen mit den Pins.

GPIO status auslesen:

gpio readall

Mode einstellen, also ob der Pin als Ausgang, bzw. als Eingang fungiert.

gpio mode 0 out

PIN 0 ausschalten:

gpio write 0 0

PIN 0 einschalten:

gpio write 0 1

Hier eine sehr gute Anleitung um GPIOs mit Python zu schalten.

Relais verdrahten und initialisieren

Das Relais wird so mit dem Raspberry verdrahtet:

raspi-mit-relais_steckplatine

Um ein Python skript direkt nach dem Bootvorgang zu starten dieses File ändern

sudo nano /etc/rc.local

dort vor der letzten Zeile exit 0 folgendes einfügen:

# initializes the GPIO Pins 11 and 12 on start of the raspberry
sudo /home/pi/scripts/init_GPIO.py

Das Skript selbst sieht so aus:

#!/usr/bin/env python
import RPi.GPIO as GPIO
import sys
import syslog
import gammu.smsd

GPIO.setmode(GPIO.BOARD)
GPIO.setup(11, GPIO.OUT, initial=GPIO.HIGH)
GPIO.setup(12, GPIO.OUT, initial=GPIO.HIGH)


def sendConfirmationSMS(text):
        smsd = gammu.smsd.SMSD('/etc/gammu-smsdrc')
        message = {'Text': text, 'SMSC': {'Location': 1}, 'Number':'+49xxxxxxxx'}
        smsd.InjectSMS([message])
        return;
        
syslog.syslog("Raspberry is ready!")
sendConfirmationSMS("Rasp ist bereit!")

 

Watchdog aktivieren und einrichten

Laden des Kernelmoduls und anschließende Installation des Deamons:

sudo apt-get install watchdog
sudo modprobe bcm2708_wdog
echo "bcm2708_wdog" | sudo tee -a /etc/modules

Anschließend muss noch die Konfigurationsdatei des Watchdog-Daemon angepasst werden, um die Gerätedatei des Watchdogs und die Bedingungen für einen Reset festzulegen.

sudo nano /etc/watchdog.conf

In der Konfigurationsdatei müssen folgende beiden Zeilen auskommentiert werden (Raute-Zeichen am Anfang der Zeile entfernen):

watchdog-device = /dev/watchdog max-load-1 = 24

Bei Raspbian Jessie muss in der Datei

/lib/systemd/system/watchdog.service

noch folgender Eintrag ergänzt werden:

[Install]
WantedBy=multi-user.target

Zum Abschluss der Konfiguration muss der Watchdog-Daemon nun noch neu gestartet werden. Fertig.

sudo systemctl enable watchdog.service
sudo systemctl start watchdog.service

Die sehr gute Anleitung habe ich hier gefunden:
http://www.datenreise.de/raspberry-pi-stabiler-24-7-dauerbetrieb/