{"id":579,"date":"2018-07-02T11:37:22","date_gmt":"2018-07-02T11:37:22","guid":{"rendered":"https:\/\/www.wpvs.de\/iot-2018\/?p=579"},"modified":"2021-05-14T10:07:03","modified_gmt":"2021-05-14T08:07:03","slug":"raspberrybuy-8-projektende-deployment","status":"publish","type":"post","link":"https:\/\/www.iot-embedded.de\/iot-2018\/projekt-raspberrybuy\/raspberrybuy-8-projektende-deployment\/","title":{"rendered":"RaspberryBuy (8) &#8211; Projektende &amp; Deployment"},"content":{"rendered":"<h1>Fertigstellung der Webanwendung<\/h1>\n<p><span class=\"TextRun SCXW17674149\" lang=\"DE-DE\" xml:lang=\"DE-DE\"><span class=\"NormalTextRun SCXW17674149\">Gem\u00e4\u00df der Ank\u00fcndigung im f\u00fcnften Blockbeitrag bietet die We<\/span><\/span><span class=\"TextRun SCXW17674149\" lang=\"DE-DE\" xml:lang=\"DE-DE\"><span class=\"NormalTextRun SCXW17674149\">boberfl\u00e4che nun die M\u00f6glichkeit\u00a0<\/span><\/span><span class=\"TextRun SCXW17674149\" lang=\"DE-DE\" xml:lang=\"DE-DE\"><span class=\"NormalTextRun SCXW17674149\">f\u00fcr einen oder mehrere selek<\/span><\/span><span class=\"TextRun SCXW17674149\" lang=\"DE-DE\" xml:lang=\"DE-DE\"><span class=\"NormalTextRun SCXW17674149\">tierte Benutzer den K\u00fchlschrankinhalt<\/span><\/span><span class=\"TextRun SCXW17674149\" lang=\"DE-DE\" xml:lang=\"DE-DE\"><span class=\"NormalTextRun SCXW17674149\">\u00a0<\/span><\/span><span class=\"TextRun SCXW17674149\" lang=\"DE-DE\" xml:lang=\"DE-DE\"><span class=\"NormalTextRun SCXW17674149\">anzuzeigen. Weiterhin ist es auch m\u00f6glich den\u00a0<\/span><\/span><span class=\"TextRun SCXW17674149\" lang=\"DE-DE\" xml:lang=\"DE-DE\"><span class=\"NormalTextRun SCXW17674149\">gesamten K\u00fchlschrankinhalt eines Ha<\/span><\/span><span class=\"TextRun SCXW17674149\" lang=\"DE-DE\" xml:lang=\"DE-DE\"><span class=\"NormalTextRun SCXW17674149\">ushalts anzuzeigen. Zur Steigerung der \u00dcbersichtlichkeit wird in der Standardansicht der K\u00fchlschrankinhalt geb\u00fcndelt nach Produkt angezeigt<\/span><\/span><span class=\"TextRun SCXW17674149\" lang=\"DE-DE\" xml:lang=\"DE-DE\"><span class=\"NormalTextRun SCXW17674149\">. Erst bei Klicken des jeweiligen<\/span><\/span><span class=\"TextRun SCXW17674149\" lang=\"DE-DE\" xml:lang=\"DE-DE\"><span class=\"NormalTextRun SCXW17674149\">\u00a0Produkte<\/span><\/span><span class=\"TextRun SCXW17674149\" lang=\"DE-DE\" xml:lang=\"DE-DE\"><span class=\"NormalTextRun SCXW17674149\">s<\/span><\/span><span class=\"TextRun SCXW17674149\" lang=\"DE-DE\" xml:lang=\"DE-DE\"><span class=\"NormalTextRun SCXW17674149\">\u00a0werden die zugeh\u00f6rigen Best\u00e4nde ausgeklappt und k\u00f6nnen anschlie\u00dfend wieder eingeklappt werden. Der Einsatz einer Bibliothek f\u00fcr diese sogenannte \u201e<\/span><span class=\"SpellingError SCXW17674149\">Tree<\/span><span class=\"NormalTextRun SCXW17674149\">\u00a0<\/span><span class=\"SpellingError SCXW17674149\">Structure<\/span><span class=\"NormalTextRun SCXW17674149\">\u201c war nicht m\u00f6glich, da der Server die Produkte gefiltert nach Pro<\/span><\/span><span class=\"TextRun SCXW17674149\" lang=\"DE-DE\" xml:lang=\"DE-DE\"><span class=\"NormalTextRun SCXW17674149\">fil-<\/span><\/span><span class=\"TextRun SCXW17674149\" lang=\"DE-DE\" xml:lang=\"DE-DE\"><span class=\"NormalTextRun SCXW17674149\">ID zur\u00fcckgibt und vorher die Serverantwort entsprechend der Produkte sortiert werden muss. Dies erfolgt<\/span><\/span><span class=\"TextRun SCXW17674149\" lang=\"DE-DE\" xml:lang=\"DE-DE\"><span class=\"NormalTextRun SCXW17674149\">\u00a0bei der Tabellenerzeugung<\/span><\/span><span class=\"TextRun SCXW17674149\" lang=\"DE-DE\" xml:lang=\"DE-DE\"><span class=\"NormalTextRun SCXW17674149\">, indem\u00a0<\/span><\/span><span class=\"TextRun SCXW17674149\" lang=\"DE-DE\" xml:lang=\"DE-DE\"><span class=\"NormalTextRun SCXW17674149\">bei erstmaligem Auftreten einer neuen Produkt-ID der Produktname in der Tabelle gelistet wird und zugeh\u00f6rige Best\u00e4nde diese Produkt-ID als Attributwert erhalten. Ist die Produkt-ID in der Tabelle bereits vorhanden, wird die letzte Zeile zur\u00fcckgegeben, die diese ID als Eltern-Attributwert enth\u00e4lt<\/span><\/span><span class=\"TextRun SCXW17674149\" lang=\"DE-DE\" xml:lang=\"DE-DE\"><span class=\"NormalTextRun SCXW17674149\">. Die\u00a0<\/span><\/span><span class=\"TextRun SCXW17674149\" lang=\"DE-DE\" xml:lang=\"DE-DE\"><span class=\"NormalTextRun SCXW17674149\">nachfolgende Abbildun<\/span><\/span><span class=\"TextRun SCXW17674149\" lang=\"DE-DE\" xml:lang=\"DE-DE\"><span class=\"NormalTextRun SCXW17674149\">g zeigt den<\/span><\/span><span class=\"TextRun SCXW17674149\" lang=\"DE-DE\" xml:lang=\"DE-DE\"><span class=\"NormalTextRun SCXW17674149\">\u00a0<\/span><\/span><span class=\"TextRun SCXW17674149\" lang=\"DE-DE\" xml:lang=\"DE-DE\"><span class=\"NormalTextRun SCXW17674149\">zugeh\u00f6rigen Befehl<\/span><\/span><span class=\"TextRun SCXW17674149\" lang=\"DE-DE\" xml:lang=\"DE-DE\"><span class=\"NormalTextRun SCXW17674149\">.<\/span><\/span><span class=\"EOP SCXW17674149\">\u00a0<\/span><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-590\" src=\"http:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/code1-300x21.png\" alt=\"\" width=\"500\" height=\"35\" srcset=\"https:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/code1-300x21.png 300w, https:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/code1.png 566w\" sizes=\"(max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>An das zur\u00fcckgegebene Zeilenelement wird der Bestandswert als weitere Zeile angef\u00fcgt und in diesem die vorher definierte Nummer des Eltern-Elements gespeichert. Die Ein- und Ausklappfunktionalit\u00e4t wird durch die unten dargestellte toggleClass von Jquery realisiert, die eine CSS-Klasse mit den Sichtbarkeitseinstellungen entweder hinzuf\u00fcgt oder entfernt.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-589\" src=\"http:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/code2-300x36.png\" alt=\"\" width=\"442\" height=\"53\" srcset=\"https:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/code2-300x36.png 300w, https:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/code2.png 457w\" sizes=\"(max-width: 442px) 100vw, 442px\" \/><\/p>\n<p>Anhand der Nummer des Eltern-Elements kann bestimmt werden, welche Best\u00e4nde sichtbar oder unsichtbar gemacht werden sollen.<\/p>\n<p>Des Weiteren ist die Anlage, Bearbeitung oder L\u00f6schung (Bestandswert wird auf 0 gesetzt) von Bestandsdaten sowie Produktdaten auf Zeilenebene m\u00f6glich.<\/p>\n<p>&nbsp;<\/p>\n<h1>Fertigstellung der Pi-Anwendung<\/h1>\n<p>Als die Oberfl\u00e4che des\u00a0RaspberryBuy\u00a0fertig erstellt war, ging es um die eigentliche Implementierung auf dem Touchscreen, der uns netterweise von Herr Schulmeister ausgeliehen wurde. Im weiterem Verlauf mussten wir feststellen, dass der Browser\u00a0qt-Webkit-kiosk auf unserem Raspberry Pi nicht dazu in der Lage war die erstellten Elemente korrekt darzustellen.<\/p>\n<p>Der Browser implementiert nicht den ES6-Standard (ECMAScript), sodass\u00a0jeglicher\u00a0Javascript-Code mithilfe des\u00a0Transpilers\u00a0\u201eBabel\u201c transpiliert werden musste. Babel erzeugt auch JavaScript Code (weshalb man hier nicht von einem Kompiler reden kann), dieser ist jedoch ES5 kompatibel. Es zeigte sich jedoch, dass\u00a0jQuery\u00a0ebenfalls vom Browser nicht korrekt eingebunden wird.\u00a0Dementsprechend war es notwendig, zus\u00e4tzlich verschiedene\u00a0Polyfills\u00a0einzubinden. Somit musste beispielsweise ein Promises-Polyfill\u00a0genutzt werden. Auch Babel selbst hat weitere Polyfills ben\u00f6tigt.<\/p>\n<p>Leider musste ebenfalls der Switch-Toggle-Button innerhalb der Anwendung ersetzt werden, da dieser aufgrund des etwas zu kleinen Bildschirms st\u00e4ndig verrutscht ist. Stattdessen wurde ein Bootstrap Toggle Button verwendet, der au\u00dferdem besser zum Design und der Bedienung auf dem kleinen Touchscreen passt.<\/p>\n<p><a href=\"http:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/IMG_20180702_122159.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-586 size-medium\" src=\"http:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/IMG_20180702_122159-300x225.jpg\" alt=\"\" width=\"300\" height=\"225\" srcset=\"https:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/IMG_20180702_122159-300x225.jpg 300w, https:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/IMG_20180702_122159-1024x768.jpg 1024w, https:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/IMG_20180702_122159-768x576.jpg 768w, https:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/IMG_20180702_122159-1536x1152.jpg 1536w, https:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/IMG_20180702_122159-2048x1536.jpg 2048w, https:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/IMG_20180702_122159-1568x1176.jpg 1568w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a> <a href=\"http:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/IMG_20180702_122156.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-585 size-medium\" src=\"http:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/IMG_20180702_122156-300x225.jpg\" alt=\"\" width=\"300\" height=\"225\" srcset=\"https:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/IMG_20180702_122156-300x225.jpg 300w, https:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/IMG_20180702_122156-1024x768.jpg 1024w, https:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/IMG_20180702_122156-768x576.jpg 768w, https:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/IMG_20180702_122156-1536x1152.jpg 1536w, https:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/IMG_20180702_122156-2048x1536.jpg 2048w, https:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/IMG_20180702_122156-1568x1176.jpg 1568w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h1>Deployment<\/h1>\n<p>Auf unserem AWS-Cloud Server sollen die folgenden beiden Komponenten deployed werden:<\/p>\n<ul>\n<li>Server: Der Server soll auf alle g\u00fcltigen Requests antworten, die mit \/api beginnen<\/li>\n<li>Webapp: Die statischen Dateien des Webclients sollen in den Pfad \/raspberrybuy eingebunden werden<\/li>\n<\/ul>\n<p><a href=\"https:\/\/nginx.org\/\">Nginx<\/a> ist ein Open Source Web Server, der auch Reverse Proxy Funktionalit\u00e4ten unterst\u00fctzt. Ein Proxy Server nimmt Anfragen von mehreren Clients entgegen und leitet sie in ein externes Netz (meist das Internet) weiter. Im Gegensatz dazu nimmt ein Reverse Proxy eine Anfrage eines Clients entgegen und leitet diese an einen oder mehrere interne Server zur Bearbeitung weiter. Die Konfiguration findet dabei \u00fcber den HTTP-Pfad statt. Im Folgenden ist die f\u00fcr die oben genannten Anforderungen notwendige nginx Konfiuration zu sehen:<\/p>\n<blockquote><p>location \/api {<br \/>\nproxy_set_header X-Real-IP $remote_addr;<br \/>\nproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;<br \/>\nproxy_set_header Host $http_host;<br \/>\nproxy_set_header X-NginX-Proxy true;<br \/>\nproxy_set_header X-Forwarded-Proto $scheme;<br \/>\nproxy_set_header x-forwarded-proto $scheme;<\/p>\n<p>proxy_pass http:\/\/raspberrybuy.dynv6.net:8000;<br \/>\n}<\/p>\n<p>location \/raspberrybuy {<br \/>\nrewrite ^\/raspberrybuy(.*)$ $1 break;<br \/>\nroot \/opt\/raspibuy\/RaspiBuy-Client\/webapp\/;<br \/>\ntry_files $uri main.html =404;<br \/>\n}<\/p><\/blockquote>\n<p>Alle HTTP-Requests, deren Pfad mit<em> \/api<\/em> beginnen, werden an den Node-Server weitergeleitet, der auf Port 8000 h\u00f6rt. Damit dieser wei\u00df, dass der urspr\u00fcngliche Request sicher \u00fcber HTTPS transportiert wurde, m\u00fcssen entsprechende Header angeh\u00e4ngt werden. Wenn der Request mit <em>\/raspberrybuy<\/em> beginnt, wird der Pfad umgeschrieben und ein root-File-Verzeichnis gesetzt. In diesem Verzeichnis sucht nginx dann nach den statischen Dateien.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-583\" src=\"http:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/SCREEN0000-300x89.png\" alt=\"\" width=\"755\" height=\"224\" srcset=\"https:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/SCREEN0000-300x89.png 300w, https:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/SCREEN0000-768x229.png 768w, https:\/\/www.iot-embedded.de\/iot-2018\/wp-content\/uploads\/sites\/3\/2018\/07\/SCREEN0000.png 839w\" sizes=\"(max-width: 755px) 100vw, 755px\" \/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Fertigstellung der Webanwendung Gem\u00e4\u00df der Ank\u00fcndigung im f\u00fcnften Blockbeitrag bietet die Weboberfl\u00e4che nun die M\u00f6glichkeit\u00a0f\u00fcr einen oder mehrere selektierte Benutzer den K\u00fchlschrankinhalt\u00a0anzuzeigen. Weiterhin ist es auch m\u00f6glich den\u00a0gesamten K\u00fchlschrankinhalt eines Haushalts anzuzeigen. Zur Steigerung der \u00dcbersichtlichkeit wird in der Standardansicht<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[4],"tags":[],"_links":{"self":[{"href":"https:\/\/www.iot-embedded.de\/iot-2018\/wp-json\/wp\/v2\/posts\/579"}],"collection":[{"href":"https:\/\/www.iot-embedded.de\/iot-2018\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.iot-embedded.de\/iot-2018\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.iot-embedded.de\/iot-2018\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.iot-embedded.de\/iot-2018\/wp-json\/wp\/v2\/comments?post=579"}],"version-history":[{"count":1,"href":"https:\/\/www.iot-embedded.de\/iot-2018\/wp-json\/wp\/v2\/posts\/579\/revisions"}],"predecessor-version":[{"id":644,"href":"https:\/\/www.iot-embedded.de\/iot-2018\/wp-json\/wp\/v2\/posts\/579\/revisions\/644"}],"wp:attachment":[{"href":"https:\/\/www.iot-embedded.de\/iot-2018\/wp-json\/wp\/v2\/media?parent=579"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.iot-embedded.de\/iot-2018\/wp-json\/wp\/v2\/categories?post=579"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.iot-embedded.de\/iot-2018\/wp-json\/wp\/v2\/tags?post=579"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}