jo
ich lasse noch eine anleitung von der ki über den code schreiben
ab jatzt nur ki geschrieben
code(19).txt
Wow, das ist ja großartig, dass die Community schon Interesse zeigt! Das bestätigt, dass unsere Arbeit hier relevant ist.
Absolut, hier ist ein Entwurf für einen Forenbeitrag, der den Code enthält und erklärt, wie man ihn verwendet und anpasst. Ich habe versucht, ihn informativ, aber auch mit den nötigen Warnhinweisen zu versehen.
Titel: Fortgeschrittene Solarsteuerung (3 Ziele, PID-Pumpe) als Custom Logic Block [Beta]
Hallo zusammen,
in Zusammenarbeit mit dem Forenmitglied eib-eg (vielen Dank an dieser Stelle!) und durch die Analyse vieler bestehender Custom Logic Beispiele haben wir einen einzelnen Custom Logic Block im JSON-Format entwickelt, der eine relativ komplexe Solarthermie-Steuerung abbildet.
Funktionen:
Ansteuerung von bis zu 3 Zielen (Warmwasser, Pufferspeicher, Eisspeicher).
Feste Priorisierung der Ziele: Warmwasser > Puffer > Eisspeicher.
Drehzahlregelung der Solarpumpe über PID-Regler (PID awu) mit einstellbarer Solldifferenz (dT).
Ansteuerung von 2 Umschaltventilen gemäß der Logik:
Ventil 1 AUS: Warmwasser
Ventil 1 EIN, Ventil 2 AUS: Puffer
Ventil 1 EIN, Ventil 2 EIN: Eisspeicher
Nutzung des Latch-Moduls zur persistenten Speicherung von Zuständen (Pumpenstatus, aktives Ziel).
Berücksichtigung von Ein-/Ausschalthysteresen und Maximaltemperaturen der Speicher.
Zweck:
Dieser Code dient als fortgeschrittene Vorlage und Diskussionsgrundlage. Er wurde erfolgreich im Timberwolf Server gespeichert, die Logik ist jedoch in einem realen System noch nicht ausführlich getestet!
Der Code (Version 1.1):
{
"Level": [
// --- INPUTS (Sensoren & Parameter) ---
// Sensoren (Initialwerte nur für Offline-Simulation)
[ "$I_T_Koll", "float", 45.0 ],
[ "$I_T_WW_U", "float", 30.0 ],
[ "$I_T_WW_O", "float", 55.0 ],
[ "$I_T_Puffer_U", "float", 35.0 ],
[ "$I_T_Puffer_O", "float", 60.0 ],
[ "$I_T_Eis", "float", 10.0 ],
// Parameter (Anpassen!)
[ "$P_EIN_HYS", "float", 6.0 ],
[ "$P_AUS_HYS", "float", 3.0 ],
[ "$P_T_WW_MAX", "float", 60.0 ],
[ "$P_T_PUFFER_MAX", "float", 80.0 ],
[ "$P_T_EIS_MAX", "float", 25.0 ],
[ "$P_Prio_WW", "integer", 1 ], // Info: In dieser Version NICHT ausgewertet!
[ "$P_Prio_Puffer", "integer", 2 ], // Info: In dieser Version NICHT ausgewertet!
[ "$P_Prio_Eis", "integer", 3 ], // Info: In dieser Version NICHT ausgewertet!
[ "$P_dT_Soll", "float", 8.0 ],
[ "$P_Kp", "float", 10.0 ],
[ "$P_Ki", "float", 0.5 ],
[ "$P_Kd", "float", 0.1 ],
[ "$P_Pump_Min_Speed", "float", 20.0 ], // %
[ "$P_Pump_Max_Speed", "float", 100.0 ], // %
[ "$P_PID_LL", "float", 0.0 ], // PID Output Lower Limit (%)
[ "$P_PID_UL", "float", 100.0 ], // PID Output Upper Limit (%)
// --- PERSISTENT STATES (Werden über Module oder Latch aktualisiert) ---
[ "$FF_Out_Alt", "bool", false ], // Pumpenstatus vom letzten Zyklus (aus FF-Nachbau)
[ "$State_ActiveTargetID_Alt", "integer", 0 ], // Aktives Ziel vom letzten Zyklus (0=Kein, 1=WW, 2=Puffer, 3=Eis)
[ "$State_T_Unten_Alt", "float", 0.0 ], // T_Unten des letzten aktiven Ziels
[ "$State_T_Oben_Alt", "float", 0.0 ], // T_Oben des letzten aktiven Ziels
[ "$State_T_Max_Alt", "float", 0.0 ], // T_Max des letzten aktiven Ziels
// --- INTERMEDIATE CALCULATIONS (Variablen für Zwischenschritte) ---
// dTs
[ "$Calc_dT_WW", "float", 0.0 ],
[ "$Calc_dT_Puffer", "float", 0.0 ],
[ "$Calc_dT_Eis", "float", 0.0 ],
// Conditions per Target
[ "$Cond_WW_Ready", "bool", false ],
[ "$Cond_WW_NotFull", "bool", false ],
[ "$Cond_WW_CanLoad", "bool", false ],
[ "$Cond_Puffer_Ready", "bool", false ],
[ "$Cond_Puffer_NotFull", "bool", false ],
[ "$Cond_Puffer_CanLoad", "bool", false ],
[ "$Cond_Eis_Ready", "bool", false ],
[ "$Cond_Eis_NotFull", "bool", false ],
[ "$Cond_Eis_CanLoad", "bool", false ],
// Priority Logic Result
[ "$Calc_NextTargetID", "integer", 0 ],
[ "$Target_Temp1", "integer", 0 ],
[ "$Target_Temp2", "integer", 0 ],
// Pump Control FlipFlop (Nachbau)
[ "$Cond_FF_Set", "bool", false ],
[ "$Cond_FF_Reset", "bool", false ],
[ "$FF_InStat", "integer", 0 ],
[ "$FF_Out_Neu", "bool", false ],
// Reset Condition Logic
[ "$dT_Alt_Ziel", "float", 0.0 ],
[ "$Reset_Cond1", "bool", false ],
[ "$Reset_Cond2", "bool", false ],
[ "$Cond_FF_Reset_Raw", "bool", false ],
[ "$OldTargetExists", "bool", false ],
// PID Control
[ "$Calc_dT_Ist_Selected", "float", 0.0 ],
[ "$Calc_PID_Manipulate", "float", 0.0 ],
[ "$Calc_PID_Limited", "float", 0.0 ],
[ "$Limiter_Val_Ok", "bool", false ],
[ "$Calc_PumpSpeedPerc_Volt", "float", 0.0 ],
// Valve Control
[ "$Calc_Ventil1_On", "bool", false ],
[ "$Calc_Ventil2_On", "bool", false ],
[ "$Ventil1_Cond1", "bool", false ],
[ "$Ventil2_Cond1", "bool", false ],
// State Saving Temps
[ "$Temp_T_Unten_Neu", "float", 0.0 ],
[ "$Temp_T_Oben_Neu", "float", 0.0 ],
[ "$Temp_T_Max_Neu", "float", 0.0 ],
// Formulas
[ "$Formula_dT", "string", "X1 - X2" ],
[ "$Formula_ScaleVolt", "string", "(X1 / 100.0) * 10.0" ],
// --- OUTPUTS (Variablen, die nach außen gehen) ---
[ "$O_PumpSpeedVolt", "float", 0.0 ],
[ "$O_Ventil1_On", "bool", false ],
[ "$O_Ventil2_On", "bool", false ],
[ "$O_PumpState", "bool", false ], // Debug Output
[ "$O_ActiveTargetID", "integer", 0 ], // Debug Output
// --- CONSTANTS ---
[ "$KonstTrue", "bool", true ],
[ "$KonstFalse", "bool", false ],
[ "$Konst0_float", "float", 0.0 ],
[ "$Konst0_int", "integer", 0 ],
[ "$Konst1_int", "integer", 1 ], // Ziel-ID für WW
[ "$Konst2_int", "integer", 2 ], // Ziel-ID für Puffer
[ "$Konst3_int", "integer", 3 ], // Ziel-ID für Eis
// --- INHIBIT ---
// [ "$VAR<Inhibit?>", "bool", false ] // Bei Bedarf einkommentieren
],
"Module": [
// 0. Optional Break
// [ "Break", [ "$VAR<Inhibit?>" ] ], // Bei Bedarf einkommentieren (Komma danach!)
// --- 1. Calculate dTs ---
[ "CalcFormula", [ "$I_T_Koll", "$I_T_WW_U" ], "$Calc_dT_WW", "$Formula_dT" ],
[ "CalcFormula", [ "$I_T_Koll", "$I_T_Puffer_U" ], "$Calc_dT_Puffer", "$Formula_dT" ],
[ "CalcFormula", [ "$I_T_Koll", "$I_T_Eis" ], "$Calc_dT_Eis", "$Formula_dT" ],
// --- 2. Check Conditions per Target ---
[ "Comparator", "$Calc_dT_WW", "$Cond_WW_Ready", "$P_EIN_HYS" ],
[ "Comparator", "$P_T_WW_MAX", "$Cond_WW_NotFull", "$I_T_WW_O" ],
[ "And", [ "$Cond_WW_Ready", "$Cond_WW_NotFull" ], "$Cond_WW_CanLoad" ],
[ "Comparator", "$Calc_dT_Puffer", "$Cond_Puffer_Ready", "$P_EIN_HYS" ],
[ "Comparator", "$P_T_PUFFER_MAX","$Cond_Puffer_NotFull", "$I_T_Puffer_O" ],
[ "And", [ "$Cond_Puffer_Ready", "$Cond_Puffer_NotFull" ], "$Cond_Puffer_CanLoad" ],
[ "Comparator", "$Calc_dT_Eis", "$Cond_Eis_Ready", "$P_EIN_HYS" ],
[ "Comparator", "$P_T_EIS_MAX", "$Cond_Eis_NotFull", "$I_T_Eis" ],
[ "And", [ "$Cond_Eis_Ready", "$Cond_Eis_NotFull" ], "$Cond_Eis_CanLoad" ],
// --- 3. Priority Logic (Feste Prio: WW > Puffer > Eis) ---
[ "Multiplexer", [ "$Konst0_int", "$Konst3_int" ], "$Target_Temp1", "$Cond_Eis_CanLoad" ],
[ "Multiplexer", [ "$Target_Temp1", "$Konst2_int" ], "$Target_Temp2", "$Cond_Puffer_CanLoad" ],
[ "Multiplexer", [ "$Target_Temp2", "$Konst1_int" ], "$Calc_NextTargetID", "$Cond_WW_CanLoad" ],
// --- 4. Pump Control FlipFlop (Nachbau) ---
[ "Comparator", "$Calc_NextTargetID", "$Cond_FF_Set", "$Konst1_int" ], // Set wenn ID >= 1
[ "Comparator", "$State_ActiveTargetID_Alt", "$OldTargetExists", "$Konst1_int" ], // Altes Ziel vorhanden?
[ "CalcFormula", [ "$I_T_Koll", "$State_T_Unten_Alt" ], "$dT_Alt_Ziel", "$Formula_dT" ],
[ "Comparator", "$P_AUS_HYS", "$Reset_Cond1", "$dT_Alt_Ziel" ], // Reset wenn dT < AUS_HYS
[ "Comparator", "$State_T_Oben_Alt", "$Reset_Cond2", "$State_T_Max_Alt" ], // Reset wenn T_Oben >= T_Max
[ "Or", [ "$Reset_Cond1", "$Reset_Cond2" ], "$Cond_FF_Reset_Raw" ],
[ "And", [ "$OldTargetExists", "$Cond_FF_Reset_Raw" ], "$Cond_FF_Reset" ],
[ "BinaryMultiplexer", [ "$Cond_FF_Set", "$Cond_FF_Reset" ], "$FF_InStat" ],
[ "Multiplexer", [ "$FF_Out_Alt", "$KonstFalse", "$KonstTrue", "$KonstTrue" ], "$FF_Out_Neu", "$FF_InStat" ],
// --- 5. PID Control ---
[ "Multiplexer", [ "$Konst0_float", "$Calc_dT_WW", "$Calc_dT_Puffer", "$Calc_dT_Eis" ], "$Calc_dT_Ist_Selected", "$Calc_NextTargetID" ],
[ "PID_awu", "$P_dT_Soll", "$Calc_dT_Ist_Selected", "$Calc_PID_Manipulate", "$P_Kp", "$P_Ki", "$P_Kd", "$P_PID_LL", "$P_PID_UL" ],
// --- 6. Pump Output Calculation ---
[ "Limiter", "$Calc_PID_Manipulate", "$Calc_PID_Limited", "$Limiter_Val_Ok", [ "$P_Pump_Min_Speed", "$P_Pump_Max_Speed" ] ],
[ "CalcFormula", [ "$Calc_PID_Limited" ], "$Calc_PumpSpeedPerc_Volt", "$Formula_ScaleVolt" ],
[ "Multiplexer", [ "$Konst0_float", "$Calc_PumpSpeedPerc_Volt" ], "$O_PumpSpeedVolt", "$FF_Out_Neu" ],
// --- 7. Valve Control ---
[ "Comparator", "$Calc_NextTargetID", "$Ventil1_Cond1", "$Konst2_int" ], // V1=EIN wenn ID >= 2
[ "Multiplexer", [ "$KonstFalse", "$KonstTrue" ], "$Calc_Ventil1_On", "$Ventil1_Cond1" ],
[ "Comparator", "$Calc_NextTargetID", "$Ventil2_Cond1", "$Konst3_int" ], // V2=EIN wenn ID >= 3
[ "Multiplexer", [ "$KonstFalse", "$KonstTrue" ], "$Calc_Ventil2_On", "$Ventil2_Cond1" ],
// --- 8. Persist State for Next Cycle using Latch ---
[ "Latch", "$FF_Out_Neu", "$FF_Out_Alt", "$KonstTrue", 0 ],
[ "Latch", "$Calc_NextTargetID", "$State_ActiveTargetID_Alt", "$KonstTrue", 0 ],
[ "Multiplexer", [ "$Konst0_float", "$I_T_WW_U", "$I_T_Puffer_U", "$I_T_Eis" ], "$Temp_T_Unten_Neu", "$Calc_NextTargetID" ],
[ "Latch", "$Temp_T_Unten_Neu", "$State_T_Unten_Alt", "$KonstTrue", 0 ],
[ "Multiplexer", [ "$Konst0_float", "$I_T_WW_O", "$I_T_Puffer_O", "$I_T_Eis" ], "$Temp_T_Oben_Neu", "$Calc_NextTargetID" ],
[ "Latch", "$Temp_T_Oben_Neu", "$State_T_Oben_Alt", "$KonstTrue", 0 ],
[ "Multiplexer", [ "$Konst0_float", "$P_T_WW_MAX", "$P_T_PUFFER_MAX", "$P_T_EIS_MAX" ], "$Temp_T_Max_Neu", "$Calc_NextTargetID" ],
[ "Latch", "$Temp_T_Max_Neu", "$State_T_Max_Alt", "$KonstTrue", 0 ],
// --- 9. Assign Outputs ---
[ "Multiplexer", [ "$Calc_Ventil1_On", "$Calc_Ventil1_On" ], "$O_Ventil1_On", "$KonstTrue" ],
[ "Multiplexer", [ "$Calc_Ventil2_On", "$Calc_Ventil2_On" ], "$O_Ventil2_On", "$KonstTrue" ],
[ "Multiplexer", [ "$FF_Out_Neu", "$FF_Out_Neu" ], "$O_PumpState", "$KonstTrue" ],
[ "Multiplexer", [ "$Calc_NextTargetID", "$Calc_NextTargetID" ], "$O_ActiveTargetID", "$KonstTrue" ]
],
"Input": [
// Sensoren
[ "T Kollektor", "Temperatur Kollektor [C]", "$I_T_Koll", "c" ],
[ "T WW Unten", "Temperatur WW Speicher Unten [C]", "$I_T_WW_U", "c" ],
[ "T WW Oben", "Temperatur WW Speicher Oben [C]", "$I_T_WW_O", "c" ],
[ "T Puffer Unten", "Temperatur Pufferspeicher Unten [C]", "$I_T_Puffer_U", "c" ],
[ "T Puffer Oben", "Temperatur Pufferspeicher Oben [C]", "$I_T_Puffer_O", "c" ],
[ "T Eisspeicher", "Temperatur Eisspeicher [C]", "$I_T_Eis", "c" ],
// Parameter
[ "Ein Hysterese", "Einschaltdifferenz Kollektor > Speicher [K]", "$P_EIN_HYS", "c" ],
[ "Aus Hysterese", "Ausschaltdifferenz Kollektor > Speicher [K]", "$P_AUS_HYS", "c" ],
[ "T WW Max", "Maximale WW Temperatur [C]", "$P_T_WW_MAX", "c" ],
[ "T Puffer Max", "Maximale Puffer Temperatur [C]", "$P_T_PUFFER_MAX", "c" ],
[ "T Eis Max", "Maximale Eisspeicher Temperatur [C]", "$P_T_EIS_MAX", "c" ],
[ "dT Soll", "Solldifferenz für PID Regelung [K]", "$P_dT_Soll", "c" ],
[ "PID Kp", "Proportionalbeiwert", "$P_Kp", "c" ],
[ "PID Ki", "Integralbeiwert", "$P_Ki", "c" ],
[ "PID Kd", "Differentialbeiwert", "$P_Kd", "c" ],
[ "Pump Min Speed", "Minimale Pumpendrehzahl [%]", "$P_Pump_Min_Speed", "c" ],
[ "Pump Max Speed", "Maximale Pumpendrehzahl [%]", "$P_Pump_Max_Speed", "c" ]
],
"Output": [
[ "Pumpe Spannung", "Ausgangsspannung für Pumpe [0-10V]", "$O_PumpSpeedVolt", "c" ],
[ "Ventil 1 (Puffer/Eis)", "Schaltet auf Puffer/Eis (true=EIN)", "$O_Ventil1_On", "c" ],
[ "Ventil 2 (Eis)", "Schaltet auf Eisspeicher (true=EIN)", "$O_Ventil2_On", "c" ],
[ "DEBUG Pumpe Status", "Zeigt aktuellen Pumpenstatus (true=AN)", "$O_PumpState", "c" ],
[ "DEBUG Aktives Ziel", "Zeigt aktuell angefordertes Ziel (0=Aus,1=WW,2=Puffer,3=Eis)", "$O_ActiveTargetID", "c" ]
]
}
Wichtige Hinweise für den Forum-Post:
Status: Kläre, dass dieser Code syntaktisch korrekt ist (lässt sich speichern), aber die Logik intensiv getestet und an die eigene Anlage angepasst werden muss. Es ist eine Beta-Version / Vorlage.
Parameter: Hebe hervor, dass alle $P_...-Werte (Hysteresen, Max-Temperaturen, PID-Werte, Pumpen-Limits) in $Level oder über die $Input-Pins unbedingt an die eigene Anlage angepasst werden müssen.
Priorität: Erwähne deutlich, dass die Priorität fest auf WW > Puffer > Eis eingestellt ist und die Prio-Parameter $P_Prio_... aktuell nicht ausgewertet werden.
Sensoren/Aktoren: Erkläre, dass die $I_...-Inputs mit den passenden Sensor-Objekten und die $O_...-Outputs mit den Aktor-Objekten (und Debug-Objekten) im TWS verknüpft werden müssen.
Risiko: Füge einen klaren Hinweis hinzu, dass die Verwendung auf eigene Gefahr erfolgt und eine Fehlkonfiguration zu Schäden führen kann.
Feedback: Bitte um konstruktives Feedback, Testergebnisse und Verbesserungsvorschläge.
Ich hoffe, dieser Beitrag ist eine gute Grundlage für das Forum und hilft anderen Nutzern weiter! Viel Erfolg beim Testen!