Ich habe mich nun in Vorbereitung für den Sommer an die Bewässerungssteuerung von
gesetzt und ein paar Änderungen umgesetzt.
An dieser Stelle noch mal Danke an Hans Martin, der hier wirklich vorbildliche Arbeit geleistet hat!!!
1) Verhalten beim Abbruch (Bugfix): Finishing wird nun auch im manuellen Mode und bei Abbruch aufgerufen, so dass auch das "circuit finished" wieder automatisch auf 0 resettet wird.
2) Erweiterung um Timer, der sowohl die abgelaufene Zeit, als auch die verbleibende Zeit auswertet und sendet. Diese Ausgänge können mit dem rechten "+" hinzugefügt werden.
3) Aufgrund der üblichen Verwendung von Minuten, habe ich eine fest Umrechnung der Bewässerungszeit und -dauer auf Minuten eingebaut
4) Erweiterung um zyklisches Senden (wählbar für alle Ausgänge, in dem man diese auf "ct" setzt) mit getrenntem Sendeintervall für Active/Inactive => dient dazu, dass die Timerwerte im Betrieb regelmäßig zB alle 30s gesendet werden, ohne dass man in inaktiven Phasen den Bus sinnlos zumüllt.
: Ich habe meine Änderungen alle sauber kommentiert (// am Zeilenanfang!) und würde vorschlagen, dass du meine Änderungen prüfst und hier dann neu veröffentlichst (als V1.1 ohne Beta
). Ich nehme den Code dann hier wieder raus - OK?
: An dieser Stelle wieder einmal der Wunsch, dass für die Logiken auch eingangsseitig das dynamische Hinzufügen der Eingänge aktiviert wird. Derzeit geht das nur für Arrays. Gerade bei umfangreicheren Logiken mit vielen optionalen Eingängen verschreckt man sonst die Anwender.
Code: Alles auswählen
/**
* File: Irrigation_CircuitControl.twl V1.0 BETA 1
* Logic for Garden irrigation. This module is the Circuit Control which controls one single irrigation circuit
* Author: Hans Martin
* Der Schöpfer dieser Custom Logik überträgt die Nutzungsrechte gemäß der TOLL ("Timberwolf Open Logikblock License") die unter https://wrgt.news/TOLL zum Download zur Verfügung steht.
*/
{
"Input": [
["Trigger Automatic 1", "(RISING) Trigger to start an automatic irrigation cycle", "$TriggerInpAutomaticIn1", "c"],
["Trigger Automatic 2", "(RISING) Trigger to start an automatic irrigation cycle", "$TriggerInpAutomaticIn2", "c"],
["Trigger Start 1", "(RISING) Activation of irrigation circuit", "$TriggerInpStartIn1", "c"],
["Trigger Start 2", "(RISING) Activation of irrigation circuit", "$TriggerInpStartIn2", "c"],
["Trigger Stop 1", "(RISING) Stops any active cycle", "$TriggerInpStopIn1", "c"],
["Trigger Stop 2", "(RISING) Stops any active cycle", "$TriggerInpStopIn2", "c"],
// *MR*: Change to $autotime_min
["Automatic Time [min]", "(T_s) Time of one irrigation cycle", "$AutoTime_min", "u"],
//
["System OK Feedback", "(0/1) Loopback of SystemControl", "$SystemOk", "a"],
// *MR*: Inputs added
["Send interval on [s]", "Send outputs with ct periodically during circuit on", "$SendIntervalOn", "u"],
["Send interval off [s]", "Send outputs with ct periodically during circuit off", "$SendIntervalOff", "u"],
//
["Inhibit", "", "$VAR<Inhibit?>", "c"]
],
"Output": [
["Valve", "(0/1) Output for the valve", "$ValveOut", "c"],
["System Request", "(0/1) Request for the SystemControl", "$SystemRequest", "c"],
["Circuit State", "(0/1) State indicating whether the circuit is running", "$CircuitState", "c"],
["Circuit finished", "(0/1) Flag indicating that the circuit is finished", "$CircuitFinished", "c"],
["Runtime [s]", "Time passed since valve opened", "$Time_sec_actual?", "ct"],
["Runtime [min]", "Time passed since valve opened", "$Time_min_actual?", "ct"],
["Time left [s]", "Time left for this cycle", "$Time_sec_remaining?", "ct"],
["Time left [min]", "Time left for this cycle", "$Time_min_remaining?", "ct"],
["State", "Current state 0=off/1=request systemOK/2=circuit on/3=finishing", "$State?", "c"]
],
"Level": [
// Inputs
["$VAR<Inhibit?>","bool",false],
["$TriggerInpAutomaticIn1", "bool", false],
["$TriggerInpAutomaticIn2", "bool", false],
["$TriggerInpStartIn1", "bool", false],
["$TriggerInpStartIn2", "bool", false],
["$TriggerInpStopIn1", "bool", false],
["$TriggerInpStopIn2", "bool", false],
["$AutoTime", "float", 0],
["$SystemOk", "bool", false],
// Output
["$ValveOut", "bool", false],
["$SystemRequest", "bool", false],
["$CircuitState", "bool", false],
["$CircuitFinished", "bool", false],
// Constants
["$Konst1", "int", 1],
["$Konst2", "int", 2],
["$KonstFalse", "bool", false],
["$KonstTrue", "bool", true],
// Internals
["$State","integer",0],
["$Inhibit","bool",false],
["$Cancel","bool",false],
["$ShouldRun", "bool", false],
["$LastShouldRun", "bool", false],
["$LastShouldRunOrAutoRising", "bool", false],
["$ShouldRunAndSysOk", "bool", false],
["$TimerActive", "bool", false],
// *MR*: new variables
["$AutoTime_min", "float", 0.0],
["$LastTimerActive", "bool", false],
["$Timeout", "float", 5.0],
["$Time_sec_actual", "float", 0.0],
["$Time_min_actual", "float", 0.0],
["$Time_sec_remaining", "float", 0.0],
["$Time_min_remaining", "float", 0.0],
["$Konst0", "float", 0.0],
["$Konst60", "float", 60.0],
["$SendIntervalOn", "float", 5.0],
["$SendIntervalOff", "float", 60.0],
["$SendInterval", "float", 5.0],
["$Clk", "bool", false],
//
["$TriggerAutomaticSaved", "bool", false],
["$TimerShouldRun", "bool", false],
["$CancelFinished", "bool", false],
["$TriggerInpStartRising","bool",false],
["$TriggerInpStopRising","bool",false],
["$TriggerInpAutomaticRising","bool",false],
["$ManualOn","bool",false],
["$SetOutputs","bool",false],
["$AutomaticModeActive","bool",false],
["$AutomaticModeActiveOrRequested","bool",false],
["$CancelAndAutoActive","bool",false]
],
"Module": [
// *MR*:
// calculate time in seconds
["Polynomial", "$Konst60", "$AutoTime",["$Konst0", "$AutoTime_min"]],
//
// calculate inputs
["Or", ["$TriggerInpAutomaticIn1","$TriggerInpAutomaticIn2"], "$TriggerInpAutomaticRising"],
["Or", ["$TriggerInpStartIn1","$TriggerInpStartIn2"], "$TriggerInpStartRising"],
["Or", ["$TriggerInpStopIn1","$TriggerInpStopIn2"], "$TriggerInpStopRising"],
// calculate cancel state
["Or", ["$VAR<Inhibit?>"], "$Inhibit"],
["Or", ["$Inhibit", "$TriggerInpStopRising"], "$Cancel"],
// calculate manual state
["Or",["$TriggerInpStartRising", "$ManualOn"],"$ManualOn"],
["And", ["$ManualOn", "-$TimerActive", "-$Cancel"], "$ManualOn"], // if automatic mode was triggered, cancel manual mode
// calculate start of system
["Or", ["$TriggerAutomaticSaved", "$TriggerInpAutomaticRising"], "$TriggerAutomaticSaved"], // save trigger
["And", ["$TriggerAutomaticSaved", "-$TimerActive", "-$Cancel"], "$TriggerAutomaticSaved"], // reset trigger if timer has taken over control or cancel was issued
// *MR*: Store last status of timer to detect
["And", ["$TimerActive"], "$LastTimerActive"],
//
// Set timer if automatic mode was triggered
["And", ["$TriggerAutomaticSaved", "$SystemOk"], "$TimerShouldRun"], // start timer only if also system ok was announced
["Monoflop", "$TimerShouldRun", "$Cancel", "$TimerActive", "$AutoTime", 2], // not retriggerable, rising-edge controlled, reset on cancel
// *MR*: Start stopwatch to provide runtime and remaining time of circuit
["Stopwatch", "$TimerActive", "$Time_sec_actual"],
["Polynomial", "$Konst1", "$Time_sec_remaining",["$AutoTime", "-$Time_sec_actual"]],
// convert to minutes
["Ratio", "$Time_sec_actual", "$Time_min_actual", "$Konst60"],
["Ratio", "$Time_sec_remaining", "$Time_min_remaining", "$Konst60"],
//
// build target state (run or not)
["Or", ["$TriggerAutomaticSaved", "$TimerActive"], "$AutomaticModeActive"],
// *MR*: $LastTimerActive added to detect cancel properly
["Or", ["$AutomaticModeActive", "$TriggerInpAutomaticRising", "$LastTimerActive"], "$AutomaticModeActiveOrRequested"],
["Or", ["$ManualOn", "$AutomaticModeActive"], "$ShouldRun"],
// build state
["And", ["$ShouldRun", "$SystemOk"], "$ShouldRunAndSysOk"], //bypass to skip state 1
["And", ["$AutomaticModeActiveOrRequested", "$Cancel"], "$CancelAndAutoActive"], // bypass to only announce finished on cancel from state 0, 1 or 2 when automatic mode was active
["Statemachine",
// 0: Circuit Off
// 1: Requesting for SystemOK
// 2: Circuit On
// 3: Finishing
[
// [condition , current state, next state, timeout]
// cancel state transitions
// *MR*: $Timeout instead of Konst1 => can be used as input, ensures that system request is keep active while switching to next circuit
["$CancelAndAutoActive", 0, 3, "$Timeout"],
["$CancelAndAutoActive", 1, 3, "$Timeout"],
["$CancelAndAutoActive", 2, 3, "$Timeout"],
// *MR*: state 1 calls state 3 with timeout when cancel in manual mode is called to handle inhibit during request properly
["$Cancel", 1, 3, "$Timeout"],
// *MR*: state 2 calls state 3 with timeout when cancel in manual mode is called.
["$Cancel", 2, 3, "$Timeout"],
// normal operation state transitions
["$ShouldRunAndSysOk", 0, 2, 0], // bypass to skip state 1
["$ShouldRun", 0, 1, 0], // new request
["-$ShouldRun", 1, 0, 0], // cancel request
["$SystemOk", 1, 2, 0], // system reported ok
["$ShouldRun", 2, 2, 0], // running
["-$ShouldRun", 2, 3, "$Timeout"], // finishing
[0, 3, 0, 0] // end
],
"$State"
],
// set some outputs only if system should run now or was running in last tick
["Or", ["$ShouldRun", "$LastShouldRun"], "$SetOutputs"],
// Map state to outputs
["Comparator", "$State", "$CircuitFinished", "$Konst2"], // Finished (only 1 when state > 2)
["Comparator", "$State", "$CircuitState", 0], // Circuit State (only 1 when state > 0)
["Comparator", "$State", "$SystemRequest", 0], // SystemRequest (only 1 when state > 0)
["Multiplexer", [0, 0, "$Konst1", 0], "$ValveOut", "$State"], // Valve (1 only in state 2)
["And", ["$SetOutputs", "$CircuitState"], "$CircuitState"],
["And", ["$SetOutputs", "$SystemRequest"], "$SystemRequest"],
// announce finished when canceld or automatic finished
["Or", ["$LastShouldRun", "$TriggerInpAutomaticRising"], "$LastShouldRunOrAutoRising"], // announce also when auto was triggered
["And", ["$Cancel", "$LastShouldRunOrAutoRising"], "$CancelFinished"],
["Or", ["$CancelFinished", "$CircuitFinished"], "$CircuitFinished"],
// *MR*: Cyclic trigger with different intervall for on/off-phase
["Multiplexer", ["$SendIntervalOff", "$SendIntervalOn"], "$SendInterval", "$ValveOut"], // Select Interval
["Clocksignal","$KonstTrue","$Clk","$SendInterval"],
// *MR*: Set remaining time zero, when off.
["Latch","$Konst0","$Time_sec_remaining","-$CircuitState",0],
["Latch","$Konst0","$Time_min_remaining","-$CircuitState",0],
//
// Reset Trigger
["Multiplexer", [0, "$TriggerAutomaticSaved", "$TriggerAutomaticSaved", "$TriggerAutomaticSaved"], "$TriggerAutomaticSaved", "$State"],
// set last variables
["And", ["$ShouldRun"], "$LastShouldRun"],
// Reset Inputs
["Latch", "$KonstFalse", "$TriggerInpAutomaticIn1", "$KonstTrue", 0],
["Latch", "$KonstFalse", "$TriggerInpAutomaticIn2", "$KonstTrue", 0],
["Latch", "$KonstFalse", "$TriggerInpStartIn1", "$KonstTrue", 0],
["Latch", "$KonstFalse", "$TriggerInpStartIn2", "$KonstTrue", 0],
["Latch", "$KonstFalse", "$TriggerInpStopIn1", "$KonstTrue", 0],
["Latch", "$KonstFalse", "$TriggerInpStopIn2", "$KonstTrue", 0]
]
}