Ich habe bisher unter Verwendung eines Raspberry Pi 3, eines Shelly 1, eines Magnetventils per Mosquitto (MQTT Broker) und Node-RED eine Dauer gesteuerte Bewässerung realisiert. Als Mensch Maschinen Schnittstelle (Handhabungsgerät) kann man ein Smartphone mit MQTT Dash App, eine Website (Node-RED Dashboard) oder auch ein Amazon Echo einsetzen, letzteres etwas eingeschränkt. Im Display des Smartphones und auf der Website wird nach dem Starten der Bewässerung die Restdauer angezeigt - alles parallel. Man kann somit den Vorgang von jedem passend eingerichteten Gerät aus verfolgen und steuern - MQTT halt. Dies gelingt auch remote per Internetzugriff. ;-)

Das Magnetventil ist eine Energie sparende Version aus China für 12V und selbstschließend. Weil der shelly 1 auch mit 12V betreibbar ist, brauche ich für den Betrieb nur ein 12V Netzteil. Man könnte auch eine Autobatterie dafür einsetzen.

Obwohl die Anwendung gut funktioniert, stört es mich, dass die ganze Last der Raspberry Pi 3 mit Node-RED tragen muss ... und was geschieht mit der Bewässerung, wenn Node-RED dort mal ausfallen sollte? Es ist ohnehin besser, ein Gerät (ESP8266) mit hinreichenden Fähigkeiten auszustatten, damit es eigenständig einen erteilten Auftrag erfüllen kann. Das kann ein Shelly mit Original-Firmware nicht, aber bspw. mit geflashtem Tasmota. 

Somit arbeite ich an einer Lösung auf Basis des Shelly und Tasmota, welche die komplette Zeitsteuerung dem µC überlässt. Eines der fortgeschritteneren Ziele ist, die MQTT Kommunikation weitestgehend, soweit möglich, unabhängig von Node-RED Flows laufen zu lassen. Dieses Ziel habe ich fast erreicht, es bleibt nur noch eine Fehlstelle, deren Ursache in MQTT Dash liegt. Wenn ich dort vor dem Senden der Payload an der Nachricht manipulieren kann, beseitige ich auch diese letzte Fehlstelle. Dazu fehlen mir noch Informationen zu MQTT Dash.

Gegenwärtig setze ich einen sehr kleinen Node-RED Flow als Workaround ein. MQTT-Dash versendet eine Nachricht mit dem Topic cmnd/test/rule/<Triggername> und dem Payload <Zahlenwert>. Der Node-RED Flow konvertiert dies in Topic: cmnd/test/event und Payload: <Triggername>=<Zahlenwert>.

Der kleine Workaround Flow - im Funktions Node steckt JavaScript Code
Inzwischen weiß ich, dass solche Adapter fast unvermeidbar sind.

Die Zeitsteuerung der Bewässerung basiert auf dem Prinzip eines retriggerbaren Monoflops. Zur Implementierung des Monoflops habe ich mich ausdauernd durch die Tasmota Rules geärgert. Diese Regeln gestatten eine Parametrierung und schrittweise Steuerung der Bewässerung. Zwecks Perfektionierung arbeitet das Monoflop Perioden ab, deren Dauer der Anwender einstellen kann, wenn er/sie denn will. Man kann diese Periodendauer auch fest einstellen, bspw. 60s, und dem Anwender keine Möglichkeit der Veränderung geben, obwohl es dazu eine Kommunikationsschnittstelle gibt.

  1. Man kann die Dauer der Perioden in Sekunden einstellen (s.o.). Diese Einstellung wird im Flash des µC gespeichert.

  2. Man stellt die Bewässerungsdauer ein oder belässt es bei dem angezeigten Wert.
    Diese Dauer ist/wird im RAM des µC gespeichert.

  3. Man startet die Bewässerung und kann sich darauf verlassen, dass nach Ablauf der Dauer die Bewässerung gestoppt wird.
    Hierzu erhält der µC eine MQTT Nachricht, die den Trigger einer Tasmota Rule enthält (siehe Tasmota).

  4. Die Bewässerung stoppt nach Ablauf der eingestellten Dauer (variabel) automatisch.
    Die gegenwärtig eingestellte Dauer wird auf dem verwendeten Handhabungsgerät angezeigt.
    Soweit, dass Alexa dies sprachlich mitteilt, bin ich noch lange nicht. Allerdings glaube ich, dass dies bereits möglich wäre (AWS ...).

  5. Optionale Handhabung: Die Bewässerung wird vorzeitig gestoppt.
    Es folgt das Gleiche wie unter 4.

Abbildungen zur Handhabung per Android App MQTT Dash

 

Sobald ein Anwender die Beregnung startet, während eine Beregnung bereits läuft, beginnt die Zeit von vorne abzulaufen. Wie er die Beregnung startet ist total unerheblich. Dies kann durch einen Taster, durch eine App oder sonstwas geschehen. Immer dann, wenn der Power1 Ausgang auf High wechselt, wird das Monoflop getriggert und schaltet automatisch nach Ablauf den Ausgang auf Low. Selbstverständlich lässt sich die Bewässerung vorzeitig abschalten. Zusätzlich lässt sich das Monoflop triggern durch starten des Ereignisses event mobeg (s.u.), bspw. von der Tasmota Konsole oder meiner in Node-RED erstellten Konsole.

Übrigens - eine Rasenberegnung per Webseite gesteuert arbeitet seit etwa 2 Jahren störungsfrei, auf Basis eines Arduino Uno, eines Banana Pi und von mir ziemlich proprietär erstellter Software. Damals kannte ich MQTT, Node-RED, ... noch nicht.

Mein Gartenbewässerungsprojekt mit Tasmota-Rules

Inzwischen habe ich einige (höchtwahrscheinlich) fehlerfreie Rules hierfür zusammengestellt, die unten dargelegt werden.

Warum erstelle ich relativ aufwändig Rules für ein Monoflop-Verhalten? Man kann auch einfach die Pulslänge des Ausgangs zur Relaisteuerung per

PulseTime <Dauer in Sekunden>

einstellen und danach das Relais für das Magnetventil einschalten.

Gründe, die gegen eine solche sehr einfache Lösung sprechen:

  1. Die Pulsdauer wird persistent gespeichert, also im Flash des µC. Zur Bewässerung werden aber nicht immer die gleichen Dauern eingestellt. Somit sind relativ häufige Änderungen der Pulsdauer erforderlich, was viele Schreibvorgänge im Flash zur Folge hat und den Flash relativ schnell altern lässt. Vermutlich ist diese Vorsicht übertrieben, ich sehe aber keinen Grund, dies nicht zu berücksichtigen. Die 16 Variablen Var1 bis Var16 sind Speicherplätze im RAM des µC. Ein RAM erträgt erheblich mehr Schreibvorgänge als ein Flashspeicher. Auch die 8 RuleTimer sind sicherlich durch mindestens eine Interrupt Service Routine (ISR) implementiert, die schlicht Speicherplätze im RAM dekrementiert.

  2. Es fehlt an Komfort. Ich möchte auf dem Display meines (alten) Smartphones sehen können, wie lange noch bewässert wird. Hierfür ließe sich die TelePeriod Einstellung nutzen, bspw. auf 60s stellen. Dann liefert Tasmota in minütlichen Abständen u.a. Sensorwerte und die Pulsdauer sowie die verbleibende Restdauer. Damit würden auch jedesmal die Werte aller Sensoren und Schaltausgänge geliefert werden, was zumeist nicht interessiert. Es dürfte zumeist genügen, wenn bspw. Temperaturen einmal in der Stunde erfasst und ggf. gespeichert werden.

  3. Falls man mit demselben µC neben der Monoflop Steuerung Messwerte erfassen will, wird man in den meisten Fällen eine für Messungen geeignete und feste TelePeriod Einstellung nutzen wollen. Dies widerspricht der gleichzeitigen TelePeriod Nutzung für das Monoflop Verhalten.

Zusammenstellung der MQTT Topics

Struktur: pre/device/special
pre = %mem1% (bspw. zuhause)
device = %topic% (dasjenige des Tasmota Systems)
special hängt jeweils von der konkreten Nachricht ab.

Generelle Überlegungen

  • Auslöser möglichst am entscheidenden Ereignis festmachen. Hier wird Power1 als Auslöser zum starten und zum beenden verwendet. Was diesen Ausgang manipuliert, ist bedeutungslos. Zusätzlich muss das Monoflop nach Ablauf der Zeit Power1 ausschalten.
  • Vor dem "Einpflanzen" der Regeln ist es für Tests und Fehlersuche sehr hilfreich, die Telemetry Nachrichten auszuschalten (teleperiod 0).
  • Wenn eine Regel nur einmal verwendet wird, kann diese Regel in die auslösende Regel verschoben werden. Dies dient zwar nicht der Übersicht, kann aber Platz einsparen. Ich stehe allerdings mit dem Backlog noch auf dem Kriegsfuß, weil ich nicht sehen kann, wann bzw. in welcher Reihenfolge die Aktionen hinter Backlog ausgeführt werden.

Vorarbeit

Festlegen, wo Parameter und laufende Werte gespeichert werden.
Hier pre-topic:mem1, Periodendauer:mem2, Dauer:var1, Restdauer:var2, bereinigte Periodendauer:var3

Versuche zeigten, dass der RuleTimer immer eine Sekunde länger läuft als seine Initialisierung angibt. Für 5s muss der Timer also mit 4 initialisiert werden ... Deshalb wird zu Beginn Mem2 in Var3 kopiert und Var3 dekrementiert. Dies ist der Initialisierungswert für den Timer. Vielleicht ist die erste Periode 1s länger als die restlichen. Dies stört mich aber nicht. Es sind eh Latenzen von ca. 2-3s enthalten, die systembedingt mit meinen Vorgaben unvermeidbar sind. Und schließlich braucht das Wasser etwas Zeit, bis es aus dem Perlschlauch austritt. ;-)

Die Rules

Die Triggernamen der folgenden Regelsätze 1 und 2 müssen in den MQTT Topics verwendet werden, damit die Kommunikation Wirkung hat. Für weitere Rules könnte der Rulespeicher eng werden, weshalb ich die Triggernamen kurz halte. Das sind hier purem, puper, modur, moper, mobeg und moend.

Die Regelsätze 1, 2 und 4 passen leicht in rule1. Regelsatz 3 in rule2 packen! So bleibt für weiteres (Experimente) noch rule3 frei.

1. Regelsatz für publish, Input: Payload
//veröffentlicht die verbleibende Dauer (morem = monoflop remain) mit retain flag
on event#purem do publish2 %mem1%/%topic%/morem %value% endon
//veröffentlicht die Periodendauer (moper = monoflop period) mit retain flag
on event#puper do publish2 %mem1%/%topic%/moper %value% endon

2. Regelsatz für empfangene Parameter (Periode, Dauer)
//Input: Dauer
on event#modur do backlog var1 %value%;event purem=%value% endon
//Input: Periode
on event#moper do backlog mem2 %value%; event puper=%value% endon

3. Regelsatz zur Implementierung des Monoflops
//Starten des Monoflops, var3 <- Periodendauer-1, ruletimer1 <- var3, Power1 ein, Restdauer dekrementieren
on event#mobeg do backlog var2 %var1%;var3 %mem2%;sub3 1;ruletimer1 %var3%;event purem=%var1%;sub2 1 endon
//Timer1 abgelaufen -> Timer1 neu starten, Restdauer veröffentlichen, Restdauer dekrementieren
on rules#timer=1 do backlog ruletimer1 %var3%;event purem=%var2%;sub2 1 endon
//Monoflopzeit abgelaufen (Restdauer<0) -> Power1 aus (power1 0 -> event moend)
on var2#state<0 do power1 0 endon
//Monoflop aus -> RuleTimer1 aus, Dauer veröffentlichen - in Restzeitanzeige erscheint die Dauer
on event#moend do backlog ruletimer1 0;event purem=%var1% endon

4. Regelsatz für Ereignisse Zustandsänderungen des Ausgangs (Power1), unabhängig vom Auslöser
So wird sichergestellt, dass Power1 immer das Verhalten eines retriggerbaren Monoflops besitzt, solange die Regeln aktiv sind.
//Beenden des Monoflops, wenn Power1 ausgeschaltet wird
on power1#state=0 do event moend endon
//Starten des Monoflops, wenn Power1 eingeschaltet wird
on power1#state=1 do event mobeg endon

Abhängig von weiteren Aufgaben desselben µC kann es sehr ratsam sein, mit folgenden Kommandos nützliches Verhalten einzustellen.

Mit einem Neustart des µC alle Power-Ausgange auf off stellen:
PowerOnState 0

Alle Nachrichten aufgrund von Power Zustandsänderungen mit dem MQTT retain versehen:
PowerRetain 1

Mit Letzterem wird erreicht, dass jedes Gerät, welches sich später beim MQTT Broker und entsprechenden subscriber topics anmeldet, die letzten (aktuellen) Zustände der Power Ausgänge erhält. Aktuell sind diese Zustände selbstverständlich nur, wenn der µC nicht ausgefallen ist. Hierzu wäre noch die MQTT LWT Nachricht zu prüfen ... 

Hinweise für weitere Implementierungen mit beliebigen Umgebungen

Die Aufteilung eines Triggers auf das Topic und die Payload einer MQTT Nachricht habe ich unter Tasmota / Tasmota Regeln beschrieben. Wenn beispielsweise die Dauer auf 15 Perioden eingestellt werden soll, ist folgende Nachricht zu versenden:

{topic: cmnd/test/event, payload: modur=15} Darin ist "test" der MQTT Gerätename und kann leicht geändert werden.

Gestartet wird per {topic: cmnd/test/event, payload: mobeg}, beendet mit {topic: cmnd/test/event, payload: moend}.

Parallel zu diesem Monoflop kann der µC einige weitere Aufgaben bearbeiten.

Funktionssicherheit herstellen

Empfehlung:
PowerOnState 0 und die Schaltung um den µC so auslegen, dass im stromlosen Zustand nichts eingeschaltet ist, was nicht eingeschaltet bleiben muss - in üblichen Haushalten kein Gerät außer vielleicht der Heizung und der Kühlgeräte. Und diese sollten doch besser nicht durch einen µC geschaltet werden. ^^ 

Kleiner Ausblick

In der fertigen Node-RED Anwendung lässt sich die Startzeit der nächsten Bewässerung eingeben. Dieser Zeitpunkt wird automatisch auf den nächsten Tag gesetzt, wenn er im aktuellen Tag bereits verstrichen ist. Dies ist deshalb sehr praktisch, weil eine tropfende Bewässerung zumeist in der Nacht am effizientesten ist. Diesen Komfort werde ich vielleicht in Tasmota (per Regeln) nicht implementieren können. Dies bleibt voraussichtlich einer im Hintergrund arbeitenden Node-RED Anwendung überlassen, welche schlicht ein MQTT Suscriber und Publisher ist.

Zukünftig will ich (selbstverständlich) noch Feuchtigkeitsmessungen implementieren, damit man auch aus der Ferne erfassen kann, ob eine Bewässerung angemessen ist. Eine Automatisierung wäre dann zwar möglich, sehe ich aber nicht vor. Wasser könnte evtl. für eine Gartenbewässerung zu wertvoll werden. Da möchten wir lieber selbst entscheiden, wann bewässert werden soll.

...

2020-04-07

- Fortsetzung folgt (vielleicht) -