Experimentation - Soley02/IoTBarcodeHHZ GitHub Wiki

Minimum Viable Product

Für die konkrete Realisierung im Rahmen des Hackathons wurde als Minimum Viable Product (MVP) folgender Inhalt gewählt:

Es soll demonstriert werden, dass

  • die Kommunikation zwischen einer Kassenanwendung und einer App zur Einkaufslistenverwaltung realisiert werden kann,
  • die digitale Einkaufsliste automatisch aktualisiert werden kann und
  • Nutzer per Barcode identifiziert werden können.

Hierbei wurde auf die bestehende App Wunderlist zurückgegriffen, da diese bereits die Möglichkeit zur Verwaltung von Einkaufslisten bietet und damit nicht neu entwickelt werden muss. Gleiches gilt für die Erstellung von Barcodes, für das auf bestehende Anwendungen zurückgegriffen wurde. Der Fokus wurde wie beschrieben gewählt, um einen Prototypen zu erstellen, der die Grundfunktionalitäten darstellt und die Basis für weitere Entwicklungen bildet.

Die folgende Abbildung zeigt den Aufbau des MVP: Architektur des MVP

Über die Bilderkennung der USB-Webcam werden sowohl die eingekauften Produkte, als auch die Nutzerkarte des Anwenders eingescannt und über den jeweils vorhandenen Barcode identifizert. Diese Daten werden in der Kassenanwendung verarbeitet und über das Internet per HTTPS an die Rest-API der Wunderlist-App übertragen. Die REST-Interaktionen sind zustandslos und die Anfragen enthalten alle Informationen, da keine Zwischeninformationen gespeichert werden. Dort findet dann der Abgleich mit der verknüpften Einkaufsliste statt, die daraufhin aktualisiert wird und den Anwender informiert.

Der Nachrichtenaustausch im MVP basiert auf einem Push/Pull Konzept. Beim Push wird der Nachrichtenaustausch initiiert und zum Sender übertragen. Auf der anderen Seite ist Pull die Anfrage für eine Information. Die Kassenanwendung fordert per Pull-Anfrage Daten (zum Beispiel für die Einkaufsliste und User-Informationen) von der Wunderlist-App an und per Push können die Einkaufsinformationen an die Wunderlist-App gesendet werden. Der Datentransport findet in zufälligen Intervallen statt, nachdem sich der Nutzer an der Kasse authentifiziert hat und der smarte Checkout durchgeführt wurde.

Architekturmodell

Die folgende Abbildung zeigt das Architekturmodell nach Elgar Fleisch et al., das die Aufteilung des MVP in die verschiedenen Architektur-Layer darstellt. Dieses wurde verwendet, da der komplette IoT-Stack anhand dieser Architektur verständlich abgebildet werden kann. Anhand der Abbildung wird darüber hinaus deutlich, dass IoT mehr als eine Telemetrie-Applikation ist und zusätzliche Hintergrund-Services bietet.

Architekturmodell

Technische Implementierung

Verwendete Hardware

  • Controller: Raspberry Pi 3 mit Ubuntu 16.04
  • Sensor: USB-Webcam Logitech C525
  • Eingabegeräte: USB-Tastatur und USB-Maus
  • Monitor mit HDMI-Anschluss

Netzwerk

In der folgenden Grafik wird dargestellt, auf welche bestehenden Protokolle und Standards im Zusammenhang mit dem Netzwerk zurückgegriffen wird. Netzwerk

Die Synchronisation zwischen Smartphone und dem Kassesystem erfolgt mit einem Webserver per TCP/IP, der in das Smart Object "Kasse" integriert ist. Das Smartphone bzw. die Kassenanwendung kann über verschiedene Lower Layer angeschlossen sein. Im MVP ist das Smartphone mit dem Wi-Fi verbunden und die Kassenanwendung per Ethernet an das Internet angeschlossen.

Zwischen Smartphone und USB-Webcam besteht eine Point-to-Point Verbindung, die ad-hoc aufgebaut wird, sobald ein Barcode zur Identifikation vor die Kamera gehalten wird. Zwischen Kamera und Kassensystem (und den daran anknüpfenden Systemen) liegt eine ständig aufgebaute Netzwerkinfrastruktur vor.

MEAN-Stack

Der MEAN-Stack ist ein kostenloses Open-Source-Softwarebündel, um dynamische Webseiten und Webapplikationen auf der Basis der Programmiersprache JavaScript zu entwickeln. Das Softwarebündel ist eine Zusammenstellung von verschiedenen Technologien und beschleunigt beispielsweise durch die geräteübergreifende Kompatibilität die Entwicklung von Webapplikationen. Aus diesem Grund ist das Bündel für die Entwicklung zeitkritischer Applikationen im Rahmen eines Hackathons sehr geeignet. Das Akronym MEAN repräsentiert folgende Frameworks:

  • MongoDB: Dokumentenbasiertes NoSQL-Datenbanksystem
  • Express: Serverseitiges Web-Framework
  • AngularJS: Clientseitiges Web-Framework
  • Node.js: Serverlaufzeitumgebung

Das entwickelte Frontend besteht aus Vereinfachungsgründen zum größten Teil aus HTML-, CSS-, and Javascript-Komponenten, da eine Einarbeitung in AngularJS, als clientseitiges Web-Framework, bisher noch nicht erfolgte.

Grundgerüst der Web-Applikation

Das Grundgerüst der entwickelten Web-Applikation basiert auf einem rudimentären MEAN-Beispiel zum Login und Registrieren. Der Programmcode für das verwendete Beispiel ist im dazugehörigen Github Repository abrufbar und unterliegt der MIT Lizenz, womit der Code kostenlos sowie ohne Einschränkung weiterverwendet werden kann. Für die Zwecke des Hackathons wurde das Frontend des MEAN-Beispiels entsprechend angepasst, vor allem unter dem Verzeichnis /smartApp/app/home. Die Beispielapplikation besitzt eine Model-View-Controller-Architektur und baut direkt auf dem MEAN-Stack auf. Das Beispiel dient als Grundgerüst und bietet bereits eine grafische Benutzeroberfläche sowie ein funktionierendes Backend. Für die Nutzung der Applikation wird eine lokale MongoDB-Instanz benötigt, um den Login zu ermöglichen. Für den Zweck des Hackathons spielt die Login- und Register-Funktion keine funktionale Rolle, ist allerdings dennoch Bestandteil der Applikation.

Grafische Benutzeroberfläche

Die grafische Benutzeroberfläche besteht aus folgenden Seiten:

  • Login: Dient, durch die Angabe eines Usernamens und Passwords, zum Einloggen eines bestehenden Benutzers in die Web-Applikation.

  • Registrierung: Dient zum Registrieren eines neuen Benutzers durch die Angabe von First Name, Last Name, Username und Password.

  • Home: Stellt die grafische Oberfläche der Kasse dar und besteht aus folgenden Komponenten:

    • Einer Liste zur Darstellung der Artikel im Warenkorb
    • Die Summe der Preise für die Artikel im Warenkorb
    • Einem Container für die Integration des Barcode-Scanners
    • Ein Nummernblock für die Eingabe von Werten (aktuell keine Funktion)
    • Die Leiste für den Abruf von Kassenfunktionen

  • Account: Ermöglicht das Abändern der Nutzerdaten durch die Anpassung dieser.

Barcodes

Barcode sind maschinenlesbare Codes in Form von Zahlen oder der Struktur von Linien, die für die Identifizierung von Produkten verwendet werden. Barcode-Systeme unterstützen die Nachverfolgung von Produkten und können somit zu einer Steigerung der Produktivität und Effizienz beitragen. Supermärkte nutzen Barcode-Scanner, um die Erkennung der Produkte zu beschleunigen.

Es gibt unterschiedliche Arten von Barcodes, die für verschiedene Anwendungsfelder entwickelt wurden. Der Barcode ist in der ISO Norm ISO/IEC 15420 festgelegt. Für den Handel ist unter anderem der Type EAN-8 üblich, der auch für das MVP im Rahmen des Hackathons benutzt wird. EAN-8 besitzt bei einem Zeichenvorrat 0-9 insgesamt acht Stellen, wobei die letzte Stelle eine Prüfziffer darstellt.

Für die Erstellung der Barcodes wird ein Online-Generator verwendet, bei dem unter der Angabe des Barcodetyps und numerischer Werte ein eindeutiger Barcode generiert wird, der als Download heruntergeladen werden kann.

Barcode-Scanner-Software

Für die Erkennung der Barcodes wird die Barcode-Scanner-Software QuaggaJS verwendet. Es handelt sich dabei um eine in JavaScript geschriebenen Echtzeiterkennung von verschiedenen Barcode-Arten. Die Software kann problemlos als JavaScript-Bibliothek in MEAN-basierte Projekte integriert werden und befindet sich im Programmcode unter dem Pfad /smartApp/home/quaggaJS.

QuaggaJS kann direkt auf den Stream von Webcams zugreifen und eignet sich besonders durch die Robustheit gegen Rotation und Bewegungen zur Verarbeitung von Barcodes. Die Einbindung der Funktionalitäten von QuaggaJS in den Programmcode erfolgte durch die Integration von quagga.min.js als Skript in der Datei /smartApp/app/home/index.html:

<script src="./home/quaggaJS/dist/quagga.min.js"></script>

Wunderlist API

Wunderlist ist eine von Microsoft angebotene mobile Web-Applikation zur Verwaltung von Aufgaben und Notizen. Die Applikation verfügt über eine REST-API, die Entwicklern die Möglichkeit bietet, programmatischen Zugang zu Funktionalitäten von Wunderlist zu erhalten und diese in andere Applikationen zu integrieren.

Folgende Routen der REST-API von Wunderlist, die im Programmcode in der Datei /smartApp/server.js enthalten sind, wurden zur Ansteuerung der Wunderlist-Applikation verwendet:

  • GET a.wunderlist.com/api/v1/user - Informationen über den aktuell angemeldeten Nutzer
  • GET a.wunderlist.com/api/v1/tasks - Informationen über die Tasks einer Liste
  • POST a.wunderlist.com/api/v1/tasks - Erstellung eines Tasks
  • POST a.wunderlist.com/api/v1/subtasks - Erstellung eines Subtasks
  • GET a.wunderlist.com/api/v1/tasks/:id - Informationen über einen Task
  • PATCH a.wunderlist.com/api/v1/tasks/:id - Bearbeitung von Task-Eigenschaften
  • POST a.wunderlist.com/api/v1/reminders - Erstellung eines Reminders
  • POST a.wunderlist.com/api/v1/notes - Erstellung einer Notiz

Genaue Beschreibungen der erforderlichen Parameter, Header und HTTPS-Methoden sind der Entwicklerdokumentation von Wunderlist zu entnehmen. Ein Beispiel aus dem Programmcode zum Abhaken von Tasks in der Wunderlist-App ist der folgenden Methode app.post zu entnehmen. Unter der Angabe Authentifizierungsinformationen (id & token) kann der Task mit der Identifizierung taskid sowie der Revision revision abgehakt werden. Die HTTPS-Methode für das Abhaken von bestehenden Tasks in der Wunderlist-App lautet PATCH. Die Optionen des HTTPS-Requests können dem Datensatz options und die Parameter dem Datensatz postData entnommen werden.

app.post('/completeTasks/:id/:token/:taskid/:revision', function(req, res){
        var id = req.params.id;
        var token = req.params.token;
        var taskid = req.params.taskid;
        var revision = req.params.revision;

        console.log(id+" "+token+" "+taskid+" "+revision);

        var postData = JSON.stringify({ 
            'revision' : parseInt(revision),
            'completed' : true
        }); 

        console.log(postData);

        var http = require("https");

        var options = {
        "method": "PATCH",
        "hostname": "a.wunderlist.com",
        "port": null,
        "path": '/api/v1/tasks/'+taskid, 
        "headers": { 
            'X-Client-ID': id,
            'X-Access-Token': token,
            'Content-Type':'application/json'
            } 
        };

        var req1 = http.request(options, function (res1) {
        var chunks = [];

        res1.on("data", function (chunk) {
            chunks.push(chunk);
        });

        res1.on("end", function () {
            var body = Buffer.concat(chunks);
            console.log(body.toString());
            res.send(body.toString());
        });
        });

        req1.write(postData);

        req1.end();

});

Datensätze der Barcodes

Im Programmcode fungiert die Datei /smartApp/app/home/index.controller.js als Controller für zahlreiche Funktionalitäten und enthält darüber hinaus die Datensätze, die als Datenbank für die Speicherung der Informationen von Waren und Nutzern dienen. Die Speicherung dieser Informationen im Programmcode ist lediglich eine Vereinfachung im Rahmen des Hackathons, da auf diese Daten bereits zur Laufzeit zugegriffen werden kann. Programmatisch werden die erkannten Identifier aus den Barcodes verwendet, um die Datensätze zu identifizieren. Im Konkreten handelt es sich um folgende Datensätze:

  • Items: Enthält die Datensätze, die repräsentativ als digitales Abbild der Waren fungieren. Das Format der Datensätze beinhaltet die Barcode-ID, die Bezeichnung des Items, eine Beschreibung, einen Preis und die Anzahl der Items im aktuellen Warenkorb.

    // [ Barcode-ID, Item, Description, Price, Number]
    var items = [
      [ "00000017", "Nudeln", "DescriptionNudeln", "1.99", "0"],
      [ "00000024", "Eier", "DescriptionEier", "3.49", "0"],
      [ "00000031", "Eis", "DescriptionEis", "0.50", "0"],
      [ "00000048", "Bier", "DescriptionBier", "6.91", "0"],
      [ "00000079", "Chips", "DescriptionChips", "2.49", "0"],
      [ "00000062", "Zeitung", "DescriptionZeitung", "0.99", "0"],
      [ "00000055", "Orangensaft", "DescriptionOrangensaft", "1.49", "0"]        
    ];
  • Users: Diese Datensätze enthalten die Authentifizierungsdaten der Einkauflisten-Nutzer, die für die Schnittstelle einer smarten Einkauflisten-App genutzt werden.

    //[Barcode, Client-ID, Wunderlist-Token, Wunderlist-List-ID, isCurrentUser, Wunderlist-History-List-ID]
    var users = [
      [ "90311017","588538a81d23d9275ed7", "3d11ca29b52057ec511cf487c84ee4e655f5d829083ed8ddc17cdc925000", "353993604","0","353993625"],
      [ "00000086","c6cbc57bcc2adfe80be4", "af9b424386d056070502f4a88b266f4c92d2a6d5d4eed4affec5ec50981b", "353992302","0","353992384"]
    ];

Visualisierter MVP Prozess

Der smarte Checkout Prozess des MVP kann der folgenden Präsentation entnommen werden: Visualisierter MVP Prozess.pptx. Die Präsentation enthält die einzelnen Schritte als Bildschirmaufnahmen, die bei der Demonstration des MVPs durchgeführt wurden.

Installationsbeschreibung

Aufbau und Installation des Raspberry Pi 3

Für den Prototypen wurde ein Raspberry Pi 3 gewählt, da dieser als vollständiger PC verwendet und direkt darauf entwickelt und getestet werden kann. Außerdem sind die entsprechenden Anschlüsse (USB, HDMI, Ethernet) vorhanden, um die erforderliche Peripherie anzuschließen und eine stabile Netzwerkverbindung herzustellen.

Der Raspberry Pi wurde gemäß der, in der Verpackung beiliegenden, Anleitung zusammengebaut und eine USB-Maus und USB-Tastatur angeschlossen. Per HDMI-Kabel wurde ein Bildschirm angeschlossen und ein LAN-Kabel eingesteckt.

Im nächsten Schritt wurde eine microSD-Karte mit Hilfe eines Laptops vorbereitet. Diese wurde zuerst mit der Anwendung "SD Formatter 5.0 for SD/SDHC/SDXC Tool" formatiert, damit sie beschreibbar wird. Gemäß einer weiteren Anleitung wurde das Betriebssystem-Image (Ubuntu 16.04) heruntergeladen und auf die microSD-Karte überspielt, da dieses besonders für die Webcam und die beabsichtigte Anwendungssoftware geeignet ist. Daraufhin wurde die microSD-Karte in den Raspberry Pi gesteckt, der Micro-USB-Netzadapter angeschlossen, woraufhin der Raspberry Pi startete. Die damit angestoßene Ubuntu-Installation wurde von Ubuntu selbst ausgeführt, bevor manuell die Sprache, das Tastaturlayout etc. eingestellt und ein Benutzerkonto (Benutzername: iot, Passwort: Tobias1415) angelegt wurde.

Aufbau Raspberry Pi 3

Installation der Node.js und MongoDB

Für den vorliegenden Prototypen wurde auf die bereits vorinstallierten Versionen von Node.js und der MongoDB zurückgegriffen. Die Funktionsfähigkeit wurde mit einem Testaufbau überprüft. Die Begründung für die Wahl dieser beiden Komponenten wird in der Technischen Implementierung beschrieben.

Installation der USB-Webcam

Nun wurde eine USB-Webcam (Logitech C525) angeschlossen, die direkt funktionsfähig war. Dies wurde mit einer Webcam Application geprüft. Diese Kamera wurde ausgewählt, da sie ohne zusätzliche Stromversorgung auskommt und Full HD als Auflösung bietet. Zur Konfigurierung der Webcam wurde die Kontrollapplikation Gtk-v4l verwendet, um die Auflösung und Bildwechselfrequenz auf die Rechenleistung des Raspberry Pis anzupassen.

Aufbau USB-Webcam

Installation eines Browsers

Für die Ausführung der web-basierten Kassenanwendung ist ein Browser notwendig. Hierfür wurde eine aktuelle Version von Chromium installiert, da sich dieser Browser am besten für den Raspberry Pi eignet. Im Rahmen des Hackathons wurden auch andere Browser getestet (beispielsweise Firefox-ESR, Midori, LuaKit), die sich jedoch aufgrund von Problemen bei der Webcam-Integration oder der Performanz nicht geeignet haben.

Kassensystem_Browser

Ausführung der Web-Applikation

Die Ausführung der entwickelten Kassenanwendung besteht aus zwei Einzelschritten. Der erste Schritt ist das Starten eines lokalen MongoDB-Servers auf dem Standard-Port 27017, der zur Speicherung der Nutzerdaten dient. Zum Starten muss der folgende Befehl über die Kommandozeile ausgeführt werden.

sudo service mongod start

Der zweite Schritt umfasst die Ausführung des lokalen Node.js-Webservers zur Bereitstellung des Front- und Backends der Web-Applikation. Zum Starten des Webservers dient das folgende Kommando, das über die Kommandozeile im Pfad /smartApp ausgeführt wird.

node server.js

Sind die beiden Schritte erfolgreich, kann unter Angabe folgender URL die grafische Benutzerschnittstelle in einem Browser geöffnet werden.

http://localhost:3000/
⚠️ **GitHub.com Fallback** ⚠️