Gästebuch mit Wemos
Als ich mit meiner Freundin zum Geocaching unterwegs war, fiel mir ein das ich ein Programm schreiben wollte, das die Funktion eines Gästebuch ausführt und das auf einem Mikrocontroller. Wer Geocaching kennt, der weis dass man nach einem gefundenen Geocach sich auf einem beiliegenden Zettel eintragen kann. Und genau das will ich als digitale Form abbilden.
Was brauche ich:
- Wemos
- SD Shield
- SD Karte
Anforderung
Für ein Gästebuch, soll ein (Nick)Name und Datum hinterlegt werden. Datum wird Automatisch mit dem Eintrag gesetzt, so das nur der Nickname eingetragen wird. Hier sollte der Wemos als eigenständiger Access-Point funktionieren, so das man sich mit dem Smartphone verbinden kann. Auf der Webseite sollten zwei Textboxen für die Eingabe des Namens und Datum vorhanden sein. Das Speichern erfolgt dann über ein Button. Neben der Eintrage Möglichkeit, soll auch eine Tabelle mit bereits bestehenden Einträgen zusehen sein. Und natürlich sollte der Zugang per Smartphone funktionieren.
Webseite schreiben
Leider kann die Webseite nicht mit Bootstrap aufgebaut werden. Na ja, eigentlich schon, aber das wäre ein eigenes Thema. Diesmal wird die Seite wieder Klassisch und einfach aufgebaut nach Standard HTML Bordmitteln.
Die Webseite wird mit in dem Programmcode eingebettet, so das diese nicht von der SD Karte erst gelesen werden muss. Zudem sollte bei defekter SD Karte trotzdem etwas angezeigt werden, wie eine Fehlermeldung.
Da die Darstellung des Code mit HTML auf dem Blog sich schwierig gestaltet, kann der Programmcode für den Seitenaufbau auf dem Github Repository betrachtet werden [Link zu WebsiteContent].
Die Seite habe ich zuvor ganz normal in HTML geschrieben und das Ergebnis im Browser immer wieder betrachtet. Erst danach kam die Seite in den Programmcode, das jedoch optisch grausig aussieht. Daher habe ich den Teil in einen eigenen Tab bzw. Code-Datei verfrachtet. Am Ende kam fast das selbe Ergebnis wie in den Folgendem Bild zu sehen ist.
Das Aktuelle Datum wird durch ComboBoxen ermöglicht, in dem man das aktuelle Datum und Uhrzeit einrichten kann. Das testen auf dem Windows Phone erfolgt ohne Probleme. Auf dem Iphone jedoch nicht.
SD Karte prüfen
Mit dem Start soll zunähst geprüft werden, ob die SD Karte verfügbar ist. Zuerst wird jedoch geprüft, ob bereits die Datei mit den Gästeeinträgen vorhanden ist. Wenn nicht, dann wird diese angelegt.
void InitSdCard() {
SD.begin(mChipSelect);
if(!SD.exists(mGuestList)){
Serial.println("Create file...");
File dataFile = SD.open(mGuestList, FILE_WRITE);
dataFile.close();
Serial.println("...finish");
}
else {
Serial.println("the guest list exist");
}
if(!mCard.init(SPI_HALF_SPEED, mChipSelect)) { // initialize sd card and check insert sd card
Serial.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
Serial.println("\t\tERROR: can not init sd card");
Serial.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
return;
}
if(!mVolume.init(mCard)) { // initialize sd card
Serial.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
Serial.println("\t\tERROR: Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
Serial.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
return;
}
Serial.println("SD Card: Exist and partion was found");
}
Wemos zum Access Point machen
Auf der Webseite von Wemos ist es eigentlich schon beschrieben, aber zur Vollständigkeit, nehme ich das hier denoch auf. Um den Wemos zum Access Point zu machen, bedarf dies nur weniger Code zeilen. In den Globalen Variablen muss dann nur die Instanz vom WiFiServer gehalten werden. Für den Zugang wird kein Passwort festgelegt.
void StartWebserver() {
Serial.println("Start access point");
WiFi.mode(WIFI_AP);
byte setMode = 0; // 0 = disable, 1 = enable router information
wifi_softap_set_dhcps_offer_option(OFFER_ROUTER, &setMode);
WiFi.softAP("VisitorsBook", "");
mServer.begin(); // Start the HTTP Server
Serial.print("Ip Address: ");
Serial.println(WiFi.softAPIP());// Send the IP address of the ESP8266 to the computer
}
Aufruf der Seite
Mit dem Aufruf der Seite wird zunächst geprüft, ob der Benutzer einen Request sendet. Wenn nicht, wird die Methode zum Speichern umgangen. Den Request nach dem Inhalt zuprüfen, sieht hier etwas kryptisch aus, das jedoch nur schlimm aussieht. Beim auslesen des Datums wird ein Doppelpunkt mit '%3A' ausgefüllt, der sich jedoch einfach mit einem Replace wieder in einen Doppelpunkt gesetzt werden kann. Nach dem aufbereiten des Namens und Datum kann das Ergebnis gespeichert werden.
void printOnWebside() {
WiFiClient webclient = mServer.available();
if (!webclient) {
return;
}
String request = webclient.readStringUntil('\r');
webclient.flush();
int indexGuest = request.indexOf("guestname=");
if(indexGuest != -1) {
int indexEndGuestname = request.indexOf('&');
String guestName = request.substring(indexGuest + 10, indexEndGuestname);
int indexSetTime = request.indexOf("settime=");
int indexEndSettime = request.indexOf(" HTTP");
String settime = request.substring(indexSetTime + 8, indexEndSettime);
// Example: 2019-08-25T19%3A40
// filter technical colon
settime.replace("T", " ");
settime.replace("%3A", ":");
WriteGuest(guestName, settime);
}
BuildWebside(webclient);
}
Datenspeichern
Das Speichern erfolgt Zeilenweise. Hier wird der Eintrag mit einem Zeilenumbruch in die Datei hinzugefügt. Zuerst hatte ich nur Name und Datum, aber das Parsen wäre relativ aufwendiger geworden. Daher wird die Zeile bereits mit dem Ziel HTML Format eingetragen. (Wegen HTML Inhalt ist der folgende Code nur ein Bild)
Daten abrufen
Ist etwas lang die Methode. Aber auch nur, weil wieder etwas HTML mit eingeflossen ist, um die Anzahl der gespeicherten Einträge wieder zugeben. Anschließend werden die Gast Einträge aus der Datei Zeilenweise mit dem bereits HTML Anteil abgerufen und hinzugefügt.
Offene Punkte
Das Hübsch machen der Webseite habe ich weggelassen, sowie das Fehlerbehandlung. Denn ein Eintrag kann ohne Namen und Datum erfolgen und führt dazu, dass der Eintrag in der Liste wirklich leer sein kann. Zudem war auch ein RTC Timer angedacht, der jedoch für den ersten Schritt nicht benötigt wird. Im Main Branch habe ich diesen Teil stehen gelassen.
Und dann noch der Fehler, dass das Datum nicht geht, wenn versucht wird vom Iphone ein Request zu senden.
Datenschutz
Die Anmeldung erfolgt anonym, weil hier keine Personenbezogenen Daten erhoben werden. Um genau zu sein, dürfen hier keine Personendaten erhoben werden, wie Email (Macht in diesen Kontext auch kein Sinn), Namen und Geburtsdatum. Für den Eintrag reicht dann der Hinweis:
Mit meinem Eintrag ins Gästebuch erkläre ich mich einverstanden, dass dieser Beitrag mit Datum und Uhrzeit auf der Gästebuch-Seite hier Lokal öffentlich lesbar wird.
Weitere Informationen findet ihr auf der Seite zu "Datenschutz auf Webseiten"
Wie immer das ganze Beispiel auf meinem Github Repository
Kommentare