Internet der Dinge WS2015/ObservableCookieJar

Aus Verteilte Systeme - Wiki
Wechseln zu: Navigation, Suche
Jar.jpg


Einleitung

Kurzbeschreibung des Projektes

Im Rahmen des Projekts soll ein Gegenstand im Sinne eines Smart Objects intelligent und kommunikationsfähig gemacht werden. Diese Gruppe beschäftigt sich mit der Realisierung eines Prototypen einer eigenen Idee, die so in der Realwelt bislang noch nicht existiert. Die Idee ist ein Behälter, welcher das eigene Gewicht feststellen kann und somit in der Lage ist, seinen Besitzer zu informieren, falls sich an der Füllmenge des Gefäßes etwas geändert hat. Zum Beispiel könnte diese Benachrichtigung über den Kurznachrichtendienst Twitter realisiert werden. Weiterhin soll es dem Besitzer möglich sein, das aktuelle Gewicht mit einem Internetbrowser über das Internet abzufragen. Optionale Erweiterung: Um nicht nur über eine Entnahme informiert zu werden, sondern auch ein Beweisfoto dazu hat, könnte der Behälter mit einer Kamera ausgestattet werden, die bei Gewichtsveränderung des Gefäßes auslöst und ein Bild erstellt.

Erwartete Ergebnisse

  • E1 - Planung: Hardware und Aufbau des Dings
  • E2 - Analyse: Funktionsweise eines AD-Wandlers
  • E3 - Analyse: Evaluation eines geeigneten Microcontrollers
  • E4 - Analyse: Web-Technologie und Programmbibliotheken
  • E5 - Entwicklung der Software
  • E6 - Zusammenbau des Dings
  • E7 - Test der Implementierung
  • E8 - Funktionale und optische Ausgestaltung der Web-Oberfläche
  • E9 - Anbindung einer Kamera

Geplante Arbeitsschritte

  • E1 - Es ist eine geeignete Auswahl von Hardware zu bestimmen, was einiger Recherche bedarf. Darüber hinaus muss sich überlegt werden, wie die Einzelteile zusammengebaut werden können.
  • E2 - Wägezellen liefern in aller Regel ein analoges Signal, welcher zur weiteren Verarbeitung in einen digitalen Wert umgewandelt werden muss, sofern der ausgewählter Mikrocontroller nicht über einen eingebauten AD-Wandler verfügt. Da dieses Team über keine Hardware-nahe Kompetenzen verfügt, müssen diese erst angelesen werden um zu verstehen wie diese AD-Wandlung funktioniert.
  • E3 - Vor und Nachteile verschiedener Mikrocontroller müssen abgewogen werden um eine geeignete Wahl des zu verwendenden Mikrocontrollers zu treffen.
  • E4 - Die Möglichkeiten eine Web-Oberfläche zu implementieren sind vielfältig. Es sollte eine Technologie und ein Framework ausgewählt werden, welches sowohl leichtgewichtig ist, als auch eine schnelle und unkomplizierte implementierung zulässt. Selbiges gilt auch für andere Abhängigkeiten wie die Notifikation über Twitter oder Datenpersisitierung.
  • E5 - Es ist eine einfache und pragmatische Software zu entwickeln, die lediglich vorgesehene Funktionalitäten unterstützt. Es wird aufgrund der begrenzten Zeit bewusst auf viele der klassischen Prozesse und Prinzipien der Softwaretechnik verzichtet.
  • E6 - Nachdem die Einzelteile in E1 bestellt wurden und einige Zeit vergangen ist, muss das Ding zusammengebaut werden.
  • E7 - Die entwickelte Software ist auf das Ding aufzuspielen und auszuprobieren.
  • E8 - Soweit die restliche Zeit es erlaubt, kann die Web-Oberfläche, die bis hierhin lediglich über Grundfunktionalitäten verfügt, optisch ausgestaltet werden und zusätzliche Features implementieren.
  • E9 - Sollte weiterhin Zeit für die Arbeit an das Projekt vorhanden sein, wird eine Kamera eingebunden, die zusätzlich bei Ereignissen Fotos vom Auslöser schießt.

Hardware und Aufbau des Dings

Federkoerper.png

Wägezelle

Zur Messung des Gewichts wird eine Wägezelle benötigt, welche genau genug ist um die Entnahme einzelner kleiner Kekse sicher zu bestimmen. Diese Wägezelle wird ein sog. Doppelbiegebalken-Federkörper sein, welcher unter der Keksdose verbaut wird. Auf solchen Federkörpern sind Dehnungsmessstreifen platziert, welche je nach Dehnungsgrad unterschiedliche elektrische Widerstände aufweisen.

Verstärker und AD-Wandler

Schließt man die Wägezelle mit einer bestimmten Spannung an, lässt sich je nach Last eine Änderung der Restspannung beobachten. Da diese Änderung gering ist, wird ein Verstärker benötigt, der idealer weise eine Analog-Digital-Wandlung durchführt, damit ein Mikrocontroller leicht damit arbeiten kann. Zu diesem Zweck wäre ein HX711 Modul geeignet.

Aufbau

Der Federkörper wird unter der Keksdose verbaut werden. Um eine sachgemäße Verformung dieses Federkörpers zu ermöglichen, ist der Aufbau von elementarer Wichtigkeit. Der Federkörper ist ein Balken, dessen Verformung in der Mitte stattfindet. Daher muss ein Ende von unten befestigt und das andere Ende von oben befestigt sein, ohne dass der ganze Federkörper aufliegt. Die Mitte des Federkörpers muss wie auf der Abbildung rechts frei schweben. Durch diesen Aufbau entsteht zwischen Keksdosenboden und Untergrund ein Hohlraum in dem sich der Federkörper befindet. In diesem Hohlraum wird genügend Platz sein um das HX711 Modul und einen Mikrocontroller unterzubringen.

Funktionsweise des AD-Wandlers HX711

Die Funktionsweise des AD-Wandlers wurde dem Datenblatt entnommen. Demnach verstärkt er auf seinem ersten Kanal ein differentielles Signal von ±20mV oder ±40mV um den Faktor 64 oder 128 und bildet es auf den digitalen Wertebereich von vorzeichenlosen 24-Bit Ganzzahlen ab. Der Zweite Kanal hat einen festen Verstärkungsfaktor von 32 und verarbeitet ein differentielles Signal von ±80mV. Versorgt wird er mit einer Spannung von 2,6 ~ 5,5V und kann damit direkt durch einen Arduino oder Raspberry Pi betrieben werden. Die Serielle Schnittstelle besteht aus einem Input für einen Taktgeber und einem Output für die Messdaten.

Um eine Messung in Form einer 24-Bit Ganzzahl zu erhalten, wird die serielle Schnittstelle des HX711 angesteuert. Jedes Bit, angefangen mit dem höchstwertigsten, wird mithilfe einer Taktgabe an dem Serial-Clock-Input (SCK) abgerufen. Im Detail bedeutet das folgendes Vorgehen:

  1. Es wird am SCK-Pin Spannung angelegt
  2. Ein neues Daten-Bit kann vom Daten-Pin ausgelesen werden
  3. Die Spannung wird vom SCK-Pin genommen
  4. Zurück zu 1. bis alle 24 Bits ausgelesen wurden

Im direkten Anschluss werden 1-3 weitere Taktgaben durchgeführt, welche die nächste Messung konfigurieren:

  • 1 Takt = Die nächste Messung wird auf Kanal A gemacht mit einem Verstärkungsfaktor von 128
  • 2 Takte = Die nächste Messung wird auf Kanal B gemacht mit einem Verstärkungsfaktor von 32
  • 3 Takte = Die nächste Messung wird auf Kanal A gemacht mit einem Verstärkungsfaktor von 64

Ab dem 25. Takt besteht am Daten-Pin Spannung, um anzuzeigen, dass der HX711 noch nicht bereit ist für eine neue Messung. Sobald der Daten-Pin wieder ohne Spannung ist, können die 24 Bits einer neuen Messung abgerufen werden.

Jeder Zustand der Taktgebung, ob Spannung anliegt oder nicht, muss mindestens 0,2µs bestehen bleiben. Zudem darf die Spannungs-Phase maximal 50µs bestehen bleiben. Außerdem darf die ansteigende sowie fallende Flanke des Takts maximal 0,1µs dauern.

Analyse: Evaluation eines geeigneten Microcontrollers

Für das Bereitstellen der Gewichtsdaten über das Internet wird ein Mini-PC oder sogenannter Microcontroller benötigt. Es gibt eine Reihe an verschiedenen Modellen von verschiedenen Herstellen, die jeweils für andere Bedürfnisse optimiert sind. Der für dieses Projekt geeinigte Microcontroller muss über ein GPIO Board verfügen, an den die Keksdose später angeschlossen werden soll. Weiterhin muss er in der Lage sein, einen Webserver auf dem Gerät laufen zu lassen, das bedeutet automatisch, dass der Controller ebenfalls Anschlüsse für Ethernet oder aber auch WLan vorsieht, oder evtl. über Adapter ans Internet angebunden werden kann. Als mögliche Microcontroller wurden folgende Geräte untersucht und sich anschließend auf einen festgelegt:


Arduino

Der Arduino Controller ist ein hardwarenaher Microcontroller der auf einem Baukasten Prinzip basiert. Er wird meistens für die Sensordatenerfassung verwendet bietet aber darüber hinaus auch andere Features wie z.B. . Er bietet ebenfalls ein Steckerboard an das die Wägezelle angeschlossen werden kann. Um selbstgeschriebene Software auf dem Arduino auszuführen, muss diese sozusagen in die Firmware geflasht werden.


Ursprünglich sind die Arduino Boards nicht dafür ausgelegt ans Internet angeschlossen zu werden. Dies kann nur mit externen Komponenten und Chips erreicht werden, was für dieses Projekt einen erheblichen zusätzlichen Aufwand erfordern würde.

Arduino.jpg
Raspberry Pi

Das Raspberry Pi ist im Gegensatz zum Arduino ein sogeannter "Micro-Computer". Der größte Unterschied zum Arduino ist, dass der Pi ein eigenes Betriebssystem besitzt. Dieses Betriebssystem ist eine eigene Linux-Distribution (Raspbian Pi), welche somit auch das einfache Installieren von diverser Paket-Software komfortabel ermöglicht. Das Pi besitzt ebenfalls einen GPIO Port sowie auch verschiedene andere Anschlüsse (2x USB, 1x LAN, Firewire, HDMI). Ein weiterer entscheidender Vorteil ist die einfache Anbindung ans Internet. Entweder benutzt man den standardmäßig enthaltenen Ethernet Port, oder aber man holt sich einen externen WLan-USB-Stick über den man ebenso einfach auf das Internet zugreifen kann.

Rasp.jpg

Kalibrierung der Wägezelle

Nachdem der AD-Wandler in der Lage ist Werte zu liefern, welche das differentielle Signal der Wägezelle repräsentieren, gilt es herauszufinden, ob sich diese Werte tatsächlich linear zum tatsächlichen Gewicht verhalten. Sei dies der Fall, wird ein Umrechnungsfaktor benötigt, mit dem das Gewicht in Gramm berechnet werden kann.

Zur Lösung dieser beiden Probleme, wurde mithilfe von homogenen Testobjekten (Keksen), deren Gewicht bekannt ist, manuell kalibriert. Das Ergebnis wurde in der Tabelle rechts dokumentiert.

Spaltenlegende

  • Kekse
    • Anzahl der Kekse in der Keksdose
  • Inhalt (Gramm)
    • Kalkuliert, Keksanzahl * 9,5 (Einzelgewicht)
  • Messung (Rohwert)
    • Abgelesen bei tatsächlicher Messung
  • Inhalt (Rohwert)
    • Messung abzüglich Leergewicht (70700)
  • Einzelgewicht (Rohwert)
    • Kalkuliert, Inhalt(Rohwert) / Keksanzahl

An der letzten Spalte ist zu erkennen, dass die gelieferten Werte tatsächlich linear sind zum Gewicht. Darüber hinaus lässt sich der Umrechnungsfaktor durch das Einzelgewicht in Gramm und in Rohwerten berechnen:

Fehler beim Parsen (MathML mit SVG- oder PNG-Rückgriff (empfohlen für moderne Browser und Barrierefreiheitswerkzeuge): Ungültige Antwort („Math extension cannot connect to Restbase.“) von Server „https://en.wikipedia.org/api/rest_v1/“:): {\displaystyle 11680 / 9,5 ≈ 1230 Roheinheiten/Gramm}

Fehler beim Parsen (MathML mit SVG- oder PNG-Rückgriff (empfohlen für moderne Browser und Barrierefreiheitswerkzeuge): Ungültige Antwort („Math extension cannot connect to Restbase.“) von Server „https://en.wikipedia.org/api/rest_v1/“:): {\displaystyle 9,5 / 11680 ≈ 8,13*10^{-4} Gramm/Roheinheit}

Cookiejar calib.png

Analyse: Verwendete Web-Technologie und Programmbibliotheken

Für die Entwicklung der Softwarefunktionalität werden im weiteren Verlauf verschiedene Module und Bibliotheken benötigt. Es wurden eine Reihe an verschiedenen Bibliotheken untersucht und sich festgelegt. Da auf dem Raspberry Pi wie oben erwähnt ein Linux Betriebssystem läuft und durch die Umgebung auch Skriptsprachen ausgeführt werden können, wurde sich darauf geeinigt, die Programmiersprache Python für dieses Projekt zu verwenden.


Ansteuerung der Wägezelle

Gpio.jpg

Das Raspberry Pi wird auf die Wägezelle über den GPIO- (general purpose input/output) Port zugreifen. Dieser Port ist ein zusätzliches Features des Raspberry Pi's um den Anschluss von elektronischen, kompatiblen Geräten jeglicher Art zu erlauben. [1]. Da die Anwendung in der Programmiersprache Python geschrieben werden soll, wurde ein Modul benötigt, welches es erlaubt, auf den Port zuzugreifen. Für diese Aufgabe wurde das Python-Modul python-rpi.gpio benutzt. Dieses Modul bietet alle wichtigen Funktionen wie z.B. das Senden sowie das Lesen des GPIO-Ports. [2]

Das Auslesen des Ports in folgendem Programmausschnitt passiert analog, wie es in Kapitel Funktionsweise des AD-Wandlers erläutert wurde.

import time
import RPi.GPIO as GPIO

def read(self):
    while not self.isready():time.sleep(0.1)
    ret=""
    for _ in range(24):
        GPIO.output(self.CLK,1)
	ret+=str(GPIO.input(self.DATA))
	GPIO.output(self.CLK,0)

    #gain
    for _ in range(GAIN):
        GPIO.output(self.CLK,1)
	GPIO.output(self.CLK,0)
		
    #print(ret)	
    return int(ret, 2)-self.empty

Werkzeug WSGI Library

Das Python Web Server Gateway Interface (WSGI) ist eine Schnittstellen-Spezifikation, die eine Schnittstelle zwischen Webservern und Web Application Frameworks bzw. Web Application Servern festlegt, um die Portabilität von Webanwendungen auf unterschiedlichen Webservern zu fördern.[3]

Ein praktisches Toolkit für dieses Interface bietet die Werkzeug Library[4], welche einen leichtgewichtigen Webserver mit geringem Implementierungsaufwand ermöglicht. Dabei hilft das Toolkit unter anderem bei oder mit folgenden Punkten:

  • URL-Mapping und Routing von Anfragen
  • HTTP-Serving von statischen Dateien wie z.B Bilder oder CSS-Stylesheets
  • Vereinfachte Nutzung des WSG-Interfaces durch Request- und Response-Wrapper
  • Eingebauter Webserver zum Testen

Twitter API [5]

Für die Anbindung des externen Kurznachrichten-Dienstes Twitter soll eine bereits bestehende Bibliothek von einem Drittanbieter verwendet werden. Twitter selbst bietet keine eigenen Bibliotheken an, verweist aber auf eine Reihe von API's, auch für ganz verschiedene Programmiersprachen, die von verschiedenen unabhängigen Entwicklern zur Verfügung gestellt wurden. Aus dieser Liste wurden drei verschiedene Bibliotheken ausgewählt, getestet und sich für eine entschieden.

Als am besten geeignet hat sich Tweetpony herausgestellt. Diese API kann sehr einfach über die PIP Paketverwaltung installiert werden und im Gegensatz zu den beiden anderen Bibliotheken hat diese auf Anhieb ohne Probleme oder Konfigurationsaufwand funktioniert. Desweiteren ist die API sehr gut dokumentiert, quelloffen und absichtlich sehr schlank gehalten. Für das eventuell spätere zu implementierende Kamerafeature besitzt die API zusätzlich die Funktion, nicht nur ein Bild, sondern eine ganze Serie von Bildern an einen Post anzuhängen.

Generell muss für das Posten auf Twitter zuerst ein Twitter-Account erstellt werden. Anschließend muss Twitter mitgeteilt werden, dass unsere Applikation Zugriff auf die Twitter-schnittstelle braucht. Nach Angabe von Informationen über die Applikation generiert Twitter verschiedene Tokens, die von der Bibliothek und letztendlich unserem Programm beim Start zur Authentifizierung übermittelt werden müssen.

Datenbank

Um die Informationen der Keksdose wie etwas Gewichtsveränderung, Datum der Entnahme sowie ein dazugehöriges Bild zu speichern soll eine Datenbank verwendet werden. Um dem Aufwand einer Installation und Konfiguration, möglicherweise noch das Aufsetzen eines Apache-Systems zu entgehen, soll eine leichtgewichtige Datenbank verwendet werden, die ebenfalls in der Programmiersprache Python existieren soll. Nach einiger Recherche wurden wir aufmerksam auf die PyDbLite-Bibliothek [9]. Diese ist einfach über den PIP-Paketmanager zu installieren.

Die API ermöglicht es dem Benutzer, ganze Python-Objekte zu serialisieren. Wichtig ist darauf zu achten, dass bei Änderung der Objektstruktur auch die Datenbank neu generiert bzw. die alte gelöscht wird.

def writeConfig(self, param, value):
    """ writes key value pair into config database """
    try:
         result= self.config._param[param]
	 if len(result)==0:
	     self.config.insert(param = param, value = value)
         else:
	     self.config.update(result[0], value = value)
	     self.config.commit()

    except:
         print "DB config error occured..."

Entwicklung der Software

Ocj-software.png

Die Architektur wurde anhand der Anforderungen entworfen ist mehrschichtig aufgebaut. Sie basiert auf einer Art Model-View-Controller Architektur. Dabei existiert eine Applikationsschicht / Präsentationsschicht, die durch den TwitterPoster und Webserver realisiert wird, einen Main-Controller (JarController) und einer Datenbank als Persistenzschicht. Weiterhin gibt es Klassen zur Repräsentation der Hardware und einen Controller zur Überwachung der Keksdose inkl. einem erweitertem EventHandling.

Software-Komponenten

ScaleController
Der ScaleController ist dafür verantwortlich, die Waage bzw. den für Testzwecke implementierten ScaleEmulator permantent nach Werten abzufragen. Er läuft in einem separaten Thread um so nebenläufig seine Abfragen zu tätigen. Die Klasse bedient sich am Observer-Pattern, das anderen Klassen erlaubt, sich zu registrieren und bei Änderungen des Gewichtes informiert zu werden. Sobald sich das Gewicht der Keksdose über einem vorher eingestellten Schwellenwert ändert, wird der ScaleController alle vorher registrierten Observer per update()-Methode informieren und den aktuellen Stand des Gewichtes
ScaleEmulator
Die Aufgabe des ScaleEmulators ist es, dem Entwickler das Testen zu vereinfachen. Dieses Stück Software emuliert eine Waage, die angibt ein bestimmtes Gewicht zu haben und in unregelmäßigen Abständen stochastisch unabhängig eine Keksentnahme simuliert.
HX711
Die hx711 Klasse kapselt die Hardware und verbindet sich intern über den GPIO-Port an die Wägezelle. Die Methoden sind gleich zu dem ScaleEmulator, sodass der ScaleController keine Anpassungen benötigt.
JarController
Das Herzstück der Anwendung bildet der JarController. Dieser instanziiert die Objekte der Persistenz- sowie der Präsentationsschicht. Er ist als Observer an dem ScaleListener registriert und beinhaltet außerdem das EventManagement. Über die Webschnittstelle wird dem Nutzer Möglichkeit angeboten, den Überwachungsmodus an- oder auszuschalten. Ist der Überwachungsmodus angeschalten, so sorgt der JarController dafür, dass auf Events gehört wird und diese dann an den TwitterService zum Posten übergeben werden.
DBConnector
Die DBConnector Klasse bietet Funktionen an, um die Daten der CookieEvents zu persistieren. Dazu gehören aktuell folgende Datenbankeinträge:
Date | Delta | Weight | Images
Das Datum wird als Date von Python serialisiert. Das Delta der Gewichtsänderung wird in Gramm angegeben, sowie das aktuelle Gewicht der Dose. Die Pfade der Images werden als Strings in einer Liste übergeben.
Webserver
Der Webserver stellt die Benutzungsoberfläche dar, mit der sowohl aktuelles Gewicht und vergangene Ereignisse betrachtet werden können, als auch die Waage tariert und Einstellungen gesetzt werden können. Im eigentlichen Sinne stellt dieses Modul kein Webserver dar, sondern lediglich die Web-Anwendung welche in einem Web-Application-Server laufen kann. Sie basiert auf der WSGI-Schnittstelle und kann in jedem WSGI-fähigen Webserver deployt werden.

Der Überwachungsmodus

Nicht jede Gewichtsänderung der Keksdose soll eine Alarmierung auslösen. Wenn die Keksdose zum Beispiel aufgefüllt wird, oder ein autorisierter Keksentnehmer einen Keks entnimmt, soll keine Notifikation über Twitter ausgelöst werden. Zu diesem Zweck gibt es den Überwachungsmodus, der vom Eigentümer über die Weboberfläche an oder aus gestellt werden kann. Ist dieser aus, wird nicht auf Gewichtsänderungen reagiert, sondern lediglich auf der Weboberfläche angezeigt.

EventHandling

Um nicht schon bei jeder kleinsten Gewichtsveränderung davon auszugehen, dass ein Keks entnommen wurde, wird ein spezielles EventHandling erforderlich. Ein Event zur Keksentnahme wird sich meistens über einen gewissen Zeitraum erstrecken (Dose öffnen, Keks der Begierde aussuchen, Keks entnehmen, Deckel der Dose wieder aufsetzen). Dieser Vorgang wird vom Jar-Controller behandelt und kann folgendermaßen formalisiert werden:

  • 13:12:19: Gewichtsänderung -> createCookieEvent() -> wait 10 secs to end event...
  • 13:12:24 Gewichtsänderung -> addEventItem() -> extend waiting time for 10 secs...
  • 13:12:30 Gewichtsänderung -> addEventItem() -> extend waiting time for 10 secs...
  • 13:12:41 cookieEventEnded()

CookieEvent:

Die CookieEvent-Klasse speichert alle Informationen, die für das EventHandling benötigt werden. Es wird initialisiert mit dem Inhaltsgewicht der Keksdose bevor etwas entnommen wurde, und enthält eine Zeitangabe, prolong, wie lange noch gewartet werden soll, bis das CookieEvent terminiert.

Ist ein CookieEvent zu Ende, bzw. der Timer abgelaufen, kann über die Methode getDelta die Gewichtsveränderung der Keksdose geholt werden.

def update(self, weight):
        t = time.time()
        print "update %s" % time.strftime('%d.%m.%Y, %H:%M:%S', time.localtime(t))  
        
        if abs(self.latestWeight-weight)<self.epsilon:
            return #cancel if difference is too low
        
        if self.monitoring:
            if self.currentEvent==None or time.time()>self.currentEvent.endTime:
                self.currentEvent = CookieEvent(self.latestWeight, self.camera, starttime=time.time(), prolong=10.0)
                print "new CookieEvent - start:%.1f, end:%.1f" % (self.currentEvent.startTime, self.currentEvent.endTime)          
            else:
                self.eventTimer.cancel()
                            
            self.currentEvent.addItem(weight)
            
            self.eventTimer = Timer(self.currentEvent.prolong+0.01, self.cookieEventEnded, args=[self.currentEvent])    
            self.eventTimer.start()  
        
        self.latestWeight = weight;
        
        
    def cookieEventEnded(self, event):
        if time.time()>self.currentEvent.endTime:
            cNr = int(event.getDelta() / self.gpk)
            print "CookieEvent ended, delta=%f, cookies: %d" % (event.getDelta(), cNr)
            if cNr >= 0:
                event.cleanUp()
                return # no need to post...
            print event.getImages()
            self.db.insert(time.time(), event.getDelta(), event.getLatestWeight(), event.getImages())
            self.twitter.postStatus(abs(cNr), event.getImages())
        else:
            print "CookieEvent time ran out, but event is not finished"

Zusammenbau des Dings

Beim Zusammenbau des Dings waren handwerkliche Fähigkeiten gefragt. Der Sockel für die Keksdose, der zusammen mit der Wägezelle die Waage darstellt, wurde aus Bastelholz ausgesägt, zusammengeleimt und zusammengeschraubt. Das Erbebnis, inklusive der Verkabelung der Komponenten, kann den folgenden Bildern entnommen werden.

Jar.jpg Cookiejar aufbau.png

Funktionale und optische Ausgestaltung der Web-Oberfläche

Bei der Weboberfläche wurden sowohl funktionale, als auch ästhetische Aspekte berücksichtigt. Funktional sollte die Oberfläche folgendes liefert:
  • Der Keksdosen-Inhalt soll in Gramm und in Stückzahl umgerechnet dargestellt werden.
  • Die Darstellung des Inhalts soll regelmäßig aktualisiert werden.
  • Eine Schaltfläche zur Nullung bzw. Tarierung der Waage soll vorgesehen werden.
  • Das Gewicht pro Keks soll so eingestellt werden können, dass währenddessen der Keksdosen-Inhalt betrachtet werden kann.
    • Begründung: Um das Gewicht pro Keks festzustellen, kann ein Keks in die Dose gelegt werden.
  • Es muss ein Schalter für den Überwachungsmodus vorgesehen werden.
  • Eine Verlaufs-Sicht über Ereignisse soll dargestellt werden können.

Die Screenshots rechts zeigen die Umsetzung dieser Anforderungen. Das aktuell gemessene Gewicht wird auf dem Display der Digitalwaage dargestellt. Die verwendete Schriftart ahmt die eines LCD-Displays nach. Darunter, in dem zentralen Zimtstern wird die Keksanzahl dargestellt, welche mithilfe der Angabe von "g/Keks" berechnet wird, welche in dem Keks rechts davon vorgenommen werden kann.

Die Angaben über das Gewicht werden alle zwei Sekunden mithilfe von Ajax aktualisiert. Zentral in der Waage befindet sich dennoch ein Aktualisierungs-Button(/-Image), falls im verwendeten Browser javascript gerade nicht verfügbar ist.

Darüber befindet sich der Schalter für den Überwachungsmodus, welcher ebenfalls asynchron mit dem Webserver kommuniziert. Links von der Waage befindet sich der Verlaufs-Link, der auf die Verlaufs-Sicht führt, welche auf dem zweiten Screenshot dargestellt ist.

Der Inhaltsverlauf zeigt zu jedem Ereignis das Datum, die Uhrzeit, das neue Gewicht und die Änderung an. Darüber hinaus gelangt man über den Klick auf "details" auf eine neue Seite, welche die verknüpften Bilder anzeigt.

Cookiejar web.png
Cookiejar webhistory.png

Anbindung einer Kamera

Da zum Ende des Projektes noch Semester-Zeit verfügbar war, haben wir uns dazu entschieden, ein zusätzliches Feature zu implementieren. Die Keksdose soll nun auch Fotos vom Keksdieb machen und diese zusätzlich auf der Präsentationsschicht verfügbar machen. Als Kamera wurde eine passend zum Raspberry Pi gehörende Kamera verwendet [10], die an den eigens dafür vorgesehen Kamera Port angeschlossen wird. Die zugehörige Software kann als Paket für das Raspbian Betriebssystem heruntergeladen und installiert werden. [11]

Für die Ansteuerung der Anwendung gibt es ebenfalls ein Python-Modul für die Kamera namens „Picamera“. Somit kann die Kamera sehr einfach in die bestehende Anwendung integriert werden. Die Persistenzschicht musste dahingehend abgeändert werden, anstatt einem Pfad zu einer Bilddatei eine Liste von Dateien zu speichern. Durch die verwendete Bibiliothek, die Python-Objekte serialisiert, ist diese Erweiterung aber äußerst gering. [12]


Die Pfade zu den Bildern wurde dem CookieEvent als privates Feld hinzugefügt. So hält jedes neue Event auch eine Referenz zu dem dazugehörigen Bild. Um die Dateinamen der geschossenen Fotos eindeutig zu halten, wird jedem Foto ein Timestamp in Sekunden seit der Urzeit 1.1.1970 vorangehängt. Ebenfalls wurde der TwitterPoster angepasst, so dass die geschossenen Fotos als Mediendateien an jeden Post anhängt. Dafür wurde eine Funktion der API benutzt um mehrere Dateien statt einer anzuhängen.


def takePicture(self):
        t = time.time()
        img = "camera/%dimage.jpg" % int(t)
        self.camera.capture(img)
        return img