WeMos D1 mini als Temperatur- und Luftfeuchtigkeits-Webserver

Im nächsten Versuch mit dem WeMos D1 mini soll nun seine WiFi-Funktionalität zum Einsatz kommen. Der Plan ist dabei, mit dem bereits früher verwendeten Temperatur- und Luftfeuchtigkeitssensor DHT11 (Teil 1 und Teil 2) gemessene Daten über eine einfache Webseite darzustellen.

Als erstes der einfache Steckplatinen-Aufbau:

Steckplatinenaufbau mit Wemos D1 mini und DHT11
Aufbau des WeMos D1 mini mit dem Temperatur- und Luftfeuchtigkeitssensor DHT11

Der dazugehörige Code ist schon etwas komplizierter (basiert auf dem Beispiel von Bernhard Linz):

/*******************************************************************************************
 * Read data from DHT-11 sensor and present it with a web page                             *
 *                                                                                         *
 * Based on a Script by Bernhard Linz ( https://znil.net/ )                                *
 *******************************************************************************************/


// import used libraries
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include "DHT.h"

// include WiFi credentials
#include "credentials.h"

// definitions
#define DHTPIN D5         // pin of the arduino where the sensor is connected to
#define DHTTYPE DHT11     // define the type of sensor (DHT11 or DHT22)

// create web server
ESP8266WebServer webServer(80);

// create instance of DHT                          
DHT dht(DHTPIN, DHTTYPE, 6);

// variables for measured values
float temperature;
float humidity;

// initialization
void setup() {
  Serial.begin(9600);
  Serial.println("DHT11 test web server");

  // initialize measuring
  pinMode(DHTPIN, INPUT);
  dht.begin();

  Serial.println("Connecting to ");
  Serial.println(ssid);

  // connecting to local wi-fi network
  WiFi.begin(ssid, password);

  // check wi-fi staus until connected
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
 
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.print("my IP: ");
  Serial.println(WiFi.localIP());
  uint8_t macAddr[6];
  WiFi.macAddress(macAddr);
  Serial.printf("mac address: %02x:%02x:%02x:%02x:%02x:%02x\n", macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]);

  webServer.on("/", handle_OnConnect);
  webServer.onNotFound(handle_NotFound);

  webServer.begin();
  Serial.println("HTTP server started");
}

void loop() {
  webServer.handleClient();
}

void handle_OnConnect() {
  temperature = dht.readTemperature();
  humidity = dht.readHumidity();
  webServer.send(200, "text/html", buildHtml(temperature,humidity));
}

void handle_NotFound(){
  webServer.send(404, "text/plain", "Not found");
}

String buildHtml(float _temperature,float _humidity){
  String page = "<!DOCTYPE html> <html>\n";
  page +="<head><meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>\n";
  page +="<meta charset="UTF-8"/>";
  page +="<meta http-equiv="refresh" content="5"/>";
  page +="<title>WeMos D1 mini Temperature & Humidity Report</title>\n";
  page +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
  page +="body{margin-top: 50px;} h1 {color: #444444;margin: 20px auto 30px;}\n";
  page +="h2 {color: #0d4c75;margin: 50px auto 20px;}\n";
  page +="p {font-size: 24px;color: #444444;margin-bottom: 10px;}\n";
  page +="</style>\n";
  page +="</head>\n";
  page +="<body>\n";
  page +="<div id="webpage">\n";
  page +="<h2>WeMos Lolin D1 mini</h2><h1>Temperature & Humidity Report</h1>\n";
 
  page +="<p>Temperature: ";
  page +=(int)_temperature;
  page +=" °C</p>";
  page +="<p>Humidity: ";
  page +=(int)_humidity;
  page +=" %</p>";
 
  page +="</div>\n";
  page +="</body>\n";
  page +="</html>\n";
  return page;
}

Mit dem Einbinden des ESP8266 Microcontrollers und dem vorherigen Verwenden des DHT11 sind schon alle nötigen Libraries vorhanden. Die WLAN Zugangsdaten habe ich in eine separate Datei ausgelagert um zu verhindern, dass diese versehentlich publiziert werden. Deshalb ist zusätzlich eine zweite Datei mit dem Namen „credentials.h“ mit folgendem Inhalt nötig:

#ifndef __CREDENTIALS_H__
#define __CREDENTIALS_H__

// WiFi credentials:
const char* ssid = "mySSID";
const char* password = "secret";

#endif

Nach dem Uploaden und Starten des Programmes sollte im Serial Monitor eine Ausgabe ähnlich der nachfolgenden erscheinen (SSID, IP- und MAC-Adresse anonymisiert):

DHT11 test web server
Connecting to
mySSID
....
WiFi connected
my IP: 192.168.xxx.xxx
mac address: 2c:f4:32:xx:xx:xx
HTTP server started

Falls nach der SSID längere Zeit nur Punkte erscheinen sind vermutlich die WLAN Zugangdaten falsch. Ansonsten kann mit einem Browser auf die angegebene IP-Adresse zugegriffen werden und es sollte eine Webseite mit den aktuellen Messwerten erscheinen. Die Webseite aktualisiert sich alle 5 Sekunden.

Webseite mit den aktuellen Messwerten Temperatur und Luftfeuchtigkeit, ausgeliefert vom WeMos D1 mini
Die Webseite mit den aktuellen Messwerten

Es empfiehlt sich im DHCP-Server für die MAC-Adresse des WeMos D1 mini immer dieselbe IP-Adresse vergeben zu lassen damit man nicht auf die Ausgabe des Serial Monitor angewiesen ist.

Bei Last Minute Engineers ist ein Tutorial zu finden, welches auch als Basis für das Script von Bernhard Linz diente. Dort wird die Webseite auch noch schöner gestaltet und zum Schluss wird auch noch auf das Aktualisieren mittels AJAX eingegangen.

Erste Schritte mit dem Wemos D1 Mini

Nach den ersten Schritten mit dem Arduino Nano (Teil 1 und Teil 2) soll nun ein anderer Mikrocontroller zum Zug kommen, der ESP-8266EX auf dem Wemos Lolin D1 mini board.

Um dieses Board in der Arduino IDE verwenden zu können muss es zuerst im Board Manger installiert werden. Es ist unter dem Namen „esp8266“ zu finden. Falls es nicht gefunden wird muss unter File->Preferences-> Additonal Boards Manager URLs die URL http://arduino.esp8266.com/stable/package_esp8266com_index.json hinzugefügt werden. Danach kann unter Tools->Boards->Board Manager der ESP8266 gesucht und installiert werden. Dadurch werden bei den Boards diverse ESP8266-Boards aufgelistet. Für diese Versuche wird WeMos D1 R2 & mini ausgewählt.

Als erstes war das Ziel, zwei LEDs mit zwei Tastern zum Leuchten bringen. Die hier eingesetzten LEDs haben eingebaute Vorwiderstände. Falls normale LEDs zum Einsatz kommen den Vorwiderstand nicht vergessen! Also zwei Pins als Input und zwei als Output definiert, Schaltung aufgebaut und los!

void setup() {
  pinMode(D2, INPUT);
  pinMode(D3, INPUT);

  pinMode(D6, OUTPUT);
  pinMode(D7, OUTPUT);
}

void loop() {
  int left = digitalRead(D2);
  int right = digitalRead(D3);

  digitalWrite(D6, left);
  digitalWrite(D7, right);
}
Erster fehlgeschlagener Versuch mit dem Wemos D1 mini (Steckplatinenansicht)
Erster fehlgeschlagener Versuch mit dem Wemos D1 mini

Die rote LED funktionierte auch wie geplant, die grüne leuchtete aber andauernd. Nachdem die normale Fehlersuche (Verbindungen und Code kontrollieren) keinen Erfolg brachte war der nächste Schritt die Recherche: gibt es Pins bei diesem Board, die speziell geschaltet sind? Schlussendlich hat mir diese Pinout Referenz des ESP8266 (Kapitel „Wemos D1 Mini Pinout“ und „Best Pins to Use“, leider nicht direkt verlinkbar) das Problem aufgezeigt: D3 (GPIO0) ist für Input als „pulled up“ angegeben und sollte nicht verwendet werden. Also das Ganze umgebaut und nochmals versucht:

void setup() {
  pinMode(D6, INPUT);
  pinMode(D7, INPUT);

  pinMode(D1, OUTPUT);
  pinMode(D2, OUTPUT);
}

void loop() {
  int left = digitalRead(D6);
  int right = digitalRead(D7);

  digitalWrite(D1, left);
  digitalWrite(D2, right);
}
Zweiter, erfolgreicher Versuch (Steckplatinenansicht)
Zweiter, erfolgreicher Versuch

Mit diesem Umbau klappte dieser einfache Aufbau dann wie geplant.

Temperatur und Luftfeuchtigkeit messen und Anzeigen mit dem Arduino Nano

Im letzten Teil wurde der Temperatur-Sensor DHT-11 mit dem Arduino Nano ausgelesen. Nun sollen die gemessenen Werte auch ohne Computer anzeigen werden können.

Der Aufbau basiert auf der letzten Schaltung und erweitert diese um das Display, welches ebenfalls aus dem Arduino Adventskalender stammt. Damit alles Platz hat kommen zwei kleine Steckboards zum Einsatz.

Steckplatinen-Aufbau mit Arduino Nano, DHT-11 und Display
Steckplatinen-Aufbau mit Arduino Nano, DHT-11 und Display

Für die Ansteuerung des LCD wird zusätzlich die Bibliothek „LiquidCrystal“ von Arduino, Adafruit benötigt, welche in der Arduino IDE wiederum unter Tools->Manage Libraries… hinzugefügt werden kann. Bei der Erstellung des Programmes wurde die Version 1.0.7 verwendet. Dem grösseren Aufbau entsprechend ist auch der Code umfangreicher.

/*******************************************************************************************
 * Read data from DHT-11 sensor and show it on a two-line LCD with an arduino nano         *
 *                                                                                         *
 * based on a script by Philippe Keller (www.bastelgarage.ch)                              *
 *******************************************************************************************/


// import used libraries
#include "DHT.h"                
#include <LiquidCrystal.h>

// definitions
#define DHTPIN 2          // pin of the arduino where the sensor is connected to
#define DHTTYPE DHT11     // define the type of sensor (DHT11 or DHT22)
       
// create instance of DHT                          
DHT dht(DHTPIN, DHTTYPE, 6);

// create instance of LiquidCrystal
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

void setup() {
  Serial.begin(9600);
  Serial.println("DHT11 test program 2");
  dht.begin();
  lcd.begin(16, 2);
  lcd.clear();
  lcd.print("T:        C");
  lcd.setCursor(0,1);
  lcd.print("rF:       %");
}

void loop() {
  // Wait two seconds between measurements as the sensor will not measure faster
  delay(2000);
                                   
  float h = dht.readHumidity();
  float t = dht.readTemperature();
 
  // validate values
  if (isnan(h) || isnan(t)) {      
    Serial.println("Error while reading data!");
    return;
  }

  // send data via serial connection to pc
  Serial.print("Luftfeuchtigkeit: ");
  Serial.print(h);
  Serial.print("%\t");
  Serial.print("Temperatur: ");
  Serial.print(t);
  Serial.write("°");
  Serial.println("C");

  // write data to liquid crystal display
  lcd.setCursor(4,0);
  lcd.print(t);
  lcd.setCursor(4,1);
  lcd.print(h);
}

Für die Speisung der Schaltung habe ich eine USB-PowerBank verwendet. Im Einsatz sieht dann das Ganze so aus:

Arduino Nano, DHT-11 und Display im Einsatz
Arduino Nano, DHT-11 und Display im Einsatz

Temperatur und Luftfeuchtigkeit messen mit dem Arduino Nano

Für meine ersten Schritte im Mikrocontroller-Umfeld abseits der vorgetrampelten Pfade von Starter Kit oder Adventskalender wollte ich mich mit der Luftfeuchtigkeitsmessung beschäftigen. Dabei ist mir der Temperatur- und Luftfeuchtigkeits-Sensor DHT-11 über den Weg gelaufen.

Der DHT-11 ist ein einfacher und günstiger Sensor, der die Temperatur und die Luftfeuchtigkeit misst und über ein einfaches Protokoll ausgibt. Wenn eine höhere Genauigkeit gefordert ist kann der etwas grössere und teurere DHT-22 eingesetzt werden. Für die Ansteuerung der beiden Sensoren kann dabei die selbe Bibliothek verwendet werden, es muss bei der Instanzierung nur der passende Typ angegeben werden.

Der erste einfache Aufbau benötigt nur einen Arduino (in meinem Fall kam der Arduino Nano aus dem Adventskalender zum Einsatz) und den Sensor auf einem Modul. Dieses Modul beinhaltet den Pull-up-Widerstand bereits, beim Einsatz des „nackten“ Sensors muss dieser noch entsprechend hinzugefügt werden. Beim Modul muss noch beachtet werden dass es Versionen mit verschiedenen Pin-Belegungen gibt. Beim von mir eingesetzten Modul ist die Belegung VCC / Data / GND, es gibt aber auch Module mit Data / VCC / GND.

Steckplatinen-Aufbau mit Arduino Nano und DHT-11
Steckplatinen-Aufbau mit Arduino Nano und DHT-11

Das erste Programm soll dabei nur die Daten auslesen und über die Schnittstelle zum PC ausgeben. Dazu muss die Bibliothek „DHT sensor library“ von Adafruit in der Arduino IDE unter Tools->Manage Libraries… hinzugefügt werden. Beim Erstellen des Programmes war die Version 1.3.8 aktuell. Danach kann der untenstehende Code in die IDE übernommen werden:

/*******************************************************************************************
 * Read data from DHT-11 sensor via an arduino nano                                        *
 *                                                                                         *
 * based on a script by Philippe Keller (www.bastelgarage.ch)                              *
 *******************************************************************************************/


// import used library
#include "DHT.h"

// definitions
#define DHTPIN 2          // pin of the arduino where the sensor is connected to
#define DHTTYPE DHT11     // define the type of sensor (DHT11 or DHT22)
       
// create instance of DHT                          
DHT dht(DHTPIN, DHTTYPE, 6);

void setup()
{
  Serial.begin(9600);
  Serial.println("DHT11 test program");
  dht.begin();
}

void loop()
{
  // Wait two seconds between measurements as the sensor will not measure faster
  delay(2000);
                                   
  float h = dht.readHumidity();
  float t = dht.readTemperature();
 
  // validate values
  if (isnan(h) || isnan(t)) {      
    Serial.println("Error while reading data!");
    return;
  }

  // send data via serial connection to pc
  Serial.print("Luftfeuchtigkeit: ");
  Serial.print(h);
  Serial.print("%\t");
  Serial.print("Temperatur: ");
  Serial.print(t);
  Serial.println("°C");
}

Dieses Programm wird dann auf den Arduino übertragen. Dabei musste ich für meinen Arduino Nano den Prozessor auf „ATMega 328P (Old Bootlaoder)“ und den Programmer auf „AVRISP mkII“ einstellen. Nach dem Übertragen produziert das Programm dann im Serial Monitor eine Ausgabe wie folgende:

DHT11 test program
Luftfeuchtigkeit: 36.00%      Temperatur: 25.60°C
Luftfeuchtigkeit: 36.00%      Temperatur: 25.40°C
Luftfeuchtigkeit: 36.00%      Temperatur: 25.50°C
Luftfeuchtigkeit: 36.00%      Temperatur: 25.60°C
Luftfeuchtigkeit: 36.00%      Temperatur: 25.40°C
Luftfeuchtigkeit: 36.00%      Temperatur: 25.40°C
Luftfeuchtigkeit: 36.00%      Temperatur: 25.40°C
Luftfeuchtigkeit: 36.00%      Temperatur: 25.40°C
Luftfeuchtigkeit: 36.00%      Temperatur: 25.60°C
Luftfeuchtigkeit: 36.00%      Temperatur: 25.50°C
Luftfeuchtigkeit: 35.00%      Temperatur: 25.50°C
Luftfeuchtigkeit: 35.00%      Temperatur: 25.50°C
Luftfeuchtigkeit: 36.00%      Temperatur: 25.50°C

Natürlich möchte man nicht die ganze Zeit einen PC oder Laptop mitschleppen um die Teperatur und Luftfeuchtigkeit zu messen. In einem nächsten Ausbauschritt wird deshalb eine Anzeige hinzukommen.

DisplayPort HDMI Adapter und Lenco DVT-194

Wenn der Bildschirm (noch) nicht mitspielen will

Da bei mir noch ein kleinerer LCD-TV (Lenco DVT-194) herumstand kam die Idee auf, diesen als zweiten Screen am PC zu benutzen. Es war mir klar, dass dieser als Fernseher konzipiert war und daher als PC-Bildschirm nicht die Bildqualität liefern würde wie ein dafür optimierter Monitor.

Als erste Hürde erwies sich dabei der Anschluss. Der PC hatte einen freien DisplayPort-Ausgang, der TV aber nur einen HDMI-Eingang. Aber kein Problem, dass sich nicht durch ein Adapter-Kabel lösen liesse. Leider habe ich beim Bestellen des Kabels das Bild nicht genug genau angeschaut und deshalb nicht gesehen, dass auf der HDMI-Seite der Stecker relativ breit und lang ist. Der HDMI-Anschluss beim Lenco liegt direkt neben dem Eingang des Netzteils. Es ist möglich, beide Kabel einzustecken, dabei ist es aber sehr eng – aber es funktioniert.

Also habe ich den Bildschirm mit dem PC verbunden und bin zur Einrichtung geschritten. Der Bildschirm wurde von Windows 10 erkannt und mit der Auflösung 1280×720 angesprochen. Diese wurde auch als empfohlene Auflösung angegeben. Die Verwendung dieser Auflösung veranlasste den Bildschirm aber, das Bild in alle Richtungen zu vergrössern, so dass unten die Hälfte der Taskbar nicht mehr sichtbar war. Und beim Wechsel zwischen den beiden Screens landete der Mauszeiger im Nirvana.

Versuche mit den anderen angebotenen Auflösungen lieferten auch keine befriedigende Ergebnisse. Entweder war das Bild durch die Skalierung unscharf oder gestaucht, so dass Kreise zu Ovalen mutierten. Bei der Recherche im Internet bin ich dann aber auf das Datenblatt des Lenco DVT-194 gestossen und habe dort entdeckt, dass die Auflösung des TVs 1440 x 900 beträgt. Diese Auflösung wurde aber vom Nvidia-Grafiktreiber nicht angeboten!

Durch weitere Recherche im Internet bin ich dann auf das Tool Custom Resolution Utility gestossen. Mit diesem Tool können dem Nvidia-Grafiktreiber weitere Auflösungen beigebracht werden. Nachdem ich dann den Grafiktreiber überredet hatte, dem TV die Auflösung 1440 x 900 anzubieten konnte ich den Lenco als zweiten Screen einsetzen.

Antenna tower with satellite and cell dish

Ping mit Zeitstempel

Ping ist ein einfaches aber hilfreiches Tool für Netzwerk-Analysen. Manchmal möchte man die Ping-Ausgaben mit der aktuellen Zeit ergänzt haben, z.B. als Referenz zu einer Wireshark-Aufzeichnung. Leider gibt es weder unter Windows noch unter Linux einen einfachen Parameter um Ping anzuweisen, die Ausgabe um einen Zeitstempel zu erweitern. Aber mit etwas (Power-)Shell-Magie kann die erwünschte Ausgabe erreicht werden.

Windows (Power Shell)

ping.exe -t COMPUTERNAME | Foreach{"{0} - {1}" -f (Get-Date),$_}

Quelle: Ping with timestamp on stackoverflow.com.

Linux

ping COMPUTERNAME | while read pong; do echo "$(date): $pong"; done

Quelle: How to command “Ping” display time and date of ping on askubuntu.com.


Photo by Tony Stoddard on Unsplash

Danke Cambridge Analytica – Warum ich meine Posts bei Facebook wieder manuell promote

Bisher habe ich auf diesem Blog und meiner Website das Plugin WP Facebook Auto Publish eingesetzt um neue Artikel automatisch auf meinem Facebook Profil zu promoten. Nach dem Datenskandal bei Facebook, bei dem die Datenanalysefirma Cambridge Analytica mehr als 87 Millionen Nutzerdaten unrechtmäßig abschöpfen konnte, erlaubt Facebook die Verwendung der APIs nur noch unter erschwerten Bedingungen. Dieser Beschreibung kann man entnehmen, was man alles angeben muss, damit Facebook die Anwendung reviewed. Unter anderem muss ein Screencast aufgezeichnet werden, der die Anwenung zeigt sowie ein Testaccount für die Reviewer bei Facebook eingerichtet werden. Sprich, ich müsste Unbekannten auf meinem Blog bzw. meiner Webseite einen Account einrichten, mit dem sie Artikel und Seiten erstellen könnten!
Nein, danke, da poste ich lieber wieder manuell bei Facebook, wenn ich einen neuen Artikel geschrieben habe.

Aufgepretzelt – von statisch zu generiert – Teil 4

Pretzel

Pretzel

Mit Hilfe von Pretzel haben wir im dritten Teil die ersten redundanten Informationen ausgelagert. Im vierten und letzten Teil sehen wir, wie das Menü ausgelagert werden kann und was man bei Websites tun kann, die verschiedene Layouts verwenden.

Menü
Die meisten Websites bestehen aus mehr als einer Seite und nutzen zur Navigation zwischen den Seiten ein Menü. Um dem Benutzer anzuzeigen, wo er sich gerade befindet, wird der aktuelle Menüpunkt hervorgehoben. Dadurch sieht das Menü auf jeder Seite ein kleines bisschen anders aus, enthält aber immer die gleichen Menüpunkte, welche auch ausgelagert werden sollen.

Um das Menü mittels Pretzel auszulagern kann man den folgenden Aufbau im Layout benutzen:

<ul class="menu">
  <li {% if page.url == "/index.html" %} class="active"{% endif %}><a href="index.html">Home</a></li>
  <li {% if page.url == "/seite1.html" %} class="active"{% endif %}><a href="seite1.html">Seite 1</a></li>
  <li {% if page.url == "/seite2.html" %} class="active"{% endif %}><a href="seite2.html">Seite 2</a></li>
  <!-- etc. -->
</ul>

Dadurch wird bei der Seite, welche gerade bearbeitet wird (sprich, bei welcher die URL übereinstimmt) die css-class active gesetzt. Die Quelle für diese Variante ist Jekyll Tips. Dort wird auch auf den Nachteil dieser einfachen Lösung hingewiesen: Neue oder umbenannte Seiten müssen im Layout nachgeführt werden, sonst erscheinen sie im Menü nicht. Falls nur wenige Änderungen anfallen, kann dies aber verschmerzt werden. Die dort aufgeführte automatische Variante scheint mit Pretzel (noch) nicht zu funktionieren.

Zwei Layouts
Einige Websites nutzen neben dem Layout für die normalen Seiten ein zweites Layout, z.B. für den Blog oder eine Fotogalerie. Dazu kann ein weiteres Datei im Ordner _layouts erstellt werden. In den Dateien, welche das zweite Layout verwenden sollen, kann dann auf das neue Layout verwiesen werden.

Dadurch sind aber Redundanzen schon wieder vorprogrammiert. Dies kann aber durch includes verhindert werden. Die in beiden Layouts vorhandenen Fragmente können in Dateien ausgelagert werden, welche im Ordner _includes abgelegt werden müssen. Im Layout kann dann das Fragment mit {% include footer.html %} eingefügt werden.

Abschluss
Weitere individuelle Elemente sollten mit den oben gezeigten Grundlagen umgesetzt werden können. Ansonsten ist die Dokumentation von Jekyll eine gute Anlaufstelle, da die Beschreibung von Pretzel nur die Pretzel-spezifischen Informationen und die Unterschiede zu Jekyll enthält.

Sobald die Migration abgeschlossen ist können die geplanten Änderungen (welche ja der Auslöser für die ganze Arbeit waren) vorgenommen werden. Es empfiehlt sich dabei, den Mechanismus für die Sicherheitskopie beizubehalten.

Fazit
Mit diesen einfachen Grundlagen sollten die meisten Webseiten umgebaut werden können, so dass Änderungen einfacher vonstatten gehen. Gewisse Funktionen sind aber noch nicht komplett von Jekyll übernommen worden.

Aufgepretzelt – von statisch zu generiert – Teil 3

Pretzel

Pretzel

Nachdem wir im zweiten Teil die Struktur generiert und die Website ein erstes Mal generiert haben wollen wir nun vom Einsatz von Pretzel profitieren. Wir lagern redundante Informationen Schritt für Schritt zentral aus.

Jeder Durchgang besteht aus den drei Schritten identifizieren, modifizieren und kontrollieren.

Identifizieren
Als erstes müssen wir den HTML-Code der Seiten analysieren, um geeignete Teile zu finden, die zentral ausgelagert werden können. Dazu kommt das Compare-Tool zum Einsatz. Wir vergleichen dabei zwei verschiedene Seiten und suchen uns Blöcke, die identisch sind und auch thematisch sinnvoll ausgelagert werden können. Ein erster Kandidat ist dabei oftmals der Footer der Seiten. Wir können dies auch noch weiter überprüfen, indem wir weitere Seiten miteinander vergleichen.

Modifizieren
Wenn wir uns nun entschieden haben, können wir den auszulagernden Teil aus einer Datei kopieren, eine neue Datei layout.html im Ordner _layouts erstellen und den auszulagernden Inhalt dort einfügen. Dann müssen wir noch angeben, wo der individuelle Inhalt (der aus den verschiedenen Dateien kommt) eingefügt wird. Dies erfolgt durch den Platzhalter {{content}}. Entsprechend sollte dann die Datei layout.html folgende Struktur aufweisen, wenn der Footer ausgelagert wurde:

{{content}}
<!-- auszulagernder Footer -->

Damit nun die Seiten auch das Layout verwenden muss dies in jeder Datei angegeben werden (sogenannte Meta-Informationen). Dies geschieht durch folgenden Aufbau:

---
layout: layout
---
<!-- bisherige Seite, ohne Footer -->

Der Footer-Teil muss dabei auch bei jeder Datei entfernt werden, da er sonst doppelt erscheint.

Kontrollieren
Wenn wir alle Dateien entsprechend angepasst haben können wir Pretzel erneut mit dem Aufruf pretzel bake starten. Nachdem Pretzel seine Arbeit beendet hat können wir das Resultat im Ordner _site erneut mit der Ausgangs-Website vergleichen. Es sollten weiterhin keine Unterschiede vorhanden sein. Falls dies der Fall ist, sollte wiederum eine Sicherheitskopie angelegt werden.

Same same but different
Was aber ist zu tun, wenn auszulagernde Teile nur fast gleich sind, sich aber in kleinen, aber wichtigen Details unterscheiden? Dies tritt zum Beispiel oft beim Header der Seiten auf, die zwar dieselbe Struktur aber einen individuellen Titel haben.

Hierzu können in den Meta-Informationen Variablen definiert werden, auf welche im Template zurückgegriffen werden kann.

Eine Seite würde dann z.B. wie folgt aussehen:

---
layout: layout
title: Startseite
---
<!-- bisherige Seite, ohne Header und Footer -->

Das dazu passende Layout hätte folgenden Aufbau:

<!-- erster Teil des Headers -->
 <title>Meine tolle Website - {{ page.title }}</title>
<!-- zweiter Teil des Headers -->
{{content}}
<!-- auszulagernder Footer -->

Wiederum kontrollieren wir nach den Änderungen das Resultat und erstellen eine Sicherheitskopie.

Fehlerbehandlung
Bisher haben wir nur den Schönwetterfall betrachtet: Die Änderungen bewirken das gewünschte Resultat und wir können den nächsten Durchgang starten. Doch was können wir tun, wenn das Resultat nicht den Erwartungen entspricht?

Der einfachste Fall, aber manchmal trotzdem schwer zu erkennen, ist, wenn man beim Zugriff auf die Variablen einen Schreibfehler macht. So definiert man z.B. die Variable title (englische Schreibweise), versucht dann aber auf titel (deutsche Schreibweise) zuzugreifen. Eine nicht definierte Variable enthält dann einfach einen leeren Text, entsprechend wird auch nichts ausgegeben – leider auch kein Fehler.

Wenn man Fallunterscheidungen (mit if) oder Schleifen (mit for) verwendet kann es sinnvoll sein, den Wert einer Variablen einfach einmal auszugeben um so zu überprüfen, ob sie den erwarteten Inhalt hat. Dies kann man auch in einen HTML-Kommentar verpacken, um das Layout nicht zu stören:

<!-- DEBUG: URL der Seite: "{{ page.url }}" -->

Ausblick
Wir haben nun die ersten redundanten Informationen ausgelagert. Wie das Menü ausgelagert werden kann und was man bei Websites tun kann, die verschiedene Layouts verwenden, sehen wir im vierten und letzten Teil.

Aufgepretzelt – von statisch zu generiert – Teil 2

Pretzel

Pretzel

Nach den Grundlagen im ersten Teil erstellen wir nun die Struktur und lassen die Seiten aus den bestehenden statischen Seiten erzeugen. Dabei lagern wir aber noch keine Elemente in Templates aus.

Struktur erzeugen:

Pretzel wird über die Kommandozeile bedient, deshalb muss als erstes die Eingabeaufforderung oder die PowerShell geöffnet werden.

Mittels pretzel create kann die Struktur erzeugt werden. Diese wird im aktuellen Ordner erzeugt. Weitere Kommandos können über den Aufruf pretzel angesehen werden.

Die erzeugte Struktur gibt bereits eine Beispiel-Website mit einem Blog aus, wenn man sie generieren lässt. Da wir aber unsere bestehende Website migrieren wollen löschen wir die Beispiel-Dateien. Dies betrifft die Dateien about.md, atom.xml, index.html,rss.xml und sitemap.xml im Hauptverzeichnis sowie die Inhalte aller Ordner.

Dateien und Ordner mit bzw. ohne ‚_‘ am Anfang:

In der generierten Struktur fällt auf, dass es zwei unterschiedliche Arten von Dateien bzw. Ordnern gibt: solche mit und solche ohne ‚_‘ am Anfang.

Die Dateien und Ordner mit einem ‚_‘ am Anfang des Namens sind Hilfs-Dateien und -Ordner. Diese enthalten Informationen, die für die Generierung der Webseite zu Rate gezogen werden. So enthält die Datei _config.yml Konfigurationsdaten, welche die Generierung der gesamten Webseite beeinflussen. Der Ordner _layouts enthält Informationen, wie eine einzelne Seite aufgebaut werden soll.

Alle anderen Dateien und Ordner enthalten den Inhalt der Website und werden je nach Dateityp durch Pretzel verarbeitet (z.B. durch Informationen aus den Hilfs-Dateien angereichert) und das Resultat schlussendlich im Ordner _site abgelegt.

Website übernehmen:

Um die Website zu übernehmen kopieren wir die zu migrierende statische Website inklusive aller Unterordner und deren Inhalte in das Hauptverzeichnis. Mit dem Aufruf pretzel bake sollte dann das Unterverzeichnis _site entstehen, welches die generierte Website als Inhalt hat.

Mit Hilfe des Compare Tools können wir nun den Inhalt des Ordners _site mit der zu migrierenden Website verglichen werden. Wenn alles geklappt hat sollten keine Unterschiede festzustellen sein, da Pretzel nichts geändert sondern nur die Dateien übernommen hat.

Dies wäre jetzt der passende Zeitpunkt, um das erste Mal eine Sicherungskopie zu erstellen.

Ausblick:

Im dritten Teil werden wir die redundanten Informationen Schritt für Schritt zentral auslagern, um vom Einsatz von Pretzel profitieren zu können.