,

🌱HydroPi🌱 – Damit auch du deinen Garten vom Sofa aus gießen kannst.

Steffen Fingerle

⚠️ Disclaimer

Da das Projekt keinerlei Sicherheitsaspekte abdeckt, ist es aufgrund einer sehr hohen IT-Security Gefahr mit möglicherweise schweren Folgen nicht für die Nutzung außerhalb des eigenen Heimnetzwerkes ausgelegt.

🌱 Motivation

Aus aktuellem Anlass in der Entwicklung von Smart Home Technologien existiert ein stetig wachsendes Interesse, auch in der eigenen Wohnung aktuelle Bequemlichkeiten wie Staubsaugerroboter, Sprachassistenten oder Kontrollmechanismen, die einem den Alltag erleichtern zu implementieren. So wächst auch das Interesse wie man diese Funktionalitäten in anderen Lebensbereichen nutzen kann. Daraus resultierte die Frage, inwiefern man eine sehr routine-basierte und alltägliche Aufgabe wie das Bewässern des Gartens oder der eigenen Innenpflanzen automatisieren kann. Dies würde dem Nutzer nicht nur Zeit und Aufwand im Alltag sparen, sondern auch die Möglichkeit eröffnen, nicht vor Ort sein zu müssen und ganz unbesorgt auch für längere Zeit unterwegs sein zu können, ohne Nachbarn bitten zu müssen sich um seine Pflanzen zu kümmern. Obwohl es bereits SmartHome Lösungen gibt und diese sich auch stetig weiterentwickeln und verbessern, sind sie meistens sehr kostspielig und noch nicht für die breite Masse verwendbar. Deshalb wäre ein Konzept wie man sich auch schon mit geringeren Kosten eine SmartHome Bewässerungsanlage im eigenen Heim installieren könnte noch für viele Menschen interessant.

Die Motivation für das Projekt war nicht nur das vorgesehene Pflichtprojekt im Studium zu absolvieren, sondern auch das bisher in Vorlesungen erlangte Wissen in einer praktischen Anwendung zusammen zu tragen und durch neue notwendige Technologien zu ergänzen. Dabei war es uns besonders wichtig viele neue Technologien kennenzulernen.

Ziel war es eine Art Interface für Magnetventile auf einer Website zu realisieren die dann ein Relais mit passender Business-Logik ansteuern kann. Das ist auch nur möglich, solange man sich entweder im Heimnetzwerk befindet oder ein VPN benutzt. Unser “Produkt” ist eine Software-Lösung die eine Menge Hardware-Recherche mit sich bringt für DIY-Begeisterte. Deshalb wird im folgenden kurz auf die Hardware eingegangen und anschließend sprechen wir dann über den Software-Teil des Projekts.

🌱 Unsere Hardware

Hier ist ein schematischer Aufbau unseres Bewässerungssystems:

Der Raspberry Pi – Ein Mini Computer für viele Zwecke!

Als Basis für unser Projekt war uns bereits im Vorfeld klar, dass wir einen Raspberry Pi brauchen. Dieser ermöglicht es uns einen lokalen Server zu hosten, als auch über die GPIO-Pins Dinge auszulesen oder anzusteuern. Wir haben uns für einen Raspberry 3b+ entschieden, der mit dem Betriebssystem Raspbian vorinstalliert ankam, um keine Probleme durch zu langsame CPU oder RAM zu haben. Allerdings könnte man auch eine ältere Version verwenden, solange es genügend freie Pins für den Anwendungsfall gibt.

Das Relais – Viel einfacher lassen sich Stromkreise nicht schalten!

Um Schaltkreise öffnen und schließen zu können eignen sich in der Elektrotechnik sogenannte Relais. Mit ihrer Hilfe wird bei einem Output-Signal am verbunden GPIO-Pin ein Kanal geöffnet und damit der Stromkreis geschlossen. In unserem Fall nutzen wir sie, um Magnetventile zu öffnen. Wir verwenden ein Relais-Board mit mehreren Kanälen, welches sich leicht auf die gesamte Reihe der GPIO-Pins setzen lässt. Bei diesen ist es wichtig, sich den Schaltplan anzuschauen und herauszufinden, welcher Pin welchen Kanal anspricht. Man kann aber auch pro Ventil ein einzelnes Relaisboard verwenden, bei korrektem Anschluss greift dasselbe Prinzip.

Die Magnetventile und das Netzteil zur Stromversorgung!

Magnetventile kann man in einen Wasserdurchfluss einbauen und somit steuern, wann Wasser fließen soll. Sie sind standardmäßig stromlos geschlossen. Wichtig für das Bewässerungssystem ist es sich zu überlegen, wieviele Ventile man braucht und wieviele man eventuell gleichzeitig betreiben möchte. Das Netzteil, welches den Strom für unseren Magnetventil-Schaltkreis liefert, sollte anhand dieser Entscheidungen ausgewählt werden. Um Kosten für unser Projekt zu sparen haben wir nur ein Magnetventil gekauft, welches eine Spannung von 12V und eine Stromstärke von 1,6 Ampere benötigt. Möchte man in der Lage sein zum Beispiel drei Magnetventile gleichzeitig zu öffnen, sieht das ganze in etwa so aus:

Parallelschaltung der Magnetventile

Soll keine gleichzeitige Öffnung der Magnetventile möglich sein, reicht es ein Netzteil auszuwählen das mit ein wenig Stromverlust ein einzelnes Magnetventil versorgen kann. Man sollte immer auf einen korrekten Anschluss und die Einhaltung der Flussrichtung der Magnetventile achten.

Der Feuchtigkeitssensor – Eine ganz andere Herausforderung!

Bei den Feuchtigkeitssensoren gibt es eine sehr große Auswahl an Funktionalität und Qualität, weshalb es schwer ist ein System für alle Hersteller zu entwickeln. Aus Kostengründen haben wir uns für ein billigeres Exemplar entschieden, da wir testen wollten inwiefern wir in unserem Projekt dafür Verwendung finden können. Für die Stromversorgung des Sensors reicht in unserer Anwendung ein 3,3V/5V Pin des Pi’s. Leider wurde uns erst später bewusst, dass bei diesem Produkt über ein digitales Output nur erkennbar wurde, ob Feuchtigkeit gemessen wird oder nicht. Um mit dem Raspberry Pi genauere Feuchtigkeitswerte auslesen zu können, mussten wir das analoge Output des Sensors in ein digitales umwandeln. Das könnte man mit Hilfe eines Arduino’s schaffen, wir haben dafür einen Analog-Digital Converter MCP3008 verwendet. Wir empfehlen jedoch eher die Verwendung eines besseren Sensors, um sich die Arbeit beim Löten und auch das Risiko eines fragilen Systems zu sparen. Bisher sind die Feuchtigkeitsdaten in unserer Anwendung rein zur Informationsdarstellung verwendet worden, sodass der Nutzer selbst entscheiden kann, ob gewässert werden sollte oder nicht. Später könnte das System anhand dieser Daten die Bewässerung starten oder aussetzen lassen.

🌱 Unsere Software-Lösung

Da wir viele notwendige u. a. netzwerktechnische Sicherheitsaspekte nicht im Rahmen des Projektes umsetzen können, haben wir uns dazu entschieden HydroPi nur im Heimnetzwerk einsetzbar zu machen. So ist HydroPi nur im eigenen LAN zu erreichen und jeder Client von außerhalb muss sich daher via VPN mit dem Heimnetzwerk verbinden. Dabei empfehlen wir immer mit VPN Zertifikaten und einer SSH Verbindung zu arbeiten.

Grundsätzlich passiert die Business-Logik also Auslesung & Verwertung von Sensordaten sowie geplante Ansteuerung von Magnetventilen auf dem Server. Dieser speichert und liest Daten aus der Datenbank und versorgt die Clients mit neuen Werten. Präzisere Informationen zur Software Architektur findest du im Abschnitt Back-End.

Unsere Datenbank – Persistente Datenspeicherung!

Um Daten auch persistent speichern zu können haben wir uns für eine lokale Datenbank entschieden. Da die Hardware mit Python Skripts gesteuert wird benutzen wir die in Python implementierte SQLite3 Library. 

Das oben dargestellte physische Entity-Relationship Diagramm bildet alle Tabellen der Datenbank und deren Relationen zueinander ab. Über die Hilfstabelle “planXChannel” lassen sich alle Pläne und deren dazugehörigen Magnetventile speichern und verwerten.

Back-End – Der Server und Business-Logik!

Wir haben uns dafür entschieden den Server mit der plattformübergreifenden Open-Source-JavaScript-Laufzeitumgebung Node.js laufen zu lassen. Der Node Package Manager, kurz NPM, bringt viele Möglichkeiten mit sich um Projekte wie dieses zu verwirklichen. Genutzt werden die Packages Express, Socket.io, cron-job-manager, Winston, Python-shell, Knex und selbstverständlich SQLite3.

Bevor wir aber an dieser Stelle auf die Packages und deren Einsatz eingehen springen wir kurz in die Python Skripts, die ebenfalls auf dem Server, also dem Raspberry Pi liegen. Es werden gezielt GPIO Pins, in unserem Fall 20, 21 und 26 angesprochen und damit Signale an das Relais gesendet um das jeweilige Magnetventil zu öffnen. Das dazugehörige Skript irrigationController.py benötigt die Parameter –c (Kanäle) und –d (Dauer) und wird über das Node Package Python-shell ausgeführt.

Genau wie das Skript sensor.py, das dazu dient die aktuelle Feuchtigkeit zu ermitteln. Damit Messfehler vermeiden werden führt es zur Laufzeit mehrere Messungen durch, ermittelt deren Median und speichert das Ergebnis in die SQLite Datenbank.

Um die Skripte nun zu festgelegten Zeiten auszuführen, werden Cronjobs benötigt. Dies ist zwar auch über die native Variante möglich, jedoch wäre der Aufwand diese zu verwalten sehr hoch. Aus diesem Grund haben wir uns für das Node Package cron-job-manager entschieden. 

Im folgenden Code-Abschnitt lässt sich entnehmen, wie aus einem Bewässerungsplan, bestehend aus den einzelnen Wochentagen, die wiederum die jeweils definierte Zeit beinhalten, die dazugehörigen Cronjobs generiert werden:

weekdays.forEach(function (day, index) {
    //if != null 
    if (day) {
 
      // each day needs its own cronID,
      // since CronJobs are scheduled separately by day
      const cronID = composeCronID(plan.planID, index);
 
      // setup CronJob
      manager.add(cronID, day, function () {
        runIrrigation(valvesString, durations[index]);
      });
 
      // schedule CronJob
      manager.start(cronID);
    }
});

Das Managen der Cronjobs ist dadurch mit relativ wenig Aufwand zu bewerkstelligen. So zum Beispiel:
Aktualisieren:

manager.update(cronID, day, function (){
  runIrrigation(valvesString, durations[index]);
});

Löschen:

manager.deleteJob(cronID)

Sobald nun neue Daten für Bewässerungspläne eintreffen, müssen sie in die Datenbank gespeichert und die entsprechenden Cronjobs verwaltet werden. Das führt uns zu den (socket.io) WebSockets, mit deren Hilfe die Kommunikation zwischen Server und Client realisiert wird.

Um diesen Vorgang mit einem simplen Beispiel zu veranschaulichen, werfen wir einen Blick auf den “deletePlan”-Socket, der wie der Name schon verrät, uns darüber informiert welchen Bewässerungsplan der Client löschen möchte:

socket.on("deletePlan", async function(plan){
  try {
    // delete plan
    await db.deleteEntity('irrigationPlans', 'planID', plan.planID);
    // delete related plan channels
    await db.deleteEntity('planXChannel', 'planID', plan.planID);
      
    // delete CronJobs
    cron.deleteJobsFromIrrigationPlan(plan);
 
  } catch (error) {
    logger.error(error);
  }
});

Im Front-End wird der Socket dann nur noch über folgenden Befehl angesprochen und der zu löschende Plan mitgegeben:

socket.emit('deletePlan', plan)

Das senden von Daten ist natürlich in beide Richtungen und an einen bestimmten bzw. alle verbundenen Clients möglich. So wird z.B. bei der Messung neuer Feuchtigkeitswerte der aktuelle Wert an alle verbundenen Clients gesendet, um das UI zu aktualisieren. Durch den Verzicht auf Polling werden sowohl System- als auch Netzwerkressourcen gespart.

Front-End – Die Website und was sie kann!

Design und Usability des Front-Ends hatten keine Priorität, daher ist das Front-End hauptsächlich funktionell. Programmiert wurde es größtenteils aus JavaScript mit kleinen Teilen HTML und CSS. Im Folgenden wird das Webinterface gezeigt und erklärt.

Standardansicht

1 Datums- und Uhrzeitanzeige mit HydroPi-Logo
Im oberen Bereich der Webseite befindet sich neben dem HydroPi-Logo, eine Anzeige des aktuellen Datums und der Uhrzeit. Die Informationen stammen dabei von den Systemdaten des Raspberry Pi und sind somit immer lokal an die Daten des Einsatzortes angepasst. Dies ist relevant, falls man von einem Standort mit Zeitverschiebung auf die Webseite zugreift.

2 Bewässerungspläne 
Diese Elemente dienen als Buttons zur Erstellung von Bewässerungsplänen, aber auch zur Anzeige und zum nachträglichen Ändern von bereits erstellten Plänen.

3 Feuchtigkeitsanzeige
Darstellung der aktuell gemessenen Feuchtigkeit des Feuchtigkeitssensors in Prozent.

4 Ventil Anzeige
Die Menge der angezeigten Ventile ist abhängig von der beim Setup eingestellten Anzahl der Ventile. Die Anzeige zeigt an, ob ein Ventil gerade geöffnet (blau gekennzeichnet) oder geschlossen ist (ausgegraut).

Ansicht bei Erstellung/Änderung eines Bewässerungsplanes

5 Ventilauswahl
Auswahl von gewünschten Ventilen über Tile-Elemente. Ausgewählte Elemente werden hervorgehoben.

6 Wochentag Auswahl
Auswahl von Wochentagen an denen gewässert werden soll, mit Einstellungen zur genauen Uhrzeit und Dauer in Sekunden. Standardmäßig sind alle Tage ausgegraut. Erst durch Klick des Benutzers werden die gewünschten Tage mit Uhrzeit und Dauer visuell hervorgehoben.

🌱 Ausblick 👀

Dieses Projekt bietet eine solide Grundlage und viele Möglichkeiten zur Erweiterung, die aufgrund des begrenzten Zeitraumes nicht implementiert werden konnten. So ist es bisher nur per Computer und mit gewissen Einschränkungen auch per Smartphone nutzbar. Dies ist allerdings auch nur möglich, solange man sich entweder im selben Netzwerk befindet oder ein VPN benutzt. Daher ist das Nächstliegende die Erweiterung der Verbindungsmöglichkeiten und die Entwicklung einer passenden IOS oder Android Applikation. Im Bereich des Front-Ends könnten Design und Usability überarbeitet und Frameworks und Libraries in Betracht gezogen werden. Im Back-End Bereich könnte die Datenbank optimiert und eine Wetter API eingebunden werden, welche wiederum im Front-End das aktuelle Wetter mit Niederschlag auf der Webseite anzeigen könnte. Mögliche Erweiterungen an das System an sich könnten dem Nutzer die Möglichkeit geben, eine Bewässerungsgrenze anzugeben ab der die Bewässerung automatisch startet. Für die Sicherheit des Systems wäre es auch vorteilhaft, einen Sensor einzubauen der den Wasserfluss kontrolliert um vor eventuellen Wasserschäden zu warnen.


 


Posted

in

,

by

Steffen Fingerle

Tags:

Comments

Leave a Reply