Drip Master
Dieser Artikel beschreibt die Rolle des Drip Masters in unserer Software-Architektur. Falls Sie die Komponente nur einrichten und verwenden möchten, lesen Sie den Setup Guide.
Der Drip Master ist die wichtigste Komponente unseres Systems. Er steuert die tatsächliche Bewässerung der Pflanzen. In diesem Abschnitt wird die Funktionsweise des Drip Masters detailliert erklärt. Um einen Überblick zu gewinnen, sollten Sie zunächst die Grundlagen gelesen haben.
Der Drip Master kann in drei verschiedenen Modi laufen:
- Single Plant Offline Drip Cycle (
MODE_OFFLINE) - (Multiple) Plant Online Drip On Command (
MODE_WIFI_MQTT) - (Multiple) Plant Online Drip Cycle (
MODE_WIFI_MQTT_OFFLINE)
Unabhängig von diesen Modi ist unsere Software in folgende Module aufgeteilt:
Softwaremodule
Tank Handler
Der Tank Handler ist dafür zuständig, das aktuelle Tanklevel ("tank_level"), die Tankgröße ("tank_size") und das Tank Warning Level ("warning_level") zu verwalten. Dazu nutzt er den NVS (ein Key-Value-Store). Der Tank Handler bietet Funktionen, um diese Variablen zu bearbeiten bzw. sie auszulesen. Bei Änderungen wird automatisch der Device State (siehe Device State Handler) und das zugehörige MQTT-Topic aktualisiert (siehe MQTT Handler).
Device Handler
Der Device Handler verwaltet ähnlich wie der Tank Handler bestimmte globale Variablen im NVS. Er speichert für den WIFI_MQTT_OFFLINE Modus die Zykluszeit in Stunden ("sleep_time") und für jede Pflanze die Gießmenge ("plant_<id>"). Der Device Handler bietet Funktionen, um diese Variablen zu bearbeiten bzw. sie auszulesen. Bei Änderungen wird automatisch der Device State (siehe Device State Handler) und das zugehörige MQTT-Topic aktualisiert (siehe MQTT Handler).
Button Handler
Der Button Handler ist für den Reset-Button zuständig. In einem Polling-Task wird ein Knopfdruck erkannt und daraufhin der ESP aus dem Deep Sleep aufgeweckt und über den Tank Handler der Tank zurückgesetzt.
Drip Handler
Der Drip Handler ist für die direkte Steuerung der Ventile und der Pumpe zuständig. Er bietet beispielsweise die zentrale Funktion drip_on_plant(plant_id, ml), um eine Pflanze mit einer bestimmten Menge an Wasser zu bewässern.
WiFi Handler
Initialisiert und konfiguriert eine WiFi-Verbindung.
Device State Handler
Der Device State Handler bildet die Basis für die Kommunikation via MQTT. In einem struct werden hier alle zu veröffentlichenden Statusinformationen gehalten. Der MQTT Handler ist für das Teilen im JSON-Format verantwortlich.
{
"state": "IDLE" | "NO_WATER" | "BUSY" | "SLEEPING"
"last_error": string, // letzter Fehler
"tank_size": number, // in ml
"tank_level": number, // in ml
"warning_level": number, // in ml
"sleep_time": number, // in h
"low_alarm": boolean, // ob das tank_level unter warning_level ist
"plant_state_ml": number[] // in ml (nur im WIFI_MQTT_OFFLINE Modus)
"power_status": "CRITICAL" | "LOW" | "MEDIUM" | "GOOD" | "FULL" | "UNKNOWN" // aktueller Batterie Status für den Drip Master (nur im Drip Cycle Modus)
}
Diese sind stets aktuell. Der Tank Handler aktualisiert beispielsweise bei Änderungen von "tank_level", ... auch den Wert im struct. state meint den aktuellen Gießstatus:
IDLE: Warten auf GießbefehlNO_WATER: Tank ist leerBUSY: Pflanze wird gegossenSLEEPING: Im Deep Sleep, bis der nächste Gießzyklus beginnt
Battery Handler
Der Battery Handler ist dafür verantwortlich den aktuellen Akkustand der verwendeten Batterie festzustellen. Zentral ist die Funktion float power_get_battery_percentage(), die den aktuellen Akkustand in Prozent wiedergibt. Die Funktion misst die anliegende Spannung und vergleicht sie mit hardgecodeten Referenzwerten.
Aufgrund der Ungenauigkeit dieser Funktion, wird die Information in power_status_t power_get_status() in eine größere Abstufung (CRITICAl, LOW, MEDIUM, ...) unterteilt.
MQTT Handler
Der MQTT Handler ist für die gesamte Kommunikation über MQTT zuständig. Er initialisiert die Verbindung mit einem MQTT-Broker und registriert einen Event Handler, der auf die Events MQTT_EVENT_CONNECTED (mit Broker verbunden), MQTT_EVENT_DISCONNECTED (Verbindung mit Broker verloren) und MQTT_EVENT_DATA (Daten von abboniertem Topic erhalten) reagiert.
Der MQTT Handler ist die Kommunikationsschnittstelle zu Home Assistant.
Er reagiert auf Kommandos wie Gieße Pflanze 1 mit 30ml Wasser! oder Der Tank hat eine Größe von 500ml!, die über das Topic DripMaster/<MAC>/cmd und dessen Untertopics von Home Assistant verschickt werden.
Er teilt Home Assistant den aktuellen Device State (siehe Device State Handler) über das DripMaster/<MAC>/state Topic mit.
Die UI in Home Assistant wird über ein Home Assistant Discovery Topic Topic (<HomeAssistantDiscoveryTopic>/device/<MAC>/config) definiert. Dort werden auch die Kommandos definiert, die dann über die Kommando-Topics hereinkommen.
MQTT ist das Herz unserer Anwendung. Deshalb haben wir zusätzlich eine detaillierte Erklärung geschrieben.
JSON Handler
Der JSON Handler ist für die Erstellung des Home Assistant Discovery Topics im JSON-Format zuständig. Damit wird das Bewässerungssystem visuell in Home Assistant automatisch als Gerät dargestellt und kann dort konfiguriert werden. Es nutzt das DripMaster/<MAC>/state Topic als State Topic, kann also über das value_template jeder Komponente Daten darstellen. Für jede Komponente, die auch Aktionen ausführen soll, dient das command_template, die an das command_topic automatisch bei Änderungen (oder einem Button Klick) ein Command sendet.
Queue Handler
Der Queue Handler ist für die geordnete Bewässerung zuständig. Es geht also um den Fall, dass mehrere Pflanzen gleichzeitig bewässert werden sollen. Er stellt (via Mutex threadsafe) sicher, dass eine Pflanze nach der anderen bewässert wird. Im MODE_WIFI_MQTT Modus wird, wenn im MQTT Handler der Befehl hereinkommt, eine Pflanze zu bewässern, ein neues Item zur Queue hinzugefügt (Pflanzen-ID und Gießmenge) und in einem separaten Task abgearbeitet. Im MODE_WIFI_MQTT_OFFLINE wird die Queue ebenfalls verwendet. Hier wird in jedem Zyklus für jede Pflanze automatisch ein Item mit der eingestellten Gießmenge hinzugefügt.
Initialisierung
Die Initialisierung läuft zunächst unabhängig vom eingestellten Modus gleich.
-
MAC-Adresse auslesen: Als Erstes wird die MAC-Adresse ausgelesen und als UID gespeichert. Sie ist wichtig, damit der MQTT Handler weiß, welche Topics er abonnieren bzw. publishen muss.
-
NVS und Tank Handler initialisieren: Anschließend wird der NVS initialisiert. Danach wird der Tank Handler initialisiert. Das bedeutet, dass dort ein NVS Handle geöffnet wird, um Werte ein- und auszulesen.
-
Button Handler initialisieren: Als Nächstes wird der Button Handler initialisiert, d. h. ein GPIO wird als Input konfiguriert und der Polling Task erstellt, der beim Drücken den ESP aufweckt und den Tank zurücksetzt.
-
Drip Handler initialisieren: Dann wird der Drip Handler initialisiert, der die GPIOs für die Pumpe und alle Ventile als Output konfiguriert.
-
Battery Handler initialisieren: Dann wird der Battery Handler initialisiert. D.h. alle Handler, die zum Auslesen des ADC's notwendig sind, werden erstellt und konfiguriert. Anschließend wird eine Testmessung durchgeführt und ausgegeben.
-
Device Handler und Device State initialisieren: Last but not least wird der Device Handler initialisiert, der ähnlich wie beim Tank Handler ein NVS Handle öffnet. Zudem wird der Device State Handler initialisiert, d. h. das struct mit Standardwerten gefüllt.
-
Modusabhängiges Verhalten: Schließlich verhält sich die Software je nach eingestelltem Modus verschieden.
Im MODE_OFFLINE wird Pflanze 0 bewässert, dann legt sich der ESP schlafen und wartet für eine festgelegte Zeit. Dies geschieht fortlaufend.
Im MODE_WIFI_MQTT wird das WiFi via WiFi Handler initialisiert. Anschließend wird die Queue erstellt, die MQTT-Verbindung geöffnet und der Queue Processor, der die Queue fortlaufend abarbeitet, gestartet. Somit wird auf von Home Assistant hereinkommende Kommandos gewartet und bei Bedarf reagiert.
Im MODE_WIFI_MQTT_OFFLINE wird ebenfalls das WiFi via WiFi Handler initialisiert. Anschließend wird die Queue erstellt, die MQTT-Verbindung geöffnet und der Queue Processor, der die Queue fortlaufend abarbeitet, gestartet. Somit wird auf von Home Assistant hereinkommende Kommandos gewartet und bei Bedarf reagiert. Der einzige Unterschied ist, dass das Gießkommando nicht zum Gießen führt, sondern nur einstellt, wie viele Milliliter eine jeweilige Pflanze im Zyklus erhält. Zudem wird der Gießzyklus gestartet, der alle Pflanzen wie eingestellt gießt und sich danach für die konfigurierte Zeit schlafen legt. Dies wird wie im MODE_OFFLINE fortlaufend wiederholt.