3. Smart Plants
3.1. Konzept
Ziel des Projekts ist es, die Feuchtigkeit einer Pflanze auszulesen und diese Daten in einer Datenbank zu speichern. Mit Grafana werden diese Daten visualisiert. Zusätzlich werden Push-Nachrichten via Grafana an Endgeräte (z.B. Smartphone) gesendet, wenn ein gewisser Schwellwert überschritten wird.
3.2. Background
Grafana: Grafana ist eine plattformübergreifende Open-Source-Anwendung zur grafischen Darstellung von Daten aus verschiedenen Datenquellen wie z. B. InfluxDB [Wikipedia_Grafana]
Influx: InfluxDB ist ein quelloffenes Datenbankmanagementsystem, speziell für Zeitreihen. [Wikipedia_InfluxDB]
Mikrocontroller: Als Mikrocontroller werden Halbleiterchips bezeichnet, die einen Prozessor und zugleich auch Peripheriefunktionen enthalten. [Wikipedia_Mikrocontroller]
Docker: Docker ist eine Softwareplattform, mit der Sie Anwendungen schnell erstellen, testen und bereitstellen können. Docker verpackt Software in standardisierte Einheiten, die als Container bezeichnet werden und alles enthalten, was zum Ausführen der Software erforderlich ist, einschließlich Bibliotheken, Systemtools, Code und Laufzeit. [Wikipedia_Docker]
3.3. ESP8266 und Skript
Als Mikrocontroller wurde der ESP8266 ausgewählt, da er relativ günstig ist und alle Anforderungen an das Projekt erfüllt. Die Arduino-Software wurde verwendet, um ein Skript zu entwickeln, welches unter anderem eine WLAN-Verbindung aufbaut und die Messdaten an die InfluxDB sendet. Die Influx-Datenbank bekommt alle 2 Sekunden die Messdaten übermittelt.
#if defined(ESP32)
#include <WiFiMulti.h>
WiFiMulti wifiMulti;
#define DEVICE "ESP32"
#elif defined(ESP8266)
#include <ESP8266WiFiMulti.h>
ESP8266WiFiMulti wifiMulti;
#define DEVICE "ESP8266"
#endif
#include <InfluxDbClient.h>
#include <InfluxDbCloud.h>
#define WIFI_SSID "WLAN_NAME"
#define WIFI_PASSWORD "WIFI_PW"
#define INFLUXDB_URL "http://HIER_IP_ADRESSE:8086/"
#define INFLUXDB_TOKEN "ADMIN_TOKEN"
#define INFLUXDB_ORG "alex"
#define INFLUXDB_BUCKET "plants"
#define TZ_INFO "CET-1CEST,M3.5.0,M10.5.0/3"
InfluxDBClient client(INFLUXDB_URL, INFLUXDB_ORG, INFLUXDB_BUCKET, INFLUXDB_TOKEN, InfluxDbCloud2CACert);
Point sensor("plant2");
const double humidityPin = A0;
const int anyPin = 3;
void setup() {
Serial.begin(115200);
pinMode(humidityPin, INPUT);
pinMode(anyPin, INPUT);
// Setup wifi
WiFi.mode(WIFI_STA);
wifiMulti.addAP(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to wifi");
while (wifiMulti.run() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println();
sensor.addTag("device", DEVICE);
timeSync(TZ_INFO, "pool.ntp.org", "time.nis.gov");
// Check server connection
if (client.validateConnection()) {
Serial.print("Connected to InfluxDB: ");
Serial.println(client.getServerUrl());
} else {
Serial.print("InfluxDB connection failed: ");
Serial.println(client.getLastErrorMessage());
}
}
void loop() {
sensor.clearFields();
int humidityValue = analogRead(humidityPin);
Serial.println(humidityValue);
sensor.addField("plant2", humidityValue);
if (wifiMulti.run() != WL_CONNECTED) {
Serial.println("Wifi connection lost");
}
if (!client.writePoint(sensor)) {
Serial.print("InfluxDB write failed: ");
Serial.println(client.getLastErrorMessage());
}
delay(2000);
}
3.4. Speicherung der Daten mit InfluxDB
InfluxDB ist eine Open-Source-Datenbank, die speziell für Zeitreihendaten gut geeignet ist. Aus diesem Grund wurde InfluxDB für das Projekt ausgewählt, um die Messdaten der Pflanze zusammen mit einem Zeitstempel zu speichern. InfluxDB OpenSource stellt eine kostenlose Version der Datenbank zur Verfügung, die für das Projekt ausreichend ist. Dazu wird die Datenbank in einem Docker-Container ausgeführt und so auf dem lokalen Rechner gehostet. Zusammen mit Influx wird Telegraf verwendet, um die Daten von den Sensoren zu sammeln und an Influx zu senden. Telegraf ist ein Plugin-basierter Server-Agent für die Sammlung und Berichterstellung von Metriken und Ereignissen. [InfluxDB]
Beide Tools werden im docker-compose.yml-File definiert und können so einfach gestartet werden. Das File ist im Repository zu finden.
3.4.1. InfluxDB Struktur:
Zunächst sollen die wichtigsten Begriffe erklärt werden, die in InfluxDB verwendet werden:
Organisation: Eine Organisation ist eine Gruppe von Benutzern, die auf die Daten zugreifen können. Sie können mehrere Buckets und Dashboards erstellen.
Bucket: Ein Bucket ist sozusagen ein Container für die Daten. Er definiert die Location, an der die Daten gespeichert werden sollen sowie die Retention Policy, also die Zeit, wie lange die Daten gespeichert werden sollen. Daten innerhalb eines Buckets können logisch gruppiert werden. Ein Bucket kann mehrere dieser definierten Gruppen enthalten.
Measurement: Eine Measurement ist eine definierte Gruppe, der Daten zugeordnet sind. Zu dieser werden die Datenpunkte (als Felder), Zeitstempel und Tags (zusätzliche Informationen, die den Datenpunkten zugeordnet werden können) gespeichert.
Field: Ein Feld speichert einem key-value Paar mit Daten, die sich über die Zeit ändern.
Tag: Ein Tag ist ein key-value Paar, das den Datenpunkten zugeordnet wird. Daten, die in Tags gespeichert werden, ändern sich nicht oft. Sie werden verwendet, um Metadaten zu jedem Datenpunkt zu speichern.
Timestamp: Jeder Datenpunkt hat einen Zeitstempel, der angibt, wann er aufgenommen wurde. Er wird in der Spalte _time gespeichert.
Point: Dies ist ein einzelner Datenpunkt, der aus einem Zeitstempel, Feldern und Tags besteht und einem measurement zugeordnet ist
3.4.2. Umsetzung
Wie bereits erwähnt, werden die InfluxDB und Telegraf in Docker-Containern gestartet. Eingerichtet wurde die InfluxDB mit einem Bucket plants. Die Daten werden in einem Measurement gespeichert, das den Namen plant2 trägt. Die Datenpunkte, die gespeichert werden, sind die Feuchtigkeit der Pflanze und der Zeitstempel. Die Feuchtigkeit wird als Feld gespeichert, der Zeitstempel als _time-Spalte. Der folgende Codeausschnitt zeigt, wie sich der Mikrocontroller mit der InfluxDB verbindet:
#define INFLUXDB_URL "http://HIER_IP_ADRESSE:8086/"
#define INFLUXDB_TOKEN "ADMIN_TOKEN"
#define INFLUXDB_ORG "alex"
#define INFLUXDB_BUCKET "plants"
InfluxDBClient client(INFLUXDB_URL, INFLUXDB_ORG, INFLUXDB_BUCKET, INFLUXDB_TOKEN, InfluxDbCloud2CACert);
Point sensor("plant2");
Zunächst werden alle notwendigen Informationen für die Verbindung zur angelegten InfluxDB definiert: Die URL, unter der sie erreichbar ist, das Token für die Authentifizierung, der Name der Organisation sowie der Name des Buckets, in dem die Daten gespeichert werden sollen. Damit wird ein InfluxDBClient-Objekt erstellt, das die Verbindung zur Datenbank herstellt. Anschließend wird ein Point-Objekt erstellt, das die Datenpunkte speichert. Der Name des Measurement ist plant2. Zu diesem Point-Objekt können nun die Felder und Tags hinzugefügt werden. In diesem Fall wird ein Tag mit dem Namen device und dem Gerätenamen als Wert hinzugefügt. Außerdem wird die Feuchtigkeit als Feld hinzugefügt. Der Zeitstempel wird automatisch gespeichert, wenn der Datenpunkt gesendet wird. Kann der Datenpunkt nicht erfolgreich geschrieben werden, wird eine Fehlermeldung ausgegeben.
sensor.addTag("device", DEVICE);
sensor.addField("plant2", humidityValue);
if (!client.writePoint(sensor)) {
Serial.print("InfluxDB write failed: ");
Serial.println(client.getLastErrorMessage());
}
Um den korrekten Zeitstempel zu setzen, muss zudem die Zeitzone gesetzt werden. Außerdem synchronisiert sich der Mikrocontroller mit einem NTP-Server, um die aktuelle Zeit zu erhalten. Dies geschieht mit dem folgenden Code:
#define TZ_INFO "CET-1CEST,M3.5.0,M10.5.0/3"
timeSync(TZ_INFO, "pool.ntp.org", "time.nis.gov");
Die folgende Abbildung zeigt den Data Explorer von InfluxDB, in dem die gespeicherten Daten angezeigt werden. Die Daten wurden innerhalb einer Abfrage nach measurement und device-Tag gefiltert. Man sieht hier den Verlauf der Feuchtigkeit der Pflanze über einen Zeitraum von knapp zwei Tagen.

Abb. 3.4.1 InfluxDB Data Explorer
3.5. Visualisierung der Daten mit Grafana
Grafana ist ein Open-Source-Tool, das zur Visualisierung von Daten aus verschiedenen Datenquellen verwendet wird. Es bietet die Möglichkeit eine Vielzahl von Diagrammen und Graphen zu erstellen und diese in Dashboards zusammenzufassen. Darüber hinaus ist es möglich, Warnmeldungen basierend auf bestimmmten Informationen, einzurichten. In diesem Projekt wird Grafana verwendet, um die Daten aus der InfluxDB zu visualisieren. [Grafana]
Dazu wird Grafana ebenfalls in einem Docker-Container gestartet. Die Web-Oberfläche von Grafana kann dann über den Browser (http://localhost:3000) aufgerufen werden. Dort kann man neue Dashboards anlegen und Daten aus verschiedenen Datenquellen hinzufügen. In diesem Fall wird die InfluxDB als Datenquelle hinzugefügt. Man kann dort nun mithilfe verschiedenster Konfigurationsmöglichkeiten individuelle Diagramme erstellen, die die Daten aus der Datenbank darstellen. So wurde das folgende Dashboard erstellt:

Abb. 3.5.1 Grafana Dashboard
Das rechte Diagramm zeigt die aktuell gemessene Feuchtigkeit der Pflanze an. Das linke Diagramm zeigt den Verlauf der Feuchtigkeit über die Zeit an.
3.5.1. Warnmeldungen mit Grafana & Pushover
In Grafana können Warnmeldungen eingerichtet werden, die basierend auf bestimmten Bedingungen ausgelöst werden. Es wurde eine Warnmeldung eingerichtet, die eine Push-Nachricht an ein Endgerät (Smartphone) sendet, wenn die Feuchtigkeit der Pflanze unter einen bestimmten Schwellenwert fällt. Dazu wird ebenfalls die Pushover-App verwendet, die auf dem Endgerät installiert sein muss. Pushover erlaubt es Push-Nachrichten an das Endgerät zu senden. Dazu kann entweder ein API-Aufruf genutzt werden oder die direkte Integration in zahlreiche Anwendungen, wie auch Grafana. Die App ist kostenlos für die ersten 30 Tage, danach kostet sie einmalig 5€. [Pushover] Um die Warnmeldung einzurichten, wird ein neuer Alert in Grafana erstellt. Dazu wird eine Bedingung definiert, die überprüft, ob die Feuchtigkeit unter einen bestimmten Schwellenwert fällt, wir haben diesen auf 460 festgelegt. Innerhalb des Alerts wird eine Beschreibung und Zusammenfassung hinzugefügt, ebenso wie die zu überwachende Metrik. Der angelegte Alert ist in folgender Abbildung zu sehen:

Abb. 3.5.2 Grafana Alert
Grafana überprüft den Mittelwert der letzten Messungen und prüft dann, ob dieser unter dem definierten Schwellwert liegt. Ist dies der Fall, wird eine Push-Nachricht an das verknüpfte Smartphone gesendet. Dass dies funktioniert, muss dem Alert ein sogenannter contact point hinzugefügt werden. Dort kann Pushover als Benachrichtigungsmethode ausgewählt werden. Im Anschluss muss ein API-Token von Pushover eingetragen werden. Wenn die beiden Dienste nun verknüpft sind, erhält man auf dem Smartphone die folgende Benachrichtigung, wenn die Feuchtigkeit unter den Schwellenwert fällt:

Abb. 3.5.3 Pushover Notification
3.6. Gescheiterte Pläne & Neue Ansätze
Zu Projektbeginn war der eigentliche Plan die Programmierung des ESP in RUST mit der VS Code IDE. Der chinesische Hersteller Espressif stellt dafür auch schon die ESP-IDF Erweiterung bereit.
Auf der Webseite https://wokwi.com haben wir dazu bereits die Software geplant und auf dem ESP simulieren lassen, jedoch konnten wir dies nicht übertragen. Von insgesammt 6 ESP8266 habe ich nur 1 zum laufen bekommen , alle anderen wurden zwar angezeigt, aber konnten nicht als Port in der Arduino IDE geschweige denn in VS Code aufgeführt werden (weder auf Linux, MacOS noch Windows).

Theoretisch hätte mit diesem einen ESP8266 das RUST Projekt funktionieren können, jedoch ist das leider einer der ersten ESP8266 und wird leider nicht wirklich von RUST supportet, weswegen wir auf C code in der Arduino IDE wechseln mussten.
Wir wollen diesem Projekt aber eine neue Chance geben und haben dafür neue ESP32 C3, ESP32 S3 und ESP32 C6 bestellt, mit diesen sollte dann auch die RUST Programmierung funktionieren.
Zusätzlich wollen wir mit diesem Ansatz auch ein RFID/NFC Entwicklungsboard einbinden und damit einige Tests durchführen.
3.7. Literaturangaben
Wikipedia-Eintrag Grafana https://de.wikipedia.org/wiki/Grafana (abgerufen am 30.04.2024)
Wikipedia-Eintrag InfluxDB https://de.wikipedia.org/wiki/InfluxDB (abgerufen am 30.04.2024)
Wikipedia-Eintrag Mikrocontroller https://de.wikipedia.org/wiki/Mikrocontroller (abgerufen am 30.04.2024)
Amazon AWS Hompage Docker https://aws.amazon.com/de/docker/ (abgerufen am 30.04.2024)
Influxdata Documentation: Get started with InfluxDB https://docs.influxdata.com/influxdb/v2/get-started/ (abgerufen am 30.04.2024)
Influxdata: InfluxDB Open Source. https://www.influxdata.com/products/influxdb/ (abgerufen am 30.04.2024)
RedHat: Was ist Grafana? https://www.redhat.com/de/topics/data-services/what-is-grafana (abgerufen am 30.04.2024)
Pushover: Pushover - Simple Notifications https://pushover.net/ (abgerufen am 30.04.2024)