Das Problem ist, dass Du versuchst, einer globalen Variablen bei der Definition einen dynamischen Wert zuzuweisen, das ist nicht erlaubt.
Es gibt tatsächlich eine Ausnahme der Regel, nämlich die Zuweisung einer Action, aber selbst da ist es besser, das innerhalb der Rule zu erledigen.
Die Rule als solche ist auch eher fragwürdig, zumindest passt das, was die Rule aktuell tut, nicht zu dem, was Du beschreibst.
Ich nehme mal an, die Beregnung wird von einer anderen Rule eingeschaltet.

Aber so, wie die Rule geschrieben ist, wird ja nun gar nichts gesteuert. Oder ist das nur der erste Versuch?
So als erster Entwurf (wobei da verschiedene Fragen auftauchen):
Code: Alles auswählen
// Globale Variablen zu Beginn der Datei definieren!
var Number nWasseruhrAlt = null
rule "Beregnung Start"
when
Item Bewaesserungsautomatik changed to ON // Beregnung gestartet
then
Beregner.sendCommand(ON) // oder erst später in der Rule, falls der Fehler den Start verhindern soll
if(!(Rasen_Zaehlerstand_Wasseruhr.state instanceof Number)) { // Zählerstand ist keine gültige Zahl
logWarn("sprinkling","Beregnungsstart - Zählerstand kann nicht abgerufen werden!") // Warnmeldung
return; // Und Abbruch der Rule
}
nWasseruhrAlt = (Rasen_Zaehlerstand_Wasseruhr.state as Number) // alten Zählerstand retten
logInfo("sprinkling","Zählerstand bei Start: {} cm³",nWasseruhrAlt) // und Erfolg melden
end
rule "Beregnung Stop"
when
Item Rasen_Zaehlerstand_Wasseruhr changed
then
if(Beregner.state != ON || Bewaesserungsautomatik.state != ON) { // Kein Automatikbetrieb
return; // Deshalb Abbruch
}
if(!(Rasen_Zaehlerstand_Wasseruhr.state instanceof Number)) { // Zählerstand ist keine gültige Zahl
logWarn("sprinkling","Beregnungsstop - Zählerstand kann nicht abgerufen werden!") // Warnmeldung
return; // Und Abbruch der Rule
}
if(nWasseruhrAlt === null) { // Alter Zählerstand nicht gesetzt
logWarn("sprinkling","Beregnungsstop - Kein Vergleichszählerstand!") // Warnmeldung
return; // Und Abbruch der Rule
}
val nWasseruhrNeu = Rasen_Zaehlerstand_Wasseruhr.state as Number // aktueller Zählerstand
if(nWasseruhrAlt + 1000 <= nWasseruhrNeu) { // mindestens 1000 Liter gezapft
Beregner.sendCommand(OFF) // Beregner ausschalten
logInfo("sprinkling","Zählerstand bei Stop: {} cm³",nWasseruhrNeu) // Meldung ausgeben
nWasseruhrAlt = null // alten Zählerstand löschen
Bewaesserungsautomatik.sendCommand(OFF) // Automatik beenden
}
end
Die aufkommenden Fragen:
- Ich würde eher erwarten, die Beregnung entweder durch Messwerte zu starten (Boden zu trocken/x Tage kein Regen/bestimmte Zeiten) und einen Schalter vorzusehen, der den automatischen Start unterdrückt (also bei Erreichen der Startbedingung(en) zunächst prüfen, ob die Automatik aktiv ist, statt die Rule dadurch zu triggern)
- Wie soll sich die Rule verhalten, wenn der Fehlerfall eintritt, also z.B. die Wasseruhr nicht ausgelesen werden kann?
- Was soll beim Abschalten im Fehlerfall passieren? Tendenziell würde ich mit Wasserstop reagieren, man könnte aber auch ein Fallback vorsehen, z.B. einen Timer starten. Läuft der ab und es liegen keine gültigen Messwerte vor, wird die Beregnung beendet
Verhalten im Fehlerfall ist ein oft vernachlässigter Bereich. Solange es um Licht an/aus oder Rollläden auf/zu geht, ist ein Fehler normalerweise nur ärgerlich, führt aber nicht zu größerem Schaden (vielleicht abgesehen von einer erhöhten Stromrechnung), bei Wasser könnte man sich aber verschiedene Szenarien ausmalen, wo es schnell sehr unangenehm und teuer werden kann. Da kommt es natürlich auhc sehr auf die eigene Situation an. Wo kommt das Wasser her (Trinkwasser, Brunnen, Zisterne)? Was passiert bei Überschwemmung (durch die Beregnung)?