Raspberry Pi Security Camera App
In diesem Report stelle ich euch mein aktuelles Projekt vor, eine Raspberry Pi Security Camera App. Ich erkläre in den folgenden Absätzen und Artikeln das Projekt und geben den gesamten Source Code frei, damit ihr dieses bei Bedarf nachbauen könnt.
Raspberry Pi Security Camera App
Worum geht es? Mit einem Smartphone App kann ich die Fotos einer Raspberry Pi gesteuerten Security Cam von überall auf der Welt abfragen. Die App besteht aus folgenden Teilen:
- IoT Gerät(e)
Ein Raspberry Pi macht mit einer angeschlossenen Kamera ein Bild. Von diesen Bildquellen gibt es beliebig viele. Ein Raspberry Pi könnte mit beliebig vielen angeschlossenen Kameras (Pi-Kamera oder USB-Kamera) Bilder machen. Es kann beliebig viele solcher Raspberry Pis geben. - das erstellte Bild wird auf einen Server hochgeladen
Auf dem Backend werden Bilder und zugeöhrige Metadaten abgespeichert (letztes aktuelles Bild -> Timestamp, Name des IoT Gerätes, …) - eine mobile App (Android oder iOS) zeigt die Bilder an
Die App holt sich vom Backend die Metadaten und zeigt zu jedem definierten Endgerät das letzte aktuelle Bild an.
In der Folge alle Details zu den einzelnen Teilen. Der Source Code ist wie üblich auf meiner GitHub Seite verfügbar. Die Übersicht der verwendeten Sprachen zeigt folgendes Bild:
Die weiteren technischen Details zum Projekt erfordern Skills eines Full-Stack Entwicklers. Ich gehe nicht davon aus, dass jeder Leser sofort mit dem Code arbeiten will und Teile des Projekts anpassen möchte. Deshalb starte ich mit einer Erklärung für das Setup des Projekts aus Sicht eines Anwenders. Das Projekt ist derzeit noch nicht in einem Zustand, dass ein Skript alles einrichtet. Du solltest dich zumindest mit Linux und dem Raspberry Pi auskennen.
Setup
Damit du die Bilder vom Raspberry Pi auf deinem Smartphone anschauen kannst brauchst du folgendes:
- Raspberry Pi mit Kamera
Ich verwende als IoT Device einen Raspberry Pi. Dieser macht periodisch mit der dort angeschlossenen Kamera ein Foto. Der Pi muss eine Verbindung mit dem Internet haben, meiner hängt im WLAN. Am Raspberry Pi ist eine Kamera angeschlossen. Das kann entweder die offizielle Raspberry Pi Kamera sein, oder eine generische USB-Kamera. Ich verwende für meine erste Version eine aus einem kaputten Laptop ausgebaute Webcam. Die habe ich an ein USB Kabel angelötet. Du musst dir also nicht unbedingt neue Hardware kaufen! - Webspace
Der Pi schickt die Bilder laufend zu einem Server. Ich habe mit PHP ein Mini Backend erstellt, welches ein solches Bild entgegennimmt und abspeichert. Zusätzlich erstellt es eine Datei mit Metadaten. Ich habe mich bewusst für PHP entschieden, da jeder 0815 Hoster ein solches Skript ausführen kann. Habt ihr keinen Webspace, dann reicht ein Hostingpaket um einen Euro locker aus. Alternativ fragt ihr einen Freund, ober er ein paar Megabyte für das Backend erübrigen kann. - Smartphone
Du hast bestimmt ein Smartphone. Die App ist mit React Native programmiert und funktioniert deshalb unter Android und iOS. Da ich keine Apple Produkte besitze findet man die App aktuell nur im Android Store. Mit dem nötigen Know How kannst du aus meinem Source Code aber schnell eine iOS App bauen.
Ich habe die Quelldaten meines Projekts im GitHub Repository in die Ordner API (Backend), App (Smartphone App) und Raspberry Pi (Kamera Script) aufgeteilt. Beginnen wir mit dem Setup vom Raspberry Pi.
Raspberry Pi
In diesem Projekt setze ich auf meinen bewährten Raspberry Pi 3B+. Dieser ist Leistungsstark genug um laufend Bilder zu machen und diese auf den Webspace hoch zu laden. Es reicht ein Pi an dem man eine Kamera anschließen kann.
Hardware
Ich habe für mein Projekt 2 Kameras im Einsatz. Zum einen die originale Pi Cam, die direkt mit dem Flachbandkabel am Camera Interface hängt, zum anderen eine aus einem Laptop ausgebaute Webcam die ich an ein USB Kabel gelötet habe. Leider schafft diese aber aufgrund felender Treiber nur Auflösungen von 640×480.
Script
Im Projektordner findet man ein capture.sh Script.Das Skript benötigt einige Voraussetzungen die man wie folgt installiert:
sudo apt-get install curl fswebcam
Wird das Skript ausgeführt, dann wird anhand der dort getroffenen Einstellungen ein Bild erstellt und ans Backend geschickt. Zusätzlich kann man das Bild auch lokal, beziehungsweise auf einem Netzwerk Share ablegen (falls man eine Aufzeichnung benötigt). An folgenden Stellen sind Anpassungen nötig:
- jedes Engerät benötigt einen Namen. Unter diese Namen werden die Bilder im Backend abgespeichert und in der App abgespeichert. Verwendest du mehr als einen Pi bzw. mehr als eine Kamera, dann muss jedes Skript das Daten ans Backend schickt einen anderen eindeutigen Namen haben.
- das ist der Pfad an dem das Bild temporär abgespeichert wird
- das ist der Pfad unter dem das Bild dauerhaft abgespeichert wird. In meinem Fall ist das ein Netzwerkshare, der unter /mnt gemounted ist. Das kann auch ein Ordner am Raspberry Pi sein.
- Das ist die vollständige URL zum upload.php Skript des Backends. Siehe dazu weiter unten die Beschreibung für das Setup des Backends.
- die Bilder werden mit fswebcam geschossen. Über einen Parameter kann man die gewünschte Auflösung angeben. Wichtig: die gewählte Auflösung muss von der angeschlossenen Kamera unterstützt werden, andernfalls wird automatisch auf eine mögliche Auflösung umgeschalten.
Mit dem Befehl
chmod +x
muss man diesem Skript noch die Berechtigung geben ausgeführt werden zu können. Zum Testen lässt sich das Skript danach jederzeit mit
./capture.sh
vom Terminal aus ausführen. Wenn alles klappt, kann man mit einem Cronjob die automatische Ausführung konfigurieren.
Alternative
Alternativ zur beschriebenen Methode mit einer USB Webcam kann man auch die offizielle Raspberry Pi Kamera verwenden. Diese Option ist etwas teurer, liefert aber optimale Bilder. Anstatt das Bild mit fswebcam zu schießen verwenden wir stattdessen libcamera-still, der neue Name des noch auf vielen Blogs mit Beschreibungen zu findende raspistill.
libcamera-still-o $localStorage
In meinem Repo auf GitHub habe ich diese Option aktuell als default gesetzt, die fswebcam Option ist aber weiterhin als Kommentar zum Umschalten im capture.sh Script.
Optimierung
Jede Ausführung des Skripts erstellt eine Aufnahme auf dem Raspberry Pi (localStorage Einstellung). Häufige Schreibvorgänge führen zu einem Defekt der SD Karte. Abhilfe schafft da ein kleiner Trick. Die folgenden Befehle:
erstellen den neuen Ordner /capture im Dateisystem und mounten dort einen 50 MB großen Teil des Hauptspeicher. Diese RAM Disk kann vom Skript beschrieben werden. Man kann dort ganz normal Dateien abspeichern. Tatsächlich existieren diese aber nur im Hauptspeicher, sind also nach einem Neustart verschwunden. Das ist perfekt um temporär das geschossene Bild abzulegen, bevor es dem Backend übergeben worden ist.
Crontab
Damit der Raspberry Pi die Fotos laufend macht muss ein Cronjob eingerichtet werden. Das geht mit dem Befehl
crontab -e
Ich habe folgende Zeile hinzugefügt und die Datei gespeichert:
*/1 * * * * /home/pi/capture.sh
Wichtig: Bei der Definition von Cronjobs muss man immer absolute Pfade verwenden. Mit dieser Konfiguration wird das Skript zum Schießen und Hochladen des Fotos jede Minute ausgeführt.
Backend
Das Backend habe ich mit PHP geschrieben und sollte deshalb sogar auf den günstigsten Hostingpaketen laufen. Du musst die Dateien nur in einen Ordner auf den Webserver kopieren. Ich verwende dafür WinSCP.
Der Hoster sollte das Ausführen von PHP Dateien unterstützen. Navigiert man über den Browser zum Ordner und führt dort explizit die upload.php Datei aus, dann muss folgende Meldung scheinen:
Der img Ordner muss für das Skript Schreibrechte besitzen damit dort die Bilder abgespeichert werden können. In meinem Fall war das bereits Standardmäßig so. Falls nicht kann man diese mit dem WinSCP Programm ändern:
Woher weiß man ob die Rechte passen? Mit folgendem Befehl kann man vom Raspberry Pi aus manuell ein Bild zur API schicken:
curl -F "camImg=@/home/pi/test-2022.01.24-12-01-01.jpg" https://my-api-domain.com/upload.php
Damit das klappt muss der Dateiname vom Bild zwingend ein „-“ enthalten, da das Backend die Zeichen vor dem ersten „-“ als Name der Kamera interpretiert und das Bild am Server unter diesem Namen abspeichert. Das bedeutet, wenn alles funktioniert findest du nun die Datei test.jpg im img Ordner.
Smartphone
Die Smartphone App findet man aktuell nur im Android PlayStore (PiCam im PlayStore). Einmal heruntergeladen funktioniert sie erst, wenn die Datenquelle bekannt ist. Dazu gibt man den Pfad zum Backend und den Dateinamen der Metadaten an. Über den Pfad + Metadaten Dateinamen werden die Informationen über registrierte Raspberry Pis geholt und die Pfade und Timestamps der jeweils letzten Bilder. Die Kombination aus Backend URL und Dateiname des Bildes zeigt die App im Hauptbildschirm an. Dort kann ich als Benutzer alle aktuellen Bilder durchscrollen. Über einen Reload Button lässt sich die Anzeige jederzeit aktualisieren.
Fazit
In diesem ersten Artikel zu meinem Raspberry Pi Security Camera App Projekt habe ich das Projekt kurz vorgestellt und für Anwender eine hoffentlich nützliche Anleitung geschrieben. Ohne große Programmierkenntnisse solltest du damit in der Lage sein selber die einzelnen Teile zu konfigurieren und am Smartphone die aktuellen Bilder vom Raspberry Pi zu sehen. Im nächsten Teil widme ich mich speziell an alle interessierten Entwickler und nehme die einzelnen Teile im Detail auseinander.
Danke für die ausführliche Anleitung. Kann dieses Setup auch auf Videofeeds umgestellt werden?