DisSecure

Aus HRW FabLab MediaWiki
Wechseln zu: Navigation, Suche

Allgemeines[Bearbeiten]

Bei DisSecure handelt es sich um eine mobile und leichtgewichtige Home Security-Lösung, die die Messenger-App Discord nutzt, um per Smartphone oder anderen Discord-fähigen Endgeräten einen Raspberry Pi samt angeschlossener Peripherie zu steuern. Diese Peripherie bildet hierbei den Kern der Home Security-Anlage und besteht zwingend aus einer Kamera zur Bewegungsmeldung sowie einem beliebig gearteten Alarm wie beispielsweise Ton- oder Lichtsignalen, um etwaige Einbrecher abzuschrecken.

Die Idee hinter DisSecure ist eine Home Security-Lösung, dessen Komponenten erschwinglich und zudem leicht zu transportieren sind - die Schlagworte sind 'mobil' sowie 'leichtgewichtig'. Aus diesem Grund stellt der Raspberry Pi die Basis des Systems dar. Eine rudimentäre USB-Kamera wie eine Webcam mit einigermaßen akzeptabler Bildqualität und geringem Bildrauschen sowie ein per Breadboard angeschlossenes Ausgangssignal, entweder licht- oder tonbasiert, bilden in Verbindung mit entsprechender Software und Anbindung an den Raspberry Pi ein funktionierendes Home Security-System. Dieses kann durch die Discord-App nicht nur ferngesteuert werden - die Software nimmt außerdem Bilder von vermeintlichen Einbrechern und anderen Störenfrieden auf und sendet sie über Discord an den Nutzer, der nach Sichtung des Materials entscheiden kann, ob es sich um einen falschen Alarm handelt oder vielleicht doch die Polizei eingeschaltet werden sollte.


Funktion[Bearbeiten]

DisSecure nutzt die frei verfügbare Messenger-App Discord als Schnittstelle zwischen dem Nutzer und dem Raspberry Pi, welcher den Kern des Home Security-Systems bildet. Discord als Messenger-App hebt sich insofern von vergleichbaren Apps wie WhatsApp ab, da jeder Nutzer eigene Server erstellen kann, welche mit verschiedenen Text- oder Voice-over-IP-Channeln ausgestattet werden können, um mit anderen Server-Mitgliedern zu kommunizieren. WhatsApp bietet mit Gruppen zwar ähnliche Funktionalität, jedoch weniger ausgereift und deutlich unübersichtlicher. Discord hebt sich außerdem von WhatsApp ab, da eine offizielle und vollständig dokumentierte API bereitgestellt wird, die im Rahmen dieses Projekts genutzt wurde, um die Kommunikationsschnittstelle zwischen Nutzer und Home Security-System zu realisieren.

Dazu muss in erster Linie ein sogenannter Bot auf den eigenen Discord-Server eingerichtet werden, welcher sich unkompliziert per Token mit dem gewünschten Raspberry Pi verbinden kann, auf dem die Discord-API und die DisSecure-Software eingerichtet wurden. Dieser Bot ist nun ein sichtbares, als Bot ausgezeichnetes Mitglied des eigenen Servers, mit dem über ein festgelegtes Set von Befehlen kommuniziert werden kann - beispielsweise, um die Kamera zu starten und den Alarm scharfzuschalten.

Registriert die im nachfolgenden Beispiel nun scharfgestellte Kamera Bewegungen oder Bildveränderungen wie den kurzfristigen Wechsel von Lichtverhältnissen, wird automatisch der angeschlossene Alarm ausgelöst. Die DisSecure-Software speichert außerdem drei Kamera-Frames samt automatisch generierter Timestamps, während der Alarm ausgelöst wurde und sendet diese mit einer entsprechenden Benachrichtigung über den Discord-Bot an den Nutzer. Der Nutzer erhält so die Möglichkeit, vermeintliche Einbrecher oder anderweitige Gefahrensituationen zu identifizieren und kurzfristig handeln zu können oder die Anlage bei einer Falschmeldung zurückzusetzen.


Planung[Bearbeiten]

Hardware[Bearbeiten]

Es wurde für das DisSecure-Projekt eine Raspberry Pi, eine USB Kamera, ein Breadboard, eine Diode als Substitution für einen tatsächlich abschreckenden Alarm sowie eine Mini SD-Karte zur Speicherhaltung benutzt. Zu Verwendung von DisSecure wird ein einigermaßen modernes Smartphone vorausgesetzt, welches über eine Internetverbindung sowie ein gängiges Betriebssystem wie Android verfügt. Die Internetverbindung ist zwingend nötig, damit das Home Security-System über Discord mit dem Nutzer kommunizieren kann.


Software[Bearbeiten]

Das DisSecure-Projekt basiert softwareseitig auf der Programmiersprache Python sowie der offiziellen Discord-API.


API-Wechsel[Bearbeiten]

DisSecure war nicht immer ein Discord-basiertes Projekt. Zu Beginn der Konzeptionsphase war angedacht, ein mobiles Home Security-System per WhatsApp zu steuern, da es sich bei WhatsApp um eine bekanntere und populärere Messenger-App handelt. In dieser Zeit war das Projekt noch als 'WhatsSecure' betitelt. Doch bereits die ersten Programmierversuche stießen auf das Problem, dass WhatsApp kein offiziellen API für ihren Messenger bereitstellt und daher auf eine inoffizielle API zurückgegriffen werden musste. Prinzipiell entstand hier noch keine unumgängliche Hürde, lediglich eine Komplikation, denn die inoffizielle Yowsup 2-Bibliothek, die wir verwenden wollten, setzte die Registrierung des Raspberry Pis bei WhatsApp voraus - was wiederum eine separate SIM-Karte voraussetzte.

Erst im Anschluss mussten wir jedoch feststellen, dass die Yowsup 2-Bibliothek nur noch teilweise mit der aktuellen Version von WhatsApp kompatibel gewesen ist und viele zentrale Befehlsbausteine nicht funktioniert haben. Nach einer Google-Recherche fanden wir außerdem heraus, dass WhatsApp aktiv gegen inoffizielle APIs vorgeht, die für ihre Messenger-App entwickelt werden. Im Zuge dessen entschieden wir uns kurzerhand, das Projekt nicht mehr auf Basis von WhatsApp fortzuführen, sondern eine alternative Messenger-App zu verwenden. Einer der Hauptgründe für diese Entscheidung war die Aussicht darauf, dass jede neue WhatsApp-Version die Software unseres Projekts entweder teilweise oder völlig inkompatibel mit der App gemacht hätte.

Durchführung[Bearbeiten]

Hardware[Bearbeiten]

Für DisSecure haben wir ein Raspberry Pi 3 Model B in Verbindung mit einer Standard USB-Kamera benutzt. Um die ein abschreckendes Alarmsignal zu substituieren, wurde auf einem Breadboard eine einfache Leuchtdiode angebracht, welche durch die Pins 6 für Ground und 12 für Power verbunden wurde.

Software[Bearbeiten]

Unsere Software für DisSecure baut auf vier verschiedenen Teilen auf. Eher nutzerseitig existiert zum einen der Discord-Bot sowie Discord als Messenger-Applikation. Der Bot nimmt über Discord die Befehle des Nutzers entgegen und informiert den Nutzer automatisch über Alarme. Zum anderen existiert auf Seite des Raspberry Pi ein sogenannter Receiver, welcher die Befehle des Bots entgegennimmt, diese ausführt und außerdem Nachrichten generiert, welche über den Bot an den Nutzer ausgegeben werden können. Ferner existiert noch die Kamera-Software, welche in einem Loop durchgehend den Kamera-Feed überwacht und bei verdächtigen Bildveränderungen den Receiver alarmiert.

Discord[Bearbeiten]

Im Mittelpunkt unseres Projekts steht die Messenger-Applikation Discord, welche es ähnlich Skype, Teamspeak oder WhatsApp Nutzern erlaubt, schnell und unkompliziert per Text- oder Sprachnachrichten zu kommunizieren. Discord kann über jeden handelsüblichen Browser gestartet werden, bietet allerdings auch dedizierte Applikationen für Windows, Android und iOS. Des weiteren erlaubt Discord den Nutzern eine unkomplizierte Einbindung von Bots durch das Bereitstellen einer offiziellen API. Diese Bots bekommen automatisch ein Token bereitgestellt, ferner stehen auch Optionen wie OAuth 2.0 zur Verfügung, um Bots zu implementieren.

Bot[Bearbeiten]

Der Bot für DisSecure läuft in Python auf dem Raspberry Pi. Dahinter steht discord.py, ein Wrapper für die Discord-API. Dieser Wrapper bietet einfache Möglichkeiten, um den Bot über ein Token zu registrieren sowie verschiedene Befehle zu programmieren.

Beispiel Setup für discord.py

description = HRW DisSecure Bot Embedded Systems Project
bot = commands.Bot(command_prefix='?', description=description)

Wie im Setup zu sehen, kann dem Bot eine Erklärung zugeordnet werden. Des weiteren kann durch die Bestimmung eines command_prefix ein Symbol festgelegt werden, welches den Bot anspricht.

Beispiel Befehl für discord.py

@bot.command()
async def hallo():
	"""Gibt Hallo zurück"""
	await bot.say("Hallo")
	return

Ein Befehl des Bots basiert auf der Notierung @bot.command() und einer nachfolgenden Funktion. In diesem Fall würde der Bot beim Anschreiben mit ?hallo ein "Hallo" ausgeben. Im Laufe der Programmierung des Bots sind immer wieder verschiedene Probleme aufgetreten, welche gelöst werden mussten. Beispielsweise muss sich der Bot alle 60 Sekunden einmal mit der Discord-API verbinden, um Aktivität zu zeigen. Im Zuge dessen mussten alle blockenden Teile des Codes in ein separates Programm ausgelagert werden.

Bot-Befehle

  •  ?start Startet die Kamera nach einer kurzen Startup Phase.
  •  ?stop Stoppt die Kamera und den Alarm.
  •  ?prime Sobald die Kamera gestartet ist, kann der Alarm scharfgestellt werden.
  •  ?defuse Entschärft den Alarm, lässt aber die Kamera weiterlaufen.
  •  ?help Gibt eine kurze Erklärung aller Befehle aus.

Receiver[Bearbeiten]

Der Receiver ist das oben genannte separate Programm, welches Befehle des Nutzers verarbeitet und Antworten an den Nutzer generiert. Es handelt sich um eine einfache, auf Python basierte WebApplication, die dank tornado verwirklicht wurde. Der Discord-Bot öffnet ein Websocket zu dieser WebApplication und sendet eine Method über JSON, die nachfolgend im Receiver ausgeführt wird.

Methode zum Start der Kamera

	def start(self):
		global videocamera, prime_flag, start_flag
		start_flag = True
		videocamera = threading.Thread(target=camera_thread.run)
		videocamera.start()
		return "Camera started."

In diesem Beispiel wird die Methode Start aufgerufen, welche für unsere Kamera einen separaten Verarbeitungsthread startet. Am Ende wird der Websocket abermals angesprochen und ein Return erzeugt, hier in Form eines Textes, welcher über den Bot an den Nutzer ausgegeben wird, um ihn über die aktuelle Situation in Kenntnis zu setzen.

Die größten Probleme während der Implementierung waren abermals das Unterbringen des blockenden Codes, welcher auch schon aus der Bot-Software entfernt werden musste.

Blockender Code

	async def prime(self):
		global videocamera, prime_flag
		secret = False
		prime_flag = True
		while prime_flag:
			await asyncio.sleep(1)
			#print("wait 1 secs")
			try:
				if videocamera.alarm_trigger:
					prime_flag = False
					secret = True
			except  Exception as e:
				#print(e)
				None
		if secret:
			return "Yes"
		else:
			return "No"

Da unsere Camera einen eigenen Thread hat, ist kein direkter Zugriff über Python gewährleistet. Dieses Problem wurde umgangen, indem Startvariablen des Pythonthreads überprüft werden. Hier benutzen wir die Variable videocamera.alarm_trigger, um zu überprüfen, ob ein Alarm vorliegt. Wie man ferner sieht, weist der Code ein "await asyncio.sleep(1)" auf. Das bedeutet, dass pro Sekunde lediglich eine Überprüfung erfolgt, gewährleistet aber im selben Zug, dass der restliche Code in dieser Sekunde weiterhin ausgeführt werden kann. Die Ausführung des restlichen Codes ist besonders wichtig, um Befehle wie ?stop zu registrieren.

Kamera[Bearbeiten]

Ein zentraler Aspekt des DisSecure-Projekts ist die Kamera-Software. Wir benutzen OpenCV über Python, um verschiedenste USB-Kameras ansprechen zu können. Am Anfang des Programms wird ein Kamera-Feed aufgebaut. Dieser wird im Folgenden dauerhaft überwacht und mit einem vorhergehendem Bild abgeglichen, um Veränderungen festzustellen. Das Test-Bild wird alle 60 Sekunden neu aufgenommen. Ansonsten würde die Kamera nach längerer Zeit am selben Ort auch natürliche Lichtveränderungen wie die Dämmerung als möglichen Einbrecher wahrnehmen.

Aufrufen des Threads

if status_2 == 'background':
	newbacktimer = threading.Timer(60, newback)
	newbacktimer.start()
	status_2 = 'background_change_ongoing'

Änderung des Vergleichbildes

def newback():
	print("Background Change Over")
	global status_2
	global back
	status_2 = 'background'
	back = None

Auch müssen wir davon ausgehen, dass im Feed selbst Probleme entstehen können. Einige dieser Probleme haben wir während mehrerer Testdurchläufe identifizieren können. Hierzu gehören beispielsweise Artefakte der Kamera, falsche Übertragungen, aber auch ein kurzer Abbruch des Feeds. Diese Probleme können dazu führen, dass eine Auslösung des Alarms stattfindet. Um das zu verhindern, wurde eine bestimmte Anzahl von Fehler- bzw. Falschmeldungen eingebaut, welche in Sequenz aufeinander folgen dürfen, bevor von einem Ereignis ausgegangen werden kann, der tatsächlich einen Alarm rechtfertigt. Hierbei handelt es sich letztendlich um einen Threshold-Wert, um für qualitativ minderwertige Kameras zu kompensieren. Erst, wenn dieser Threshold-Wert überschritten innerhalb einer bestimmten Zeitspanne überschritten wird, kommt es zum Alarm.

Wird der Alarm ausgelöst, werden im Abstand von drei Sekunden drei Bilder des möglichen Einbrechers aus dem Feed gespeichert.

Aufnahme

if timer == 0:
	cv2.imwrite("culprit.jpg", culprit_frame)
	time.sleep(3)
if timer == 1:
	cv2.imwrite("culprit2.jpg", culprit_frame)
	time.sleep(3)
if timer == 2:
	cv2.imwrite("culprit3.jpg", culprit_frame)
	setattr(t, "alarm_trigger", True)
	status = 'interrupted'
timer += 1

Sobald der Bot erkennt, dass ein Alarm ausgelöst wurde, greift dieser alle drei gespeichert Bilder ab und sendet sie über Discord an den Nutzer. Nach erfolgreicher Übertragung der Bilder setzt sich das System zurück und kann erneut gestartet sowie scharfgestellt werden.


Links[Bearbeiten]

  • Discord Application, welche das Grundgerüstet bildet für die Kommunikation mit dem User.
  • Bildvergleich Nr. 1 Beispiel was zur Hand gezogen wurde für den Vergleich von Bildern.
  • Bildvergleich Nr. 2 Weiteres Beispiel was zur Hand gezogen wurde für den Vergleich von Bildern.
  • Discord API Python Einfach Bibliothek für die Verwendung der Discord API in Python.
  • Tornado Framework für einen internen Websocket, wird beim Receiver benutzt.