Seite 1 von 4

Tutorial: Schritt für Schritt zur Custom-Logik "Entkalkungsanlage"

Verfasst: Di Feb 18, 2020 6:20 pm
von Robert_Mini
Hallo zusammen!

Ich habe diesmal wieder die Teilschritte zwischengespeichert, mit denen ich eine neue Logik zur Überwachung bzw. Protokollierung einer Entkalkungsanlage mittels T-Fühler an der Rückspülleitung erstellt habe.
Diskussion gab es hier dazu: viewtopic.php?f=47&t=1878&start=10#p20140, ich habe das Prinzip seit 7 Jahren am WireGate als Plugin laufen - funktioniert tadellos. Je nach Installation und Umgebungsbedingungen, könnte ein kleine Anpassung der Parameter notwendig sein.

Hinweis:
Ich werde in 8-10 Schritten beschreiben, wie man von der Anlage der Logik bis zum fertigen Modul mit ein/ausblendbaren (=optionalen) Ausgängen kommt und dazwischen schrittweise im Dokmode testet.
Da ich das ganze in 3-4 Postings und mehrere Tage aufteile, können Interessierte dazwischen jederzeit fragen! Also der ideale Zeitpunkt für alle, die sich bisher noch nicht an Custom Logiken heran gewagt haben.
Am Ende werde ich alle Schritte in das 1. Posting einfügen, also keine Angst, dass das ganze unleserlich wird.

Lg
Robert

Auf geht's!

Funktion:
Der aktuelle Temperaturwert wird laufend gegen die mittlere Umgebungstemperatur (Tiefpass über zb 10h) verglichen. Unterschreitet die aktuelle Temperatur diese um mehr als dT=3°C, wird dies als Rückspülung gewertet und die Erkennung für zb 2h gesperrt, bevor erneut das Unterschreiten gewertet wird.
Die Logik zählt die Anzahl der Rückspülungen und berechnet damit die Füllstandshöhe der Entkalkungsanlage. Beim Unterschreiten der Minimumhöhe, wird der Ausgang Warnung auf true gesetzt. Beim Empfang von true auf dem Nachfülleingang wird die Anzahl der nachgefüllten Säcke +1 gezählt und der Füllstand um zb 20cm erhöht.
Weiters wird für Rückspülung und Nachfüllen der letzte Zeitpunkt gespeichert. Für alle Werte kann durch Setzen der Sendeoption ein zyklisches Senden oder nur Senden bei Änderung eingestellt werden. Die Anzahl der nachgefüllten Säcke und Rückspülungen wird bei Jahreswechsel zurück gesetzt.

Schritt 1:
  • Alle bereits bekannten Ein-/Ausgänge anlegen und Variablennamen dafür vergeben
  • Eingänge erhalten bei mir immer ein "I_" vorangestellt.
  • Zugehörige Varablen richtig im Abschnitt Level definieren
  • Die Funktionen der Reihenfolge nach grob per Kommentare beschreiben (was zu Beginn bekannt ist)
Logik im Editor anlegen und man hat schon mal ein kleines Erfolgserlebnis, nämlich ein erstes Bild der Logikzelle mit richtig bezeichneten Ein-/Ausgängen.

Code: Alles auswählen

//============== Schritt 1 ===============
{
  "Input": [
        	["Temperatur Rueckspülung","Temperatur gemessen an der Rückspülleitung","$I_Temp","c"],
		["Delta T Rückspülung","Schwelle zur Erkennung Temperaturabfall bei Rückspülung","$I_DeltaT","c"],
		["Zeitkonstante Glättung","Zeitkonstante der geglätteten Temperatur, gegen die Delta T gemessen wird","$I_Glaettung","c"],
		["Trigger nachfüllen","Trigger für Nachfüllen je Sack","$I_TriggerNachfuellen","c"],
		["Füllstandserhöhung je Sack","","$I_HoeheSack","c"],
		["Füllstandsverringerung je Rückspülung","","$I_HoeheRueckspuelung","c"]
  ],
  "Output": [
		["Rückspülung Jahr","Anzahl Rückspülungen im aktuellen Jahr","$RS_Anzahl","c"],
		["Füllstand aktuell","Aktueller Füllstand","$Fuellstand","c"],
		["Warnung Füllstand","Trigger GA für Warnung","$Warnung","c"],
		["Temperatur geglättet","Temperatur nach Tiefpassfilter","$TempGeglaettet","c"]
  ],
  "Level": [
		["$I_Temp","float",20.0],
		["$TempGeglaettet","float",20.0],
		["$I_DeltaT","float",3.0],
		["$I_Glaettung","float",36000.0],
		["$I_TriggerNachfuellen","bool",false],
		["$I_HoeheSack","float",25.0],
		["$I_HoeheRueckspuelung","float",2.0],
		["$RS_Anzahl","integer",0],
		["$Fuellstand","float",0.0],
		["$Warnung","bool",false],
		//
		["$KonstTrue","bool",true],
		["$KonstFalse","bool",false],
		["$Konst0","float",0.0],
		["$Konst1","float",1.0]
  ],
  "Module": [
		// Temperatur Glättung
		
		// Vergleich T aktuell < (T geglättet - DeltaT)
		
		// Wenn Rueckspuelung, dann Fuellstand + Zaehler neu berechnen
		
		// Timer Sperre
		
		// Trigger Nachfuellung => Fuellstand erhöhen
  ]
}
Schritt 2:
  • Module hinzufügen. Ich kopiere dazu meist die Syntax aus der Knowledge Base (app.php/kb/viewarticle?a=115) und passe die Variablennamen an.
  • Modul Lowpass (Tiefpass): Das Ergebnis wird mit der Variable $TempGeglaettet verbunden, die auch mit dem Ausgang "Temperatur geglättet" verbunden ist.
  • Modul Polynomial hinzufügen, um von $TempGeglaettet den Wert $I_Delta abzuziehen => Ergebnis $TempSchwelle.
  • Mittel Comparator vergleichen, ob der aktuelle Temperaturwert unter $Tempschwelle liegt => die Variable $Temp_CResult wird dann true.
  • $Temp_CResult und $Temp_Schwelle werden temporär auf 2 zusätzliche Ausgänge geschrieben.
  • Im Dokmode kann man sofort testen (noch keine Ein-/Ausgänge verknüpfen), ob die 3 ersten Module richtig funktionieren:
    • Parameter für Glättung und dT fix setzen und Logik speichern!
    • Dann Ist-Temp. eingeben zb 20C, dann zb 16C eingeben und die Werte von $Temp_CResult und $Temp_Schwelle prüfen.
So sieht die Logik nach Schritt 2 im DokMode aus:

Bild

Code: Alles auswählen

//================ Schritt 2 =====================
{
  "Input": [
        ["Temperatur Rueckspülung","Temperatur gemessen an der Rückspülleitung","$I_Temp","c"],
		["Delta T Rückspülung","Schwelle zur Erkennung Temperaturabfall bei Rückspülung","$I_DeltaT","c"],
		["Zeitkonstante Glättung","Zeitkonstante der geglätteten Temperatur, gegen die Delta T gemessen wird","$I_Glaettung","c"],
		["Trigger nachfüllen","Trigger für Nachfüllen je Sack","$I_TriggerNachfuellen","c"],
		["Füllstandserhöhung je Sack","","$I_HoeheSack","c"],
		["Füllstandsverringerung je Rückspülung","","$I_HoeheRueckspuelung","c"]
  ],
  "Output": [
		["Rückspülung Jahr","Anzahl Rückspülungen im aktuellen Jahr","$RS_Anzahl","c"],
		["Füllstand aktuell","Aktueller Füllstand","$Fuellstand","c"],
		["Warnung Füllstand","Trigger GA für Warnung","$Warnung","c"],
		["Temperatur geglättet","Temperatur nach Tiefpassfilter","$TempGeglaettet","c"],
		// Debug Ausgänge
		["_Temp_CResult","Temperatur nach Tiefpassfilter","$Temp_CResult","c"],
		["_Temp_Schwelle","Temperatur nach Tiefpassfilter","$Temp_Schwelle","c"]
  ],
  "Level": [
		["$I_Temp","float",20.0],
		["$TempGeglaettet","float",20.0],
		["$I_DeltaT","float",3.0],
		["$I_Glaettung","float",36000.0],
		["$I_TriggerNachfuellen","bool",false],
		["$I_HoeheSack","float",25.0],
		["$I_HoeheRueckspuelung","float",2.0],
		["$RS_Anzahl","integer",0],
		["$Fuellstand","float",0.0],
		["$Warnung","bool",false],
		//
		["$Temp_Schwelle","float",0.0],
		["$Temp_CResult","bool",false],
		
		["$KonstTrue","bool",true],
		["$KonstFalse","bool",false],
		["$Konst0","float",0.0],
		["$Konst1","float",1.0]
  ],
  "Module": [
		// Temperatur Glättung
		["Lowpass","$I_Temp","$TempGeglaettet","$I_Glaettung"],
		
		// Vergleich T aktuell < (T geglättet - DeltaT)
		["Polynomial", "$Konst1", "$Temp_Schwelle",["$TempGeglaettet", "-$I_DeltaT"]],
		["Comparator" , "$I_Temp" , "$Temp_CResult" , "$Temp_Schwelle"]
		
		// Wenn Rueckspuelung, dann Fuellstand + Zaehler neu berechnen
		
		// Timer Sperre
		
		// Trigger Nachfuellung => Fuellstand erhöhen
		
  ]
}

Re: Tutorial: Schritt für Schritt zur Custom-Logik "Entkalkungsanlage"

Verfasst: Mi Feb 19, 2020 9:37 am
von StefanW
Wunderbar. ganz hervorragend.

genau solche Tutorials sollten uns alles wirklich vorwärts bringen mit den Custom Logiken


BTW: Stefan hat - extra für Dich auf Basis Deiner Wünsche- ein paar der gewünschten Erweiterungen in die Engine gezaubert um die Möglichkeiten zu erweitern, kommt also demnächst neues auf Euch zu.

lg

Stefan

Re: Tutorial: Schritt für Schritt zur Custom-Logik "Entkalkungsanlage"

Verfasst: Mi Feb 19, 2020 1:19 pm
von Robert_Mini
Alles klar von Seiten der Mitleser?

Am Abend geht es weiter!

Lg
Robert

Re: Tutorial: Schritt für Schritt zur Custom-Logik "Entkalkungsanlage"

Verfasst: Mi Feb 19, 2020 6:24 pm
von CHD
Hallo Robert,

vielen Dank für deinen tollen Schritt für Schritt Kurs!

Was mir aufgefallen ist: Wenn ich Schritt 1 kopiere bekommen ich zwei Fehler.
-Einmal fehlt ein Komma hinter ["Füllstandserhöhung je Sack","","$I_HoeheSack","c"]
-Einmal ist ein Komma zuviel hinter ["Temperatur geglättet","Temperatur nach Tiefpassfilter","$TempGeglaettet","c"],

Gruß, Christian

Re: Tutorial: Schritt für Schritt zur Custom-Logik "Entkalkungsanlage"

Verfasst: Mi Feb 19, 2020 6:35 pm
von Robert_Mini
Sehr gut! Will jetzt nicht sagen, dass das Absicht war, aber beim Kopieren von Notepad++ in den LE kann es schon mal sein, dass der eine oder andere kleine Fehler nicht zurück fließt.

Hab’s ausgebessert.

Lg
Robert

Re: Tutorial: Schritt für Schritt zur Custom-Logik "Entkalkungsanlage"

Verfasst: Mi Feb 19, 2020 8:29 pm
von Robert_Mini
Weiter geht's!

Schritt 3:
  • Timer (= Modul Monoflop) hinzufügen. Gibt jene Zeit an, in der keine erneute Rückspülung erkannt werden soll. Der Timer wird durch das Unterschreiten der Temperaturschwelle ($Temp_Schwelle = true) gestartet und ist nicht retriggerbar (Parameter 0). Bei aktivem Timer nimmt die Variable $Sperre_Aktiv den Wert true an.
  • Ein And-Modul aus $Temp_CResult und -$Sperre_aktiv dient dazu, einen neuen Rückspülvorgang zu erkennen. Da der Timer im Code der Custom-Logik erst unterhalb gestartet wird, ist $Sperre_aktiv noch false und wird mit dem "-" invertiert => true. Damit wird das Ergenis von diesem AND $Rueckspuelung_Neu einmalig true, wenn die Temperaturschwelle unterschritten wird und der Timer (noch) nicht läuft. Später wird damit für Füllstandsberechnung bzw. Anzahl Rückspülungen weiter gearbeitet.
  • Zwei zusätzliche temporäre Ausgänge dienen zum Prüfen der Zustände des Timers $Sperre_Aktiv und der And-Logik $Rueckspuelung_Neu. Solch Ausgaben (ich nennen sie gerne Debug-Ausgänge) sollten als Sendeoption immer "a" für always haben, damit immer aktualisiert wird.
Bei Fragen - fragen.
Lg Robert

So sieht die Logik nach Schritt 3 im DokMode aus:

Bild

Code: Alles auswählen

//================ Schritt 3 =====================
//Test ob And nach Unterschreiten 1x auf True gesetzt wird und 
//dann beim nächsten Aufruf wieder false ist => ok.
{
  "Input": [
        ["Temperatur Rueckspülung","Temperatur gemessen an der Rückspülleitung","$I_Temp","a"],
		["Delta T Rückspülung","Schwelle zur Erkennung Temperaturabfall bei Rückspülung","$I_DeltaT","c"],
		["Zeitkonstante Glättung","Zeitkonstante der geglätteten Temperatur, gegen die Delta T gemessen wird","$I_Glaettung","c"],
		["Sperrzeit nach Rückspülung","Mindestzeit, bevor wieder eine Rückspülung erkannt wird","$I_Sperrzeit","c"],
		["Trigger nachfüllen","Trigger für Nachfüllen je Sack","$I_TriggerNachfuellen","c"],
		["Füllstandserhöhung je Sack","","$I_HoeheSack","c"],
		["Füllstandsverringerung je Rückspülung","","$I_HoeheRueckspuelung","c"]
  ],
  "Output": [
		["Rückspülung Jahr","Anzahl Rückspülungen im aktuellen Jahr","$RS_Anzahl","c"],
		["Füllstand aktuell","Aktueller Füllstand","$Fuellstand","c"],
		["Warnung Füllstand","Trigger GA für Warnung","$Warnung","c"],
		["Temperatur geglättet","Temperatur nach Tiefpassfilter","$TempGeglaettet","c"],
		// Debug Ausgänge
		["_Temp_CResult","Comparator Ergebnis","$Temp_CResult","c"],
		["_And_RS_Neu","Neue Rückspülung","$Rueckspuelung_Neu","a"],
		["_And_RS_Aktiv","Sperre aktiv","$Sperre_Aktiv","a"]
  ],
  "Level": [
		["$I_Temp","float",20.0],
		["$TempGeglaettet","float",20.0],
		["$I_DeltaT","float",3.0],
		// zusätzlich
		["$I_Sperrzeit","float",3.0],
		["$I_Glaettung","float",36000.0],
		["$I_TriggerNachfuellen","bool",false],
		["$I_HoeheSack","float",25.0],
		["$I_HoeheRueckspuelung","float",2.0],
		["$RS_Anzahl","integer",0],
		["$Fuellstand","float",0.0],
		["$Warnung","bool",false],
		//
		["$Temp_Schwelle","float",0.0],
		["$Temp_CResult","bool",false],
		// zusätzlich
		["$Sperre_Aktiv","bool",false],
		["$Rueckspuelung_Neu","bool",false],
		
		
		["$KonstTrue","bool",true],
		["$KonstFalse","bool",false],
		["$Konst0","float",0.0],
		["$Konst1","float",1.0]
  ],
  "Module": [
		// Temperatur Glättung
		["Lowpass","$I_Temp","$TempGeglaettet","$I_Glaettung"],
		
		// Vergleich T aktuell < (T geglättet - DeltaT)
		["Polynomial", "$Konst1", "$Temp_Schwelle",["$TempGeglaettet", "-$I_DeltaT"]],
		["Comparator" , "$I_Temp" , "-$Temp_CResult" , "$Temp_Schwelle"],
		
		// Wenn Rueckspuelung, dann Fuellstand + Zaehler neu berechnen
		["And",["$Temp_CResult","-$Sperre_Aktiv"], "$Rueckspuelung_Neu"],
		
		// Timer Sperre
		["Monoflop","$Temp_CResult","$KonstFalse","$Sperre_Aktiv","$I_Sperrzeit",0]
		
		// Trigger Nachfuellung => Fuellstand erhöhen
  ]
}

Re: Tutorial: Schritt für Schritt zur Custom-Logik "Entkalkungsanlage"

Verfasst: Mi Feb 19, 2020 9:13 pm
von paralan
Tolles Tutorial Robert! :clap:
Da bekomm ich gerade echt Lust neue Logiken anzulegen.

Re: Tutorial: Schritt für Schritt zur Custom-Logik "Entkalkungsanlage"

Verfasst: Mi Feb 19, 2020 9:25 pm
von Robert_Mini
Ich poste gleich Schritt 4 hinterher, da ich nachträglich noch Rückspüldauer und Sperrzeit aufgetrennt habe.

Man kann den Code übrigens einfach über den alten Code kopieren und muss nicht in jedem Schritte eine neue Custum Logik anlegen. Ein-/Ausgänge werden dynamisch angepasst (Ausnahme Trigger- und Sendeoption, das kommt noch).

Schritt 4:
  • Mittel Polynomial wird die Variable $Sperrzeit_Gesamt berechnet (Summe aus Rückspülzeit und Sperrzeit)
  • Der Timer wird nun mit $Sperrzeit_Gesamt gestartet. Der Ausgang dieses Timers wird weiterhin in der And-Logik aus Schritt 3 verwendet.
  • Ein zweiter Timer wird gleichzeitig mit der Dauer $I_RS_Dauer (neuer Eingang!!) gestartet und auf den Ausgang "Rückspülung aktiv" gelegt (Variable $RS_Stat).
  • Somit gibt es nun 2 getrennte Ausgänge: einer zeigt an ob gerade rückgespült wird, der 2. Ausgang (eher Spielerei) ist bis Ende Sperrzeit true.
Die nächsten Schritte gibt's morgen.

Lg Robert

So sieht die Logik nach Schritt 4 aus:

Bild

Bei aktivem Dokmode kann man in Grafana die Timer und das Ergebnis der And-Logik sehen:

Bild

Code: Alles auswählen

//================ Schritt 4 =====================
//Auftrennung Dauer Rückspülung und Sperrzeit
{
  "Input": [
        ["Temperatur Rueckspülung","Temperatur gemessen an der Rückspülleitung","$I_Temp","a"],
		["Delta T Rückspülung","Schwelle zur Erkennung Temperaturabfall bei Rückspülung","$I_DeltaT","c"],
		["Zeitkonstante Glättung","Zeitkonstante der geglätteten Temperatur, gegen die Delta T gemessen wird","$I_Glaettung","c"],
		["Dauer Rückspülung","Dauer für Ausgabe Rückspülung aktiv","$I_RS_Dauer","c"],
		["Sperrzeit nach Rückspülung","Mindestzeit, bevor wieder eine Rückspülung erkannt wird","$I_Sperrzeit","c"],
		["Trigger nachfüllen","Trigger für Nachfüllen je Sack","$I_TriggerNachfuellen","c"],
		["Füllstandserhöhung je Sack","","$I_HoeheSack","c"],
		["Füllstandsverringerung je Rückspülung","","$I_HoeheRueckspuelung","c"]
  ],
  "Output": [
		["Rückspülung Jahr","Anzahl Rückspülungen im aktuellen Jahr","$RS_Anzahl","c"],
		["Füllstand aktuell","Aktueller Füllstand","$Fuellstand","c"],
		["Warnung Füllstand","Trigger GA für Warnung","$Warnung","c"],
		["Temperatur geglättet","Temperatur nach Tiefpassfilter","$TempGeglaettet","c"],
			
		// Debug Ausgänge
		["_Temp_CResult","Comparator Ergebnis","$Temp_CResult","c"],
		["_Sperrre_Aktiv","Sperre aktiv","$Sperre_Aktiv","c"]	
		["_And_RS_Neu","Neue Rückspülung","$Rueckspuelung_Neu","c"],
		["_Rückspülung Aktiv","Rückspülung läuft","$RS_Stat","c"]
  ],
  "Level": [
		["$I_Temp","float",20.0],
		["$TempGeglaettet","float",20.0],
		["$I_DeltaT","float",3.0],
		["$I_Sperrzeit","float",3.0],
		// zusätzlich
		["$I_RS_Dauer","float",3.0],
		
		["$I_Glaettung","float",36000.0],
		["$I_TriggerNachfuellen","bool",false],
		["$I_HoeheSack","float",25.0],
		["$I_HoeheRueckspuelung","float",2.0],
		["$RS_Anzahl","integer",0],
		["$Fuellstand","float",0.0],
		["$Warnung","bool",false],
		//
		["$Temp_Schwelle","float",0.0],
		["$Temp_CResult","bool",false],
		["$TimerStat","bool",false],
		// zusätzlich
		["$RS_Stat","bool",false],
		["$Sperre_Aktiv","bool",false],
		["$Sperrzeit_Gesamt","float",3.0],
		["$Rueckspuelung_Neu","bool",false],
		
		["$KonstTrue","bool",true],
		["$KonstFalse","bool",false],
		["$Konst0","float",0.0],
		["$Konst1","float",1.0]
  ],
  "Module": [
		// Temperatur Glättung
		["Lowpass","$I_Temp","$TempGeglaettet","$I_Glaettung"],
		
		// Vergleich T aktuell < (T geglättet - DeltaT)
		["Polynomial", "$Konst1", "$Temp_Schwelle",["$TempGeglaettet", "-$I_DeltaT"]],
		["Comparator" , "$I_Temp" , "-$Temp_CResult" , "$Temp_Schwelle"],
		
		// Wenn Rueckspuelung, dann Fuellstand + Zaehler neu berechnen
		["And",["$Temp_CResult","-$Sperre_Aktiv"], "$Rueckspuelung_Neu"],
		
		// Timer Sperre und Rückspülung
		["Polynomial", "$Konst1", "$Sperrzeit_Gesamt",["$I_RS_Dauer", "$I_Sperrzeit"]],
		["Monoflop","$Temp_CResult","$KonstFalse","$RS_Stat","$I_RS_Dauer",0]
		["Monoflop","$Temp_CResult","$KonstFalse","$Sperre_Aktiv","$Sperrzeit_Gesamt",0]
		
		// Trigger Nachfuellung => Fuellstand erhöhen

  ]
}

Re: Tutorial: Schritt für Schritt zur Custom-Logik "Entkalkungsanlage"

Verfasst: Mi Feb 19, 2020 10:40 pm
von CHD
Hi Robert,

es haben sich wieder Kommata weggeschlichen, diesmal bei Schritt 4. Diese Schlingel...

Was ich gerade noch nicht verstehe: Warum wird bei mir an der markierten Stelle etwas angezeit, bei dir steht aber nichts?
Bild
Vielen Dank!
Gruß, Christian

Re: Tutorial: Schritt für Schritt zur Custom-Logik "Entkalkungsanlage"

Verfasst: Do Feb 20, 2020 9:46 am
von Eraser
Weil er bei den Eingängen direkt auf Parameter umgeschaltet hat und dort dann einen Wert eingetragen hat.