{"id":393,"date":"2017-06-27T21:55:21","date_gmt":"2017-06-27T19:55:21","guid":{"rendered":"https:\/\/www.pingu-mobil.de\/iot\/?p=393"},"modified":"2021-05-14T10:07:49","modified_gmt":"2021-05-14T08:07:49","slug":"home-security-zusammenbringen-der-app-und-des-backends-auf-dem-pi","status":"publish","type":"post","link":"http:\/\/www.iot-embedded.de\/iot-2017\/home-security\/home-security-zusammenbringen-der-app-und-des-backends-auf-dem-pi\/","title":{"rendered":"Home Security: Zusammenbringen der App und des Backends auf dem Pi"},"content":{"rendered":"<p><strong>Webserver<\/strong><\/p>\n<p>In unseren letzten Blogbeitr\u00e4gen haben wir erl\u00e4utert wie die Hardware und die Software des eigentlichen Alarmsystems funktioniert. Da diese Komponenten mithilfe einer App steuerbar sein sollen, muss eine entsprechende Schnittstelle geschaffen werden. Daf\u00fcr soll ein Webserver eingesetzt werden, da der Pi f\u00fcr die Kamera generell im Wlan das Hauses h\u00e4ngt und theoretisch auch von au\u00dferhalb ein Zugriff m\u00f6glich w\u00e4re. Unsere Wahl fiel daf\u00fcr auf Spring Boot, da es einfach zu entwickeln ist, kein JavaEE voraussetzt und trotzdem viele Funktionen bietet.<\/p>\n<p>Da es m\u00f6glich sein soll lediglich \u00fcber die App die Alarmanlage zu steuern, muss der Webserver alle Funktionalit\u00e4ten anbieten, die zum Steuern n\u00f6tig sind. Genauer sind das die CRUD-Operationen f\u00fcr Regeln und Komponenten &#8211; Create, Read, Update &amp; Delete. Dementsprechend muss der Webserver eine Ansprechstelle f\u00fcr fast jede der Funktionen anbieten. Diese greifen dann auf die Methoden der Klasse Alarmsystem zu, um die entsprechenden Operationen auszuf\u00fchren. Um nun zu erkl\u00e4ren wie genau der Webserver aufgebaut ist, muss jedoch erstmal die Funktionsweise von Spring Boot n\u00e4her erl\u00e4utert werden:<\/p>\n<p>Eine Spring Boot-Applikation basiert auf verschiedenen Klassenarten: Der Application-Klasse, dem Webcontroller-Klasse und optionalle Konfigurations-Klassen. Die Application-Klasse ist dabei die Klasse, die gestartet wird und dann den Webserver hochf\u00e4hrt. Sie erkennt au\u00dferdem automatisch die Webcontroller-Klasse und Konfigurations-Klassen und bindet diese in den Server ein. Da entsprechende Klassen alle mit Annotationen versehen werden, kann Spring Boot diese von alleine erkennen und es muss in der Application-Klasse lediglich eine Main-Methode erstellt werden, welche den Server mit lediglich einem Befehl startet. Die n\u00e4chste Klasse ist die Webcontroller-Klasse. In dieser werden alle Endpunkte des Webservers erstellt. Dabei k\u00f6nne alle HTTP-Methoden verwendet werden, wie auch Parameter. Ein Endpunkt wird dann als Methode der Klasse definiert und das Return-Objekt der Methode ist der Response der HTTP-Anfrage. Die gro\u00dfe Besonderheit bei Spring Boot ist jedoch, dass dabei automatisch eine Umwandlung von Java-Klassen in JSON-Objekte vorgenommen wird. Somit ist die Schnittstellen-Definition um einiges simpler und auch einfach anzusprechen. Zus\u00e4tzlich ist eine Umwandlung auch in die andere Richtung m\u00f6glich, zum Beispiel bei einem Post-Request. Daf\u00fcr wird mithilfe von Annotationen lediglich ein Input Paramter als Post-Body erkl\u00e4rt und sobald ein JSON-Objekt, welches kompatibel zum Parameter ist, eintrifft, wird dieses in ein instanziiertes Java-Objekt umgewandelt. Die letzten Klassen die f\u00fcr unsere Spring Boot-Applikation relevant ist, sind die Konfigurations-Klassen. Mit diesen k\u00f6nnen Einstellungen an der Spring Boot-Applikation ver\u00e4ndert oder aktiviert werden. Daf\u00fcr muss in der Regel lediglich eine Annotation zu der entsprechenden Klasse hinzugef\u00fcgt werden und die Einstellungen sind beim n\u00e4chsten Hochfahren aktiv.<\/p>\n<p>Wie ist nun unser Webserver aufgebaut? Nat\u00fcrlich besitzt er die Application-Klasse, um den Webserver zu starten. Interessanter wird es bei der Webcontroller-Klasse. Hier gibt es nun Methoden f\u00fcr fast jede CRUD-Operation der beiden Klassen Rule und Component. Diese sind nach dem REST-Prinzip ansprechbar, also POST f\u00fcr CREATE, GET f\u00fcr READ, PUT f\u00fcr UPDATE und DELETE f\u00fcr DELETE. Die beiden GET-Methoden liefern dabei eine Liste aller Objekte zur\u00fcck. Bei POST und UPDATE muss ein zur Klasse passender Body mitgeschickt werden und f\u00fcr DELETE die Id als Request-Parameter, welches Objekt gel\u00f6scht werden soll. Jedoch besteht eine Besonderheit bei der Klasse Component. Diese stellt, wie im letzten Beitrag erkl\u00e4rt, die Basisklasse f\u00fcr die Klassen Sensor und Aktor da. Da eine neue Komponente jedoch automatisch registriert werden soll, wird daf\u00fcr nat\u00fcrlich keine POST\/CREATE-Methode angeboten. Stattdessen wird eine Registration-Methode dargeboten, die einen sogenannten &#8222;Einwahlmodus&#8220; aktiviert. Sobald ein Request an diese geschickt wird, nimmt das Alarmsystem f\u00fcr 60 Sekunden Anmeldungen von neuen Komponenten entgegen.<\/p>\n<p>Generell steht damit der Webserver und die Applikation rudiment\u00e4r ist lauff\u00e4hig. Da hier aber eine Alarmanlage umgesetzt wird, die das Haus auch sch\u00fctzen soll, muss nat\u00fcrlich auch \u00fcber Sicherheitsma\u00dfnahmen des Servers nachgedacht werden. Deswegen ist es sinnvoll zumindest den Zugang mit einem Username und einem Passwort zusch\u00fctzen. Zum Anmelden wird ein weiterer Endpunkt angeboten, der eben diese erwartet. Dies geschieht aktuell noch \u00fcber die simple \u00dcbermittlung der Daten, kann aber noch sp\u00e4ter ausgebaut werden. Da es sich hier aber um eine HTTP-Schnittstelle handelt und HTTP zustandslos ist, muss noch weiter abgesichert werden, dass die Anfragen an die anderen Endpunkte von einem Ger\u00e4t kommen, welches angemeldet ist. Dies geschieht mithilfe von Sessions. Sobald ein User sich anmeldet, wird ein Session-Attribut gesetzt, welches dies best\u00e4tigt. Mithilfe eines Cookies wird dann die Session gemerkt und sichergestellt, dass es sich um das gleiche Ger\u00e4t handelt. Bei jeder Anfrage wird, dann das Attribut abgefragt, ob das Ger\u00e4t angemeldet ist oder nicht. Sofern es das ist, wird die Anfrage problemlos ausgef\u00fchrt, andernfalls wird diese mit dem Code 403(Unaouthorized) abgebrochen.<\/p>\n<p>Jetzt muss nur noch gekl\u00e4rt werden, wie Sessions mit Spring Boot implementiert werden. Dies ist zum Gl\u00fcck sehr simpel. Daf\u00fcr muss lediglich die Konfigurations-Klasse &#8222;HttpSessionConfig&#8220; erstellt und mit der entsprechenden Annotation versehen werden. Dadurch sind Sessions automatisch im Webserver aktiviert. Ein weitere Zusatz ist jedoch erforderlich. Dadurch, dass Sessions in gewisser Weise persistent sind, m\u00fcssen die Daten daf\u00fcr irgendwo gespeichert werden. Spring Boot nutzt daf\u00fcr Redis, einen In-Memory-Speicher. Dieses muss dann zur Zeit der Ausf\u00fchrung verf\u00fcgbar sein und der Port und optionale Einwahldaten in einer Datei festgehalten werden, auf die Spring Boot Zugriff hat. Dadurch sind Sessions in Spring Boot einsetzbar.<\/p>\n<p>Damit w\u00e4re die Schnittstelle zwischen der App oder jeglicher anderer webangebundener Software grunds\u00e4tzlich umgesetzt. Weitere Funktionen k\u00f6nnen nat\u00fcrlich hinzugef\u00fcgt werden, was aber aufgrund der einfachen und simplen Struktur von Spring Boot kein Problem darstellen sollte.<\/p>\n<p><strong>Ausf\u00fchren auf dem Raspberry Pi<\/strong><\/p>\n<p>Ein Problem welches aber noch besprochen werden sollte, ist die Ausf\u00fchrung der Software auf dem Raspberry Pi. Generell geschieht dies wie in der Projektbeschreibung schon erl\u00e4utert \u00fcber die Java Virtual Machine(JVM). Aus dem Projekt wird eine Jar gebaut, die mithilfe der Overlays in Buildroot intigriert wird. In der Inittab wird diese dann hineingeschrieben, sodass sie bei jedem Neustart das Alarmsystem und der Webserver auch gestartet werden. Jedoch muss f\u00fcr den Webserver wie im oberen Abschnitt beschrieben auch Redis laufen. Zum Gl\u00fcck hat Buildroot einen Redis-Server eingebaut, der lediglich in der Konfiguration eingebaut ist. Sobald dieser hinzugef\u00fcgt wird und ebenfalls in der Inittab gestartet wird, hat Spring Boot darauf Zugriff und kann die Sessions aufbauen.<\/p>\n<p>Ein allerletztes Problem besteht jedoch leider noch. Beim ausf\u00fchren der Komponente mit der UART Schnittstelle wird nach kurzer Zeit ein CoreDump von der JVM geschmissen. Um dem genauer auf den Grund zu gehen haben wir eine Jar gebaut, die lediglich Testdaten \u00fcber die UART-Schnittstelle schreibt und gleichzeitig auch wieder liest. Dabei sind wir zu dem Ergebnis gekommen, dass der Fehler auftritt, wenn die Verbindung kurzfristig unterbrochen wird und es dem Programm nicht m\u00f6glich ist, auf die Schnittstelle zu schreiben. Wie dieser Fehler in Verbindung mit der Funk-Hardware auftritt oder ob dies ein softwareseitig zu l\u00f6sen ist, ist uns aktuell jedoch nicht bekannt. Sofern dieser Bug aber behoben wird, ist das Projekt grundlegend umgesetzt und es m\u00fcsste nur noch ein Feinschliff vorgenommen werden.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Webserver In unseren letzten Blogbeitr\u00e4gen haben wir erl\u00e4utert wie die Hardware und die Software des eigentlichen Alarmsystems funktioniert. Da diese Komponenten mithilfe einer App steuerbar sein sollen, muss eine entsprechende Schnittstelle geschaffen werden. Daf\u00fcr soll ein Webserver eingesetzt werden, da<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[2],"tags":[],"_links":{"self":[{"href":"http:\/\/www.iot-embedded.de\/iot-2017\/wp-json\/wp\/v2\/posts\/393"}],"collection":[{"href":"http:\/\/www.iot-embedded.de\/iot-2017\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.iot-embedded.de\/iot-2017\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.iot-embedded.de\/iot-2017\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"http:\/\/www.iot-embedded.de\/iot-2017\/wp-json\/wp\/v2\/comments?post=393"}],"version-history":[{"count":1,"href":"http:\/\/www.iot-embedded.de\/iot-2017\/wp-json\/wp\/v2\/posts\/393\/revisions"}],"predecessor-version":[{"id":570,"href":"http:\/\/www.iot-embedded.de\/iot-2017\/wp-json\/wp\/v2\/posts\/393\/revisions\/570"}],"wp:attachment":[{"href":"http:\/\/www.iot-embedded.de\/iot-2017\/wp-json\/wp\/v2\/media?parent=393"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.iot-embedded.de\/iot-2017\/wp-json\/wp\/v2\/categories?post=393"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.iot-embedded.de\/iot-2017\/wp-json\/wp\/v2\/tags?post=393"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}