Für viele Anwendungen ist es ja brauchbar, wenn man eine Zeitsteuerung hat, die über eine einfache Oberfläche einstellbar ist. Etwa für:
- Rollläden
- Bewässerung
- Wecker
- etc.
Skript 1 wird periodisch aufgerufen und prüft, ob eine eingestellte Zeit mit der tatsächlichen Systemzeit übereinstimmt. Die eingestellte Zeit wird dabei über zwei Wertelisten-Variablen gesetzt, je eine für Stunde und Minute. Falls es eine Übereinstimmung gibt, dann wird eine Trigger-Variable gesetzt.
Skript 2 wird aufgerufen, wenn die Trigger-Variable gesetzt wird und führt die gewünschten Aktionen aus.
In meinem Beispiel:
Zeitgesteuerte Bewässerung mit Magnetventilen
Dafür wird zum gewünschten Bewässerungszeitpunkt die Beregnung gestartet. Die Beregnungsdauer kann ebenfalls in einer Werteliste-Variable flexibel vorgegeben werden.
Folgende Variablen sind dafür notwendig:
- Variable für die Stunde vom Typ Werteliste, Einträge von 0 - 24.
- Variable für die Minute vom Typ Werteliste, Einträge von 0 - 59 bzw. in 5-, 10- oder 15-Minuten-Schritten, je nach Anwendung.
- Variale für die Einschaltdauer vom Typ Werteliste, Einträge sind Zahlenwerte in Minuten
- Trigger-Variable vom Typ Boolean, zum Auslösen der Aktionen.
Sieht bei mir z.B. so aus:
Skript 1 - Trigger setzen
Das erste Skript wird periodisch ausgeführt. Zu jener Zeit, wo Stunde und Minute aus den oben genannten Variablen übereinstimmt, wird der Trigger gesetzt. Dieser Teil ist eben sehr universell für alle Arten von Zeitsteuerungen einsetzbar. Es müssen noch die selber definierten Variablen-Namen eingesetzt werden. In einem Programm sollte das Skript zyklisch aufgerufen werden. Hat man in der Minuten-Variable alle Minuten von 0-59 drin, dann eben 1x pro Minute. Sonst eben je nach Anforderung, beir mir reicht eben alle 5 Minuten (siehe Beispiel im Screenshot oben).
Es können auch in einem einzigen Programm, das über das Zeitmodul zyklisch aufgerufen wird mehrere Zeitprüfungen durchgeführt werden, etwa für mehrere Bewässerungsventile. Dazu kann im "dann"-Zweig das gleiche Skript mehrmals verwendet werden, nur die Variablennamen müssen richtig eingesetzt werden. Ev. die Skripte zeitlich hintereinander verzögern durch Verwendung von "verzögert um".
Das Skript macht übringens nichts, wenn eine Zeit von "00:00" (also Mitternacht) eingestellt ist. So kann die Zeitschaltung auch deaktiviert werden.
Code: Alles auswählen
!# ######################################################
!# Trigger-Variable wird gesetzt, wenn die Zeit durch Stunden- und Minutenvariable erreicht ist.
!# Daher periodisches Prüfen der Zeitvariablen nötig, dieses Skript dazu periodisch ausführen.
!#
!# Hinweis: Der Trigger wird NICHT gesetzt, wenn die Zeit auf "00:00" eingestellt ist!
!#
!# Auf die Trigger-Variable kann in anderen Programmen reagiert werden und Aktionen ausgeführt werden.
!#
!# Erstellt von A. Kos am 04.07.2017
!# ######################################################
!# Name der Stundenvariable vom Typ Werteliste:
string VARSTUNDE = "Ventil 1 Stunde";
!# Name der Minutenvariable vom Typ Werteliste:
string VARMINUTE = "Ventil 1 Minute";
!# Name der Trigger-Variable vom Typ Boolean:
string VARTRIGGER = "Ventil 1 Trigger";
!######### AB HIER MUSS NICHTS GEÄNDERT WERDEN #########
!# Variablen-Deklarationen
string hstr;
integer hint;
string zeit_sec;
integer diff;
!# Die beiden Variablen für Stunde und Minute auf das richtige Format bringen und in hstr schreiben
hint = web.webGetValueFromList(dom.GetObject(VARSTUNDE).ValueList(), dom.GetObject(VARSTUNDE).Variable().ToInteger()).ToInteger();
if (hint.ToInteger() < 10) {
hstr = "0" + hint.ToString() + ":";
} else {
hstr = hint.ToString() + ":";
}
hint = web.webGetValueFromList(dom.GetObject(VARMINUTE).ValueList(), dom.GetObject(VARMINUTE).Variable().ToInteger()).ToInteger();
if (hint.ToInteger() < 10){
hstr = hstr + "0" + hint.ToString();
} else {
hstr = hstr + hint.ToString();
}
!# Nur Ausführen, wenn die Zeit nicht auf 00:00 eingestellt ist:
if (hstr == "00:00") { quit; }
!# Prüfen, ob die aktuelle Zeit gleich der zentral eingestellten Zeit ist. Für die Übereinstimmung darf die Differenz zwischen eingestellter und aktueller Uhrzeit nicht mehr als 65 Sekunden betragen.
zeit_sec = system.Date("%F") + " " + hstr + ":00";
diff = system.Date("%F %T").ToTime().ToInteger() - zeit_sec.ToTime().ToInteger();
if (diff < 0 ) { diff = -1 * diff; }
if (diff <= 65){
!# Trigger setzen
dom.GetObject(VARTRIGGER).State(1);
}
Skript 2 - Aktion ausführen (z.B. Bewässerung starten)
Das zweite Skript wird in einem Programm aufgerufen das durch den Trigger ausgelöst wird. Dann kommt es zur Ausführung. In meinem Beispiel wird dann das Ventil zum Bewässern geöffnet für die Dauer (in Minuten) die in der Werteliste eingestellt ist.
Screenshot zur Programm-Auslösung:
Und hier das Skript:
Code: Alles auswählen
!##########################################
!# Wenn Trigger, dann bewässern.
!# Skript wird in Programm, das auf eine Trigger-Variable (oder Zeitmodul) reagiert aufgerufen.
!#
!# Aus der Werteliste für die Dauer wird der aktuell eingestellte Wert entnommen
!# und mit 60 multipliziert. Ergibt Einschaltdauer in Sekunden. Diese wird
!# für das Ventil mit dem Datenpunkt "ON_TIME" gesetzt.
!# Dann wird einschaltet.
!#
!# Erstellt am 07.07.2017 von A.Kos
!##########################################
!# Kanalname des Aktors für das entsprechende Ventil:
string ventil = "Ventil 1";
!# Name der Variable vom Typ Werteliste mit der Beregnungsdauer in Minuten:
string dauer = "Ventil 1 Dauer";
!######### AB HIER MUSS NICHTS GEÄNDERT WERDEN #########
!# Einschaltdauer setzen:
integer hint = web.webGetValueFromList(dom.GetObject(dauer).ValueList(), dom.GetObject(dauer).Variable().ToInteger());
dom.GetObject(ventil).DPByHssDP("ON_TIME").State(hint.ToFloat() * 60.0);
!# Einschalten:
dom.GetObject(ventil).DPByHssDP("STATE").State(1);
!# Rücksetzen des Triggers
dom.GetObject(ventil + " Trigger").State(0);
Soweit so gut. Ich hoffe diese Zeilen sind brauchbar für eigene Anwendungen.
LG
Andreas
EDIT am 03.04.2018:
Habe gerade einen Fehler im Skript entdeckt, weil ich es selbst wieder einmal einsetzten wollte. Sorry: Die Variable "diff" war im Skript nicht definiert. Ein "integer diff;" hat in den Variablendeklarationen gefehlt. Ohne das wird das Skript gar nicht ausgeführt! Habe ich soeben ergänzt!