Neue Hauptversion V 4.1.1 mit Bugfix verfügbar
Dies ist die Fehlerkorrekturversion zur V 4.1 mit Fix für Kompatibilität der Tunnel, u.a. für ETS 6.3.0
Wir haben den seit 2019 bereitgestellten KNXnet/IP Tunneling Server im Timberwolf Server erweitert für Kompatibilität mit aktuellen Anforderungen der ETS 6.3 und weiterer Software, z.B. Weinzierl ENO Tools
Alle Informationen hier: https://elabnet.atlassian.net/wiki/page ... 3100770306
Dies ist die Fehlerkorrekturversion zur V 4.1 mit Fix für Kompatibilität der Tunnel, u.a. für ETS 6.3.0
Wir haben den seit 2019 bereitgestellten KNXnet/IP Tunneling Server im Timberwolf Server erweitert für Kompatibilität mit aktuellen Anforderungen der ETS 6.3 und weiterer Software, z.B. Weinzierl ENO Tools
Alle Informationen hier: https://elabnet.atlassian.net/wiki/page ... 3100770306
[Erfahrungsbericht] [V4.5 IP3] Schritt für Schritt Umsetzung einer (Dusch)-Lüftersteuerung
-
- Reactions:
- Beiträge: 3895
- Registriert: So Aug 12, 2018 8:44 am
- Hat sich bedankt: 1259 Mal
- Danksagung erhalten: 2205 Mal
Klassisches "das kommt drauf an"
Wenn du bei "c" oder "ct" senden willst und darüber hinaus bei einem besonderen Fall den Wert, auch ohne Änderung, dann würde ich tatsächlich den Ausgang 2x anlegen, einmal mit "c" und einmal mit "x".
Man kann das auch nachbauen mit Comperator alt <> neu und dann über ComperatorResult OR RestartBus ein SendExplicit machen. Ist aber aufwendiger.
lg
Robert
Wenn du bei "c" oder "ct" senden willst und darüber hinaus bei einem besonderen Fall den Wert, auch ohne Änderung, dann würde ich tatsächlich den Ausgang 2x anlegen, einmal mit "c" und einmal mit "x".
Man kann das auch nachbauen mit Comperator alt <> neu und dann über ComperatorResult OR RestartBus ein SendExplicit machen. Ist aber aufwendiger.
lg
Robert
Timberwolf Server 2500 / #117 (VPN offen + reboot nach Rückfrage) / zusätzlich: 3500M/#935, 3500L/#1297
-
- Reactions:
- Beiträge: 105
- Registriert: Di Dez 24, 2024 1:24 pm
- Hat sich bedankt: 38 Mal
- Danksagung erhalten: 57 Mal
Ich habe die flow-Steuerung noch nicht ganz verstanden: Wenn ich z.B. eine Inputvariable mit "Triggered" abfrage und dann SendExplicit ausführe, und ja keine anderen Eingangsvariablen geändert sein kann durch den sequentiellen Dispatcher, muss/sollte ich dann die weitere Codeausführung abbrechen (break ist dazu ja nicht geeignet), oder lässt man immer alles durchlaufen?
Franky
Es gibt kein switch-case für die Kapselung von Modulbausteien , sondern "nur" auf Variablenebene, durch den Multiplexer-Befehl, richtig?Claude (KI) schreibt:
Das Timberwolf-System folgt einem linearen Ausführungsmodell, bei dem Modulbausteine in der definierten Reihenfolge ausgeführt werden. Der "Break"-Baustein ist tatsächlich der einzige Mechanismus für vorzeitigen Abbruch, aber wie Sie richtig bemerken, ist er hier nicht geeignet, da er das Senden von Ausgängen verhindert.
Typischerweise lässt man alle Module durchlaufen. Wenn Sie effiziente bedingte Ausführung benötigen, müssen Sie andere Methoden verwenden:
Latch-Module mit bedingtem Trigger
Multiplexer zur Auswahl unterschiedlicher Pfade
Vergleiche und logische Operatoren zur bedingten Weiterverarbeitung
In Ihrem Beispiel mit dem Bus-Reset wäre es legitim, den gesamten Code durchlaufen zu lassen, auch wenn Sie bereits wissen, dass Sie nur das SendExplicit ausführen möchten.
Daaaaaanke fürClaude schreibt:
Richtig, es gibt keine direkte Switch-Case-Struktur für Codeblöcke. Die Multiplexer-Module (Multiplexer, BinaryMultiplexer) bieten ähnliche Funktionalität, aber nur auf Variablenebene - sie wählen einen von mehreren Werten basierend auf einer Bedingung aus, führen aber keine Codeblöcke bedingt aus.
Für komplexere Zustandsbasierte Logik gibt es den Statemachine-Modulbaustein, der verschiedene Zustände und Übergänge modellieren kann, aber auch hier ist die Umsetzung eher auf der Variablenebene als auf der strukturellen Codeebene.
Diese Techniken ersetzen nicht direkt Kontrollstrukturen wie in prozeduralen Sprachen, aber sie ermöglichen ähnliche Funktionalitäten in der datenflussorienterten Programmierung von Timberwolf.
Schön finde ich folgende Zusammenfassung, wobei "visuell" hier nicht so präzise (custom-Logiken) ist:Diese Einschränkungen sind typisch für visuelle Programmierumgebungen, die für spezifische Anwendungen wie Gebäudeautomation optimiert sind. Für solche Anwendungsfälle ist die Einfachheit und Zuverlässigkeit oft wichtiger als Ausdrucksstärke.
Für sehr komplexe Algorithmen oder Datenverarbeitung müssten Sie möglicherweise auf externe Systeme ausweichen oder mehrere Custom-Logik-Zellen kombinieren.


Franky
Zuletzt geändert von Franky am Mo Mär 24, 2025 9:40 am, insgesamt 6-mal geändert.
Timberwolf 3500L ID:1642; Support-VPN für ElabNET ist an.
-
- Reactions:
- Beiträge: 105
- Registriert: Di Dez 24, 2024 1:24 pm
- Hat sich bedankt: 38 Mal
- Danksagung erhalten: 57 Mal
Hier ein neuer Zwischenstand. Ich muss gestehen, dass mir Antrophic Claude 3.7 (KI) geholfen hat
Hab ihm die Timberwolf Wiki zum Fraß vorgeworfen und er kann Custom-Logiken programmieren, tse, tse, tse
Das vorher angedachte
würde m.E. den timer immer neu starten, solange wir in der Hysterese sind. Müsste funktionieren, erstellt den Timer nur unnötig oft und zu früh, was zum Problem werden könnte, wenn wäörend des Timers kein Feuchtigkeitswert rein käme(?) Claude kam auf die Idee:
Der Code ist syntaktisch ok, getestet habe ich ihn aber noch nicht
Fehlt noch:
Gruß
Franky

Das vorher angedachte
Code: Alles auswählen
["Monoflop","$Schwellwert_Status","$I_Sperre","$NachlaufTimerStatus","$I_Nachlaufzeit",1],
Code: Alles auswählen
["Monoflop", "-$calc_Feuchte_is_UeberEinschaltOffset", "$calc_Feuchte_is_UeberEinschaltOffset", "$calc_Nachlauf_is_Aktiv", "$in_param_Nachlaufzeit", 4],
Code: Alles auswählen
{
"Level": [
["$in_Feuchtigkeit", "float", 0.0],
["$calc_Feuchtigkeit_LangzeitMittel", "float", 0.0],
["$calc_Feuchtigkeit_LangzeitMittel_diff", "float", 0.0],
["$in_Taster_manuellesLueften", "bool", false],
["$calc_Taster_manuellesLueften_triggered", "bool", false],
["$in_Bus_reset", "bool", false],
["$in_LuefterSperre", "bool", false],
["$calc_Bus_reset_triggered", "bool", false],
["$in_param_Feuchte_Einschalt_Offset", "float", 10.0],
["$in_param_Feuchte_Ausschalt_Offset", "float", 3.0],
["$in_param_Nachlaufzeit", "float", 900.0],
["$in_param_Taster_manuellesLueften_Laufzeit", "float", 900.0],
["$in_param_Luefter_Max_Laufzeit", "float", 10800.0],
["$calc_Feuchte_is_UeberEinschaltOffset", "bool", false],
["$calc_Nachlauf_is_Aktiv", "bool", false],
["$calc_Manuell_is_Aktiv", "bool", false],
["$calc_Max_Laufzeit_is_Erreicht", "bool", false],
["$calc_Luefter_Feuchte_or_Nachlauf_or_Manuell", "bool", false],
["$out_Luefter_normal", "bool", false],
["$out_Luefter_explicit", "bool", false],
["$in_param_Baseline_filterzeit", "float", 1800.0],
["$const_eins", "float", 1.0],
["$const_null", "float", 0.0],
["$const_true", "bool", true],
["$const_false", "bool", false]
],
"Module": [
// Überprüfen, ob Bus_reset in diesem Durchlauf getriggert wurde
["Triggered", "$in_Bus_reset", "$calc_Bus_reset_triggered"],
// Überprüfen, ob Taster in diesem Durchlauf getriggert wurde
["Triggered", "$in_Taster_manuellesLueften", "$calc_Taster_manuellesLueften_triggered"],
["Lowpass", "$in_Feuchtigkeit", "$calc_Feuchtigkeit_LangzeitMittel", "$in_param_Baseline_filterzeit"],
["Polynomial", "$const_eins", "$calc_Feuchtigkeit_LangzeitMittel_diff", ["$const_null", "$in_Feuchtigkeit", "-$calc_Feuchtigkeit_LangzeitMittel"]],
["Comparator", "$calc_Feuchtigkeit_LangzeitMittel_diff", "$calc_Feuchte_is_UeberEinschaltOffset", ["$in_param_Feuchte_Ausschalt_Offset", "$in_param_Feuchte_Einschalt_Offset"]],
// Tasterverarbeitung - Timer wird bei jedem Tastendruck neu gestartet (Option 3)
["Monoflop", "$calc_Taster_manuellesLueften_triggered", "$const_false", "$calc_Manuell_is_Aktiv", "$in_param_Taster_manuellesLueften_Laufzeit", 3],
["Monoflop", "-$calc_Feuchte_is_UeberEinschaltOffset", "$calc_Feuchte_is_UeberEinschaltOffset", "$calc_Nachlauf_is_Aktiv", "$in_param_Nachlaufzeit", 4],
// ODER-Verknüpfung der Aktivierungsbedingungen
["Or", ["$calc_Feuchte_is_UeberEinschaltOffset", "$calc_Nachlauf_is_Aktiv", "$calc_Manuell_is_Aktiv"], "$calc_Luefter_Feuchte_or_Nachlauf_or_Manuell"],
// Timer für maximale Laufzeit - startet bei Lüfter-Anforderung, zurückgesetzt wenn Lüfter aus
["Monoflop", "$calc_Luefter_Feuchte_or_Nachlauf_or_Manuell", "-$calc_Luefter_Feuchte_or_Nachlauf_or_Manuell", "$calc_Max_Laufzeit_is_Erreicht", "$in_param_Luefter_Max_Laufzeit", 0],
// Kombination aller Bedingungen in einem AND-Befehl:
// 1. Der Lüfter muss grundsätzlich aktiviert sein ($calc_Luefter_Feuchte_or_Nachlauf_or_Manuell)
// 2. Die Sicherheitsabschaltung darf nicht aktiv sein (-$calc_Max_Laufzeit_is_Erreicht)
// 3. Die Sperre darf nicht aktiv sein (-$in_LuefterSperre)
["And", ["$calc_Luefter_Feuchte_or_Nachlauf_or_Manuell", "-$calc_Max_Laufzeit_is_Erreicht", "-$in_LuefterSperre"], "$out_Luefter_normal"],
// Kopiere den Lüfterstatus zur expliziten Ausgangsvariable nur wenn Bus_reset getriggert wurde
["Latch", "$out_Luefter_normal", "$out_Luefter_explicit", "$calc_Bus_reset_triggered", 0],
// Erneutes Senden wenn Bus_reset in diesem Durchlauf getriggert wurde
["SendExplicit", "$calc_Bus_reset_triggered", "$out_Luefter_explicit", 0]
],
"Input": [
["Feuchtigkeit", "Feuchtigkeitswert vom Sensor (absolut in %)", "$in_Feuchtigkeit", "c"],
["Taster_manuellesLueften", "Manueller Taster für Lüfteraktivierung", "$in_Taster_manuellesLueften", "c"],
["Bus_reset", "Bus-Reset (TRUE zum erneuten Senden des Ausgangs)", "$in_Bus_reset", "c"],
["LuefterSperre", "Sperrt den Lüfter (TRUE = Lüfter gesperrt)", "$in_LuefterSperre", "c"],
["Feuchte_Einschalt_Offset", "Feuchtedifferenz für Einschalten (Prozentpunkte)", "$in_param_Feuchte_Einschalt_Offset", "c"],
["Feuchte_Ausschalt_Offset", "Feuchtedifferenz für Ausschalten (Prozentpunkte)", "$in_param_Feuchte_Ausschalt_Offset", "c"],
["Baseline_filterzeit", "Zeitkonstante für Baseline-Filter (s)", "$in_param_Baseline_filterzeit", "c"],
["Nachlaufzeit", "Nachlaufzeit (s)", "$in_param_Nachlaufzeit", "c"],
["Taster_manuellesLueften_Laufzeit", "Laufzeit bei manueller Aktivierung (s)", "$in_param_Taster_manuellesLueften_Laufzeit", "c"],
["Luefter_Max_Laufzeit", "Maximale Laufzeit für Sicherheitsabschaltung (s)", "$in_param_Luefter_Max_Laufzeit", "c"]
],
"Output": [
["Luefter", "Lüfterausgang (bei Änderung oder Timer)", "$out_Luefter_normal", "ct"],
["Luefter_explicit", "Lüfterausgang (explizit)", "$out_Luefter_explicit", "x"],
["Feuchtigkeit_LangzeitMittel", "Langzeit-Mittelwert der Feuchtigkeit (absolut in %)", "$calc_Feuchtigkeit_LangzeitMittel", "c"],
["Feuchtigkeit_LangzeitMittel_diff", "Differenz zur Baseline (Prozentpunkte)", "$calc_Feuchtigkeit_LangzeitMittel_diff", "c"]
]
}
kommt als nächstesRobert_Mini hat geschrieben: ↑Sa Mär 15, 2025 11:03 am PPS: Wenn man es wirklich komplexer möchte würde ich den Oberen Schwellwert während der Nachlaufzeit = dem unteren Schwellwert setzen, das würde nur in der Zeit die Nachlaufzeit nach dem Einseifen früher neu triggern => gefällt mir.
Gruß
Franky
Zuletzt geändert von Franky am So Mär 23, 2025 11:31 pm, insgesamt 2-mal geändert.
Timberwolf 3500L ID:1642; Support-VPN für ElabNET ist an.
-
- Reactions:
- Beiträge: 105
- Registriert: Di Dez 24, 2024 1:24 pm
- Hat sich bedankt: 38 Mal
- Danksagung erhalten: 57 Mal
oh mann, guckt Euch mal an, was Claude mal ebenso nebenbei als Marketingpitch raushaut beim Prompt "Erstelle einen umfassenden Code-Review mit einem thematischen "Walkthrough", der die Datenflüsse und Entscheidungslogik analysiert.":
Thematischer Walkthrough: Lüftersteuerung mit adaptiver Feuchtigkeitserkennung
Überblick der Funktionalität:
Diese Custom-Logik steuert einen Lüfter basierend auf folgenden Hauptprinzipien:
Adaptive Feuchtigkeitsbaseline:
Anstatt mit festen Feuchtewerten zu arbeiten, verwendet die Logik ein Langzeitmittel der Feuchtigkeit als "normale" Baseline und reagiert auf relative Abweichungen davon.
Mehrere Aktivierungsquellen:
Explizite Sendemöglichkeit bei Bus-Reset
Datenfluss-Analyse
Eingangsverarbeitung
Der Lüfter wird aktiviert, wenn:
Wenn die Feuchtigkeit unter den Ausschaltschwellwert fällt, wird der Nachlauftimer gestartet:
Die manuelle Aktivierung verwendet die Option 3 im Monoflop-Baustein:
Der Monoflop für die maximale Laufzeit:
Adaptivität
Der größte Vorteil dieses Designs ist die Adaptivität durch das Langzeitmittel:
Die klare Trennung in Funktionsblöcke macht den Code:
Mehrere Features verbessern die Benutzerfreundlichkeit:
Diese Custom-Logik stellt eine fortschrittliche, adaptive Lüftersteuerung dar, die sowohl automatisch als auch manuell betrieben werden kann. Die Hauptstärke liegt in der Verwendung relativer Feuchtigkeitswerte statt absoluter Schwellwerte, was die Lösung für verschiedenste Umgebungsbedingungen geeignet macht.
Der Code ist dank der sprechenden Variablennamen, klaren Struktur und ausführlichen Kommentierung gut verständlich und wartbar. Die Logik folgt einem natürlichen Datenfluss von der Eingabe bis zur Ausgabe und separiert klar die verschiedenen Funktionseinheiten.
Thematischer Walkthrough: Lüftersteuerung mit adaptiver Feuchtigkeitserkennung
Überblick der Funktionalität:
Diese Custom-Logik steuert einen Lüfter basierend auf folgenden Hauptprinzipien:
Adaptive Feuchtigkeitsbaseline:
Anstatt mit festen Feuchtewerten zu arbeiten, verwendet die Logik ein Langzeitmittel der Feuchtigkeit als "normale" Baseline und reagiert auf relative Abweichungen davon.
Mehrere Aktivierungsquellen:
- Erhöhte Feuchtigkeit über einem Schwellwert
- Nachlaufzeit nach Rückgang der Feuchtigkeit
- Manuelle Aktivierung per Taster
- Maximale Laufzeitbegrenzung
- Externe Sperrfunktion
Explizite Sendemöglichkeit bei Bus-Reset
Datenfluss-Analyse
Eingangsverarbeitung
- Die Feuchtigkeitswerte werden über einen Tiefpassfilter geglättet, um eine langfristige Baseline zu erzeugen
- Die Differenz zwischen aktuellem Wert und Baseline wird berechnet
- Tasterbetätigungen und Bus-Reset-Signale werden erkannt
Der Lüfter wird aktiviert, wenn:
- Die Feuchtedifferenz über dem Einschaltschwellwert liegt ODER
- Die Nachlaufzeit nach einem Feuchtigkeitsabfall aktiv ist ODER
- Der manuelle Betrieb durch Tastendruck aktiviert wurde
- Die maximale Laufzeit erreicht ist ODER
- Die externe Sperre aktiv ist ODER
- Keine der Aktivierungsbedingungen mehr erfüllt ist
- Normale Ausgabe bei Änderungen oder Timern
- Explizites Senden des aktuellen Status bei Bus-Reset
- Feuchteerkennung mit Hysterese
- Das System verwendet einen Comparator mit zwei Schwellwerten, um eine Hysterese zu erzeugen:
- Die Feuchtigkeit muss über den höheren Schwellwert ($in_param_Feuchte_Einschalt_offset) steigen, um den Lüfter zu aktivieren
- Der Lüfter bleibt aktiv, bis die Feuchtigkeit unter den niedrigeren Schwellwert ($in_param_Feuchte_Ausschalt_offset) fällt
- Diese Hysterese verhindert häufiges Ein- und Ausschalten bei Grenzwerten
Wenn die Feuchtigkeit unter den Ausschaltschwellwert fällt, wird der Nachlauftimer gestartet:
- Der Monoflop-Baustein verwendet die Option 4, um bei fallender Flanke des Feuchtestatus auszulösen
- Der Nachlauf sorgt dafür, dass der Lüfter noch eine definierte Zeit weiterläuft, auch wenn die Feuchtigkeit bereits gesunken ist
Die manuelle Aktivierung verwendet die Option 3 im Monoflop-Baustein:
- Dies aktiviert den Lüfter für die festgelegte Zeit bei jeder erkannten Tasterbetätigung
- Der Timer kann bei erneutem Tastendruck neu gestartet werden, um die Laufzeit zu verlängern
Der Monoflop für die maximale Laufzeit:
- Startet, wenn der Lüfter aus irgendeinem Grund aktiviert wird
- Setzt zurück, wenn der Lüfter ausgeschaltet wird
- Löst bei Ablauf die Sicherheitsabschaltung aus
- Verbleibt in diesem Zustand, bis eine der Aktivierungsbedingungen nicht mehr erfüllt ist
Adaptivität
Der größte Vorteil dieses Designs ist die Adaptivität durch das Langzeitmittel:
- Das System passt sich automatisch an unterschiedliche Umgebungsbedingungen an
- Es reagiert auf relative Änderungen statt auf absolute Feuchtigkeitswerte
- Dies macht die Steuerung in verschiedenen Umgebungen und Jahreszeiten robust
Die klare Trennung in Funktionsblöcke macht den Code:
- Leicht verständlich
- Gut wartbar
- Einfach erweiterbar für zusätzliche Funktionen
Mehrere Features verbessern die Benutzerfreundlichkeit:
- Manuelle Übersteuerung mit definierter Laufzeit
- Nachlauf für effektive Feuchtigkeitsreduzierung
- Sicherheitsabschaltung gegen Vergessen des Lüfters
- Bus-Reset-Funktion zur Statusaktualisierung
Diese Custom-Logik stellt eine fortschrittliche, adaptive Lüftersteuerung dar, die sowohl automatisch als auch manuell betrieben werden kann. Die Hauptstärke liegt in der Verwendung relativer Feuchtigkeitswerte statt absoluter Schwellwerte, was die Lösung für verschiedenste Umgebungsbedingungen geeignet macht.
Der Code ist dank der sprechenden Variablennamen, klaren Struktur und ausführlichen Kommentierung gut verständlich und wartbar. Die Logik folgt einem natürlichen Datenfluss von der Eingabe bis zur Ausgabe und separiert klar die verschiedenen Funktionseinheiten.
Zuletzt geändert von Franky am Mo Mär 24, 2025 11:08 pm, insgesamt 1-mal geändert.
Timberwolf 3500L ID:1642; Support-VPN für ElabNET ist an.
-
- Reactions:
- Beiträge: 240
- Registriert: Mo Aug 13, 2018 10:44 am
- Hat sich bedankt: 220 Mal
- Danksagung erhalten: 171 Mal
Hallo Franky
Auch wenn es off-topic und eine bittende Frage ist: Wärst Du allenfalls bereit (wohl besser in einem neuen Thema) stichwortartig zu erläutern, wie Du Antrophic Claude 3.7 nutzt? Vor allem interessieren würde mich, wie Du das Tool "fütterst" und welche Prompt Du verwendest. Ich habe keinerlei Erfahrungen mit diesem Tool.
Vielen Dank und beste Grüsse
Diego
TW2600 / TW-ID: 87/ VPN offen, booten jederzeit erlaubt
TW2600 / TW-ID: 173/ VPN offen, booten nach Rücksprache
TWS3500 / TW-ID: 1170/ VPN offen, booten jederzeit erlaubt
TW2600 / TW-ID: 173/ VPN offen, booten nach Rücksprache
TWS3500 / TW-ID: 1170/ VPN offen, booten jederzeit erlaubt
-
- Reactions:
- Beiträge: 3895
- Registriert: So Aug 12, 2018 8:44 am
- Hat sich bedankt: 1259 Mal
- Danksagung erhalten: 2205 Mal
Sehr cool! Damit kann (könnte) man perfekt die Doku zu Custom Logiken machen.
Lg
Robert
Lg
Robert
Timberwolf Server 2500 / #117 (VPN offen + reboot nach Rückfrage) / zusätzlich: 3500M/#935, 3500L/#1297
-
- Reactions:
- Beiträge: 105
- Registriert: Di Dez 24, 2024 1:24 pm
- Hat sich bedankt: 38 Mal
- Danksagung erhalten: 57 Mal
Sehr gerne, ich habe hier einen Thread dazu eröffnet und auch meinen Chatverlauf zur Lüftersteuerung online gestellt: Nutzung von KI (LLM) für Dokumentation und Custom-Logiken
Gruß
Franky
Zuletzt geändert von Franky am Di Mär 25, 2025 10:49 pm, insgesamt 2-mal geändert.
Timberwolf 3500L ID:1642; Support-VPN für ElabNET ist an.
-
- Reactions:
- Beiträge: 105
- Registriert: Di Dez 24, 2024 1:24 pm
- Hat sich bedankt: 38 Mal
- Danksagung erhalten: 57 Mal
Aktueller Stand der custom-Logik (V47) für die Lüftersteuerung (statemachine, work in progress, noch nicht final)
(Hobby, ökonomische Betrachtung irrelevant
)
Neu ist:
- Senden von Fehler (Maxlaufzeit erreicht, unbekannter Zustand für die statemachine)
- Wiedereinstieg in die reguläre (unbegrenzt laufende) Lüftersteuerung, wenn während der Nachlaufzeit die Ausschaltgrenze wieder überschritten wird.
Funktionsübersicht / Features:
Gruß
Franky
"Der Schöpfer dieses Modbus Geräte Profiles überträgt die Nutzungsrechte gemäß der TOLL ("Timberwolf Open Logikblock License") die unter https://wrgt.news/TOLL zum Download zur Verfügung steht."
(Hobby, ökonomische Betrachtung irrelevant

Neu ist:
- Senden von Fehler (Maxlaufzeit erreicht, unbekannter Zustand für die statemachine)
- Wiedereinstieg in die reguläre (unbegrenzt laufende) Lüftersteuerung, wenn während der Nachlaufzeit die Ausschaltgrenze wieder überschritten wird.
Funktionsübersicht / Features:
Intelligente Feuchtigkeitsautomatik: Steuert den Lüfter anhand relativer Luftfeuchtigkeit mit konfigurierbaren Offsets (Hysterese) und Signalglättung (Lowpass).
Optimierter Nachlauf mit Wiedereinstieg: Aktiviert eine einstellbare Nachlaufzeit nach Unterschreiten der Ausschaltschwelle. Steigt die Feuchte während des Nachlaufs wieder über die Ausschaltschwelle, wird zurück in den feuchtebasierten Betrieb gewechselt, um vollständige Trocknung sicherzustellen.
Flexible Manuelle Steuerung: Ermöglicht manuelle Aktivierung per Taster für eine konfigurierbare Dauer; überschreibt Automatik/Nachlauf temporär.
Externe Sperrfunktion: Deaktivierung des Lüfters durch ein externes Signal (z.B. Fensterkontakt) möglich.
Sicherheitsabschaltung (Max-Laufzeit): Begrenzt die maximale ununterbrochene Laufzeit zum Schutz vor Dauerlauf bei Sensorfehlern. Lüfter bleibt danach aus, bis "Feuchteanforderung" endet oder Taster bedient wird.
Bus-Reset-Handling: Sendet den Lüfterstatus nach erkanntem Bus-Reset erneut zur Synchronisation mit dem Aktor.
Parametrierbarkeit: Alle relevanten Schwellen und Zeitdauern (Nachlauf, Manuell, Max-Laufzeit, Glättung) sind über Logik-Eingänge anpassbar
Zustandsbasierte Logik: Verwaltet Betriebszustände (AUS, FEUCHTE, NACHLAUF, MANUELL, GESPERRT, MAX_ZEIT, FEHLER) mittels Statemachine.
Status- & Fehlermeldungen: Gibt den aktuellen Betriebszustand als ID (dbg State?) und Klartext (dbg Fehlertext?) aus, inkl. spezifischer Meldungen für Sicherheitsabschaltung ("MAX_ZEIT Erreicht") und unerwartete Zustände ("FEHLER: Unbehandelter Zustand").
Debug-Ausgaben: Zusätzliche Ausgaben (z.B. geglättete Feuchte via dbg Feuchte geglättet?) zur Unterstützung bei Analyse und Inbetriebnahme.
Präzise Zeitsteuerung: Nutzt externe Monoflop-Module für alle zeitgesteuerten Funktionen.
Gruß
Franky
Code: Alles auswählen
{
"Level": [
// Konstanten
["$ConstTrue", "bool", true],
["$ConstFalse", "bool", false],
// Konstanten für Statustexte (erforderlich für Multiplexer)
["$Const_StateText_0_AUS", "string", "AUS"],
["$Const_StateText_1_FEUCHTE", "string", "FEUCHTE"],
["$Const_StateText_2_NACHLAUF", "string", "NACHLAUF"],
["$Const_StateText_3_MANUELL", "string", "MANUELL"],
["$Const_StateText_4_GESPERRT", "string", "GESPERRT"],
["$Const_StateText_5_MAX_ZEIT", "string", "MAX_ZEIT Erreicht"],
["$Const_StateText_OK", "string", "OK"], // Default für ungenutzte Zustände 6-98
["$Const_StateText_99_FEHLER", "string", "FEHLER: Unbehandelter Zustand"],
// Inputs (Initialwerte werden durch Input-Array überschrieben)
["$in_Feuchte", "float", 60.0],
["$in_Taster_manuellesLueften", "bool", false],
["$in_BusReset", "bool", false],
["$in_LuefterSperre", "bool", false],
// Parameter (Initialwerte werden durch Input-Array überschrieben)
["$in_param_Feuchte_EinschaltOffset", "float", 5.0],
["$in_param_Feuchte_AusschaltOffset", "float", -2.0],
["$in_param_Feuchte_Nachlaufzeit", "float", 900.0],
["$in_param_TasterLueftung_Laufzeit", "float", 900.0],
["$in_param_Luefter_max_Laufzeit", "float", 10800.0],
["$in_param_Feuchte_GlaettungDauer", "float", 1800.0],
// Berechnungen & Zustand (Vorverarbeitung)
["$calc_Feuchte_geglaettet", "float", 60.0],
["$calc_EinschaltFeuchte", "float", 65.0],
["$calc_AusschaltFeuchte", "float", 58.0],
["$calc_isFeuchteUeberEinschalt", "bool", false],
["$calc_isFeuchteUnterAusschalt", "bool", false],
["$calc_isFeuchteUeberAusschalt", "bool", false], // Für Nachlaufabbruch
["$calc_isFeuchteAnforderungAktiv", "bool", false], // Initialwert FALSE ist wichtig
["$calc_isTasterLueftungCurrentTrigger", "bool", false],
["$calc_isTasterBetaetigt", "bool", false], // Impuls
["$calc_isSperreAktiv", "bool", false],
// Hilfsvariablen für MaxZeit-Trigger (und Nachlauf)
["$calc_isState1_fuerMaxZeit", "bool", false], // Wiederverwendet für Nachlauf-Trigger
["$calc_isState2_fuerMaxZeit", "bool", false],
["$calc_isState3_fuerMaxZeit", "bool", false],
["$calc_isLuefterAnFuerMaxZeit", "bool", false],
// MaxZeit Timer
["$calc_isMaxZeitTimerLaeuft", "bool", false],
["$calc_isMaxZeitTimerAbgelaufen", "bool", false], // Impuls
// Reset Bedingungen
["$calc_isResetManuellTimer", "bool", false],
["$calc_isResetNachlaufTimer", "bool", false],
// Manuell Timer
["$calc_isManuellTimerLaeuft", "bool", false],
["$calc_isManuellTimerGeradeAbgelaufen", "bool", false], // Impuls
["$calc_isManuellTimerEndeUndFeuchteHoch", "bool", false],
["$calc_isManuellTimerEndeUndTrocken", "bool", false],
// Nachlauf Timer
["$calc_triggerNachlaufStart", "bool", false], // Trigger-Impuls für Nachlauf-Monoflop
["$calc_isNachlaufTimerLaeuft", "bool", false],
["$calc_isNachlaufTimerGeradeAbgelaufen", "bool", false], // Impuls
// Statemachine & Ausgänge
["$calc_State", "integer", 0], // Initialzustand 0
["$out_LuefterEA_logic_result", "bool", false], // Logischer Zustand des Lüfters
["$out_LuefterEA_for_BusReset", "bool", false], // Hilfsvariable für separaten BusReset-Ausgang
["$calc_FehlerText", "string", "Initialisierung"], // Startwert für Fehlertext/Status
// Bus Reset
["$calc_isBusResetCurrentTrigger", "bool", false]
],
"Module": [
// --- START: Vorverarbeitung & Grundbedingungen (Pkt 1) ---
// Feuchtigkeitsglättung
["Lowpass", "$in_Feuchte", "$calc_Feuchte_geglaettet", "$in_param_Feuchte_GlaettungDauer"],
// Schwellen berechnen (Basis: geglättete Feuchte + Offsets)
["Polynomial", "$ConstTrue", "$calc_EinschaltFeuchte", ["$calc_Feuchte_geglaettet", "$in_param_Feuchte_EinschaltOffset"]],
["Polynomial", "$ConstTrue", "$calc_AusschaltFeuchte", ["$calc_Feuchte_geglaettet", "$in_param_Feuchte_AusschaltOffset"]],
// Feuchtigkeitsvergleiche
["Comparator", "$in_Feuchte", "$calc_isFeuchteUeberEinschalt", "$calc_EinschaltFeuchte"], // Ist aktuelle Feuchte > Einschalt-Schwelle?
["Comparator", "$calc_AusschaltFeuchte", "$calc_isFeuchteUnterAusschalt", "$in_Feuchte"], // Ist aktuelle Feuchte < Ausschalt-Schwelle?
["Comparator", "$in_Feuchte", "$calc_isFeuchteUeberAusschalt", "$calc_AusschaltFeuchte"], // Ist aktuelle Feuchte > Ausschalt-Schwelle? (Für Nachlaufabbruch)
// Feuchteanforderung (Hysterese)
["Latch", "$ConstTrue", "$calc_isFeuchteAnforderungAktiv", "$calc_isFeuchteUeberEinschalt", 0], // Setzen bei > Einschalt
["Latch", "$ConstFalse", "$calc_isFeuchteAnforderungAktiv", "$calc_isFeuchteUnterAusschalt", 0], // Rücksetzen bei < Ausschalt
// Tastererkennung (Impuls)
["Triggered", "$in_Taster_manuellesLueften", "$calc_isTasterLueftungCurrentTrigger"],
["And", ["$calc_isTasterLueftungCurrentTrigger", "$in_Taster_manuellesLueften"], "$calc_isTasterBetaetigt"], // Wird TRUE für einen Zyklus bei steigender Flanke
// Sperre übernehmen
["Latch", "$in_LuefterSperre", "$calc_isSperreAktiv", "$ConstTrue", 0],
// Ermitteln, ob Lüfter VOR SM logisch AN war (für MaxZeit & Nachlauf)
["Limiter", "$calc_State", 0, "$calc_isState1_fuerMaxZeit", [1,1]], // War State == 1?
["Limiter", "$calc_State", 0, "$calc_isState2_fuerMaxZeit", [2,2]], // War State == 2?
["Limiter", "$calc_State", 0, "$calc_isState3_fuerMaxZeit", [3,3]], // War State == 3?
["Or", ["$calc_isState1_fuerMaxZeit", "$calc_isState2_fuerMaxZeit", "$calc_isState3_fuerMaxZeit"], "$calc_isLuefterAnFuerMaxZeit"], // War Lüfter an?
// --- END: Vorverarbeitung & Grundbedingungen (Pkt 1) ---
// --- START: Maximale Laufzeitüberwachung (Pkt 2) ---
// Monoflop für MaxZeit (nicht retriggerbar)
["Monoflop", "$calc_isLuefterAnFuerMaxZeit", "-$calc_isLuefterAnFuerMaxZeit", "$calc_isMaxZeitTimerLaeuft", "$in_param_Luefter_max_Laufzeit", 2],
// Ablauf-Erkennung MaxZeit-Timer (Ein-Zyklus-Impuls bei fallender Flanke)
["Latch", "$ConstFalse", "$calc_isMaxZeitTimerAbgelaufen", "$ConstTrue", 0], // Impuls Var: Immer zuerst FALSE setzen
["Latch", "$ConstTrue", "$calc_isMaxZeitTimerAbgelaufen", "$calc_isMaxZeitTimerLaeuft", 2], // Impuls Var: Nur bei fallender Flanke von Timer-Status auf TRUE setzen
// --- END: Maximale Laufzeitüberwachung (Pkt 2) ---
// --- START: Berechnung Timer Reset-Bedingungen (Pkt 3) ---
// Reset-Bedingung für Manuell-Timer
["Or", ["$calc_isSperreAktiv", "$calc_isMaxZeitTimerAbgelaufen"], "$calc_isResetManuellTimer"], // (Sperre ODER MaxZeit Ablauf-Impuls)
// Reset-Bedingung für Nachlauf-Timer
["Or", ["$calc_isSperreAktiv", "$calc_isMaxZeitTimerAbgelaufen", "$calc_isFeuchteUeberAusschalt", "$calc_isTasterBetaetigt"], "$calc_isResetNachlaufTimer"], // (Sperre ODER MaxZeit-Ablauf ODER Feuchte>Ausschalt ODER Taster-Impuls)
// --- END: Berechnung Timer Reset-Bedingungen (Pkt 3) ---
// --- START: Externer Timer Manuell & Ablauf-Erkennung (Pkt 4) ---
// Monoflop für Manuell-Betrieb (retriggerbar)
["Monoflop", "$calc_isTasterBetaetigt", "$calc_isResetManuellTimer", "$calc_isManuellTimerLaeuft", "$in_param_TasterLueftung_Laufzeit", 3],
// Ablauf-Erkennung Manuell-Timer (Ein-Zyklus-Impuls bei fallender Flanke)
["Latch", "$ConstFalse", "$calc_isManuellTimerGeradeAbgelaufen", "$ConstTrue", 0], // Impuls Var: Immer zuerst FALSE setzen
["Latch", "$ConstTrue", "$calc_isManuellTimerGeradeAbgelaufen", "$calc_isManuellTimerLaeuft", 2], // Impuls Var: Nur bei fallender Flanke auf TRUE setzen
// --- END: Externer Timer Manuell & Ablauf-Erkennung (Pkt 4) ---
// --- START: Externer Timer Nachlauf & Ablauf-Erkennung (Pkt 5) ---
// Trigger für Nachlauf-Start (Impuls)
["And", ["$calc_isState1_fuerMaxZeit", "-$calc_isFeuchteAnforderungAktiv"], "$calc_triggerNachlaufStart"], // (War State 1 UND Feuchteanforderung endet jetzt)
// Monoflop für Nachlauf (nicht retriggerbar)
["Monoflop", "$calc_triggerNachlaufStart", "$calc_isResetNachlaufTimer", "$calc_isNachlaufTimerLaeuft", "$in_param_Feuchte_Nachlaufzeit", 2],
// Ablauf-Erkennung Nachlauf-Timer (Ein-Zyklus-Impuls bei fallender Flanke)
["Latch", "$ConstFalse", "$calc_isNachlaufTimerGeradeAbgelaufen", "$ConstTrue", 0], // Impuls Var: Immer zuerst FALSE setzen
["Latch", "$ConstTrue", "$calc_isNachlaufTimerGeradeAbgelaufen", "$calc_isNachlaufTimerLaeuft", 2], // Impuls Var: Nur bei fallender Flanke auf TRUE setzen
// --- END: Externer Timer Nachlauf & Ablauf-Erkennung (Pkt 5) ---
// --- START: Bedingungen für SM nach Timer-Ende (Pkt 6) ---
// Kombinierte Bedingungen für Übergänge nach Ablauf Manuell-Timer (nutzen Ablauf-Impuls)
["And", ["$calc_isManuellTimerGeradeAbgelaufen", "$calc_isFeuchteAnforderungAktiv"], "$calc_isManuellTimerEndeUndFeuchteHoch"],
["And", ["$calc_isManuellTimerGeradeAbgelaufen", "-$calc_isFeuchteAnforderungAktiv"], "$calc_isManuellTimerEndeUndTrocken"],
// --- END: Bedingungen für SM nach Timer-Ende (Pkt 6) ---
// --- START: Statemachine (Pkt 7) ---
["Statemachine",
[
// --- Priorität 1: SPERRE (Ziel: State 4=GESPERRT) ---
["$calc_isSperreAktiv", 0, 4, 0], // AUS -> GESPERRT (wenn Sperre aktiv)
["$calc_isSperreAktiv", 1, 4, 0], // FEUCHTE -> GESPERRT (wenn Sperre aktiv)
["$calc_isSperreAktiv", 2, 4, 0], // NACHLAUF -> GESPERRT (wenn Sperre aktiv)
["$calc_isSperreAktiv", 3, 4, 0], // MANUELL -> GESPERRT (wenn Sperre aktiv)
["$calc_isSperreAktiv", 5, 4, 0], // MAX_ZEIT -> GESPERRT (wenn Sperre aktiv)
["$calc_isSperreAktiv", 99, 4, 0], // FEHLER -> GESPERRT (wenn Sperre aktiv)
["-$calc_isSperreAktiv", 4, 0, 0], // GESPERRT -> AUS (wenn Sperre nicht aktiv)
// --- Priorität 2: MAX_ZEIT (Ziel: State 5=MAX_ZEIT) ---
["$calc_isMaxZeitTimerAbgelaufen", 1, 5, 0], // FEUCHTE -> MAX_ZEIT (bei MaxZeit Timer Ablauf - Impuls!)
["$calc_isMaxZeitTimerAbgelaufen", 2, 5, 0], // NACHLAUF -> MAX_ZEIT (bei MaxZeit Timer Ablauf - Impuls!)
["$calc_isMaxZeitTimerAbgelaufen", 3, 5, 0], // MANUELL -> MAX_ZEIT (bei MaxZeit Timer Ablauf - Impuls!)
// Verlassen von MAX_ZEIT (wenn keine Sperre aktiv)
["$calc_isTasterBetaetigt", 5, 3, 0], // MAX_ZEIT -> MANUELL (bei Taster - Übersteuerung - Impuls!)
["-$calc_isFeuchteAnforderungAktiv", 5, 0, 0], // MAX_ZEIT -> AUS (wenn Feuchteanforderung endet)
// --- Priorität 3: MANUELLER BETRIEB (Ziel: State 3=MANUELL) ---
["$calc_isTasterBetaetigt", 0, 3, 0], // AUS -> MANUELL (bei Taster - Impuls!)
["$calc_isTasterBetaetigt", 1, 3, 0], // FEUCHTE -> MANUELL (bei Taster - Impuls!)
["$calc_isTasterBetaetigt", 2, 3, 0], // NACHLAUF -> MANUELL (bei Taster - Impuls!)
// Ende von MANUELL (wenn keine Sperre/MaxZeit aktiv)
["$calc_isManuellTimerEndeUndFeuchteHoch", 3, 1, 0], // MANUELL -> FEUCHTE (nach Timer-Ablauf + Feuchte hoch - Impuls!)
["$calc_isManuellTimerEndeUndTrocken", 3, 0, 0], // MANUELL -> AUS (nach Timer-Ablauf + trocken - Impuls!)
// --- Priorität 4: AUTOMATIK (FEUCHTE State 1, NACHLAUF State 2) ---
["$calc_isFeuchteAnforderungAktiv", 0, 1, 0], // AUS -> FEUCHTE (wenn Feuchteanforderung aktiv)
["-$calc_isFeuchteAnforderungAktiv", 1, 2, 0], // FEUCHTE -> NACHLAUF (wenn Feuchteanforderung endet -> startet Nachlauf)
// Während NACHLAUF (wenn keine Sperre/MaxZeit/Taster aktiv)
["$calc_isFeuchteUeberAusschalt", 2, 1, 0], // NACHLAUF -> FEUCHTE (wenn Feuchte wieder steigt -> resettet Nachlauf)
["$calc_isNachlaufTimerGeradeAbgelaufen", 2, 0, 0], // NACHLAUF -> AUS (nach Timer-Ablauf - Impuls!)
// --- Catch-All für unbehandelte Fälle -> FEHLER (State 99) ---
["$ConstTrue", 0, 99, 0], // AUS -> FEHLER (Unerwartet!)
["$ConstTrue", 1, 99, 0], // FEUCHTE -> FEHLER (Unerwartet!)
["$ConstTrue", 2, 99, 0], // NACHLAUF -> FEHLER (Unerwartet!)
["$ConstTrue", 3, 99, 0], // MANUELL -> FEHLER (Unerwartet!)
["$ConstTrue", 5, 99, 0], // MAX_ZEIT -> FEHLER (Unerwartet!)
// Zustand 4 (GESPERRT) braucht keinen Catch-All, da -$calc_isSperreAktiv der einzige Weg hinaus ist.
// --- Verhalten im FEHLER Zustand (State 99) ---
// ["$calc_isSperreAktiv", 99, 4, 0] ist bereits oben bei Priorität 1 abgedeckt.
["$ConstTrue", 99, 0, 0] // FEHLER -> AUS (Default-Rückfall, wenn nicht gesperrt)
],
"$calc_State" // Variable, die den Zustand speichert und aktualisiert
],
// --- END: Statemachine (Pkt 7) ---
// --- START: Ausgangsvariablen ableiten (Pkt 8) ---
// Finalen Lüfterzustand ableiten
["Multiplexer",
[ // Index: 0 1 2 3 4 5 6...98 99
"$ConstFalse", "$ConstTrue", "$ConstTrue", "$ConstTrue", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse", "$ConstFalse"
],
"$out_LuefterEA_logic_result", // Zielvariable
"$calc_State" // Selektor
],
// Fehlertext/Status ableiten
["Multiplexer",
[ // Index: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
"$Const_StateText_0_AUS", "$Const_StateText_1_FEUCHTE", "$Const_StateText_2_NACHLAUF", "$Const_StateText_3_MANUELL", "$Const_StateText_4_GESPERRT", "$Const_StateText_5_MAX_ZEIT", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_OK", "$Const_StateText_99_FEHLER"
],
"$calc_FehlerText", // Zielvariable
"$calc_State" // Selektor
],
// Wert für BusReset-Ausgang kopieren (erforderlich, da Variable nur einem Output zugewiesen werden darf)
["Latch", "$out_LuefterEA_logic_result", "$out_LuefterEA_for_BusReset", "$ConstTrue", 0],
// --- END: Ausgangsvariablen ableiten (Pkt 8) ---
// --- START: BusReset Logik (Pkt 9) ---
// Erkennung Bus-Reset (wenn Eingang die Logik triggert)
["Triggered", "$in_BusReset", "$calc_isBusResetCurrentTrigger"],
// Explizites Senden des kopierten Lüfterstatus bei Bus-Reset
["SendExplicit", "$calc_isBusResetCurrentTrigger", "$out_LuefterEA_for_BusReset", 0] // Option 0 = Sende bei TRUE
// --- END: BusReset Logik (Pkt 9) ---
],
"Input": [
["Feuchte", "Aktuelle Feuchte vom Sensor (%)", "$in_Feuchte", "c"],
["Taster Manuell", "Manueller Taster zum Ein-/Ausschalten (steigende Flanke)", "$in_Taster_manuellesLueften", "c"],
["Bus Reset", "Signal zum erneuten Senden des Lüfterstatus (z.B. bei Busspannungswiederkehr)", "$in_BusReset", "a"],
["Sperre", "Übergeordnete Sperre für den Lüfter (true = gesperrt)", "$in_LuefterSperre", "c"],
["P: EinschaltOffset", "Offset zur geglätteten Feuchte zum Einschalten (%)", "$in_param_Feuchte_EinschaltOffset", "u"],
["P: AusschaltOffset", "Offset zur geglätteten Feuchte zum Ausschalten (%)", "$in_param_Feuchte_AusschaltOffset", "u"],
["P: Nachlaufzeit", "Nachlaufzeit in Sekunden", "$in_param_Feuchte_Nachlaufzeit", "u"],
["P: Manuelle Laufzeit", "Laufzeit bei Tasterbetätigung in Sekunden", "$in_param_TasterLueftung_Laufzeit", "u"],
["P: Max Laufzeit", "Maximale ununterbrochene Laufzeit in Sekunden", "$in_param_Luefter_max_Laufzeit", "u"],
["P: Glättungsdauer", "Zeitkonstante für Feuchte-Glättung in Sekunden (Lowpass)", "$in_param_Feuchte_GlaettungDauer", "u"]
],
"Output": [
["Luefter EA (Logik)", "Lüfter Ein-/Ausschaltbefehl (bei Änderung oder Timer)", "$out_LuefterEA_logic_result", "ct"],
["Luefter EA (BusReset)", "Lüfter Ein-/Ausschaltbefehl (nur bei Bus-Reset explizit senden)", "$out_LuefterEA_for_BusReset?", "x"],
["dbg State", "Aktueller Zustand der Statemachine (0=AUS,1=FEUCHTE,2=NACHLAUF,3=MAN,4=SPERRE,5=MAX,99=ERR)", "$calc_State?", "c"],
["dbg Fehlertext", "Textuelle Beschreibung des Zustands/Fehlers", "$calc_FehlerText?", "c"],
["dbg Feuchte geglättet", "Geglättete Feuchte (absolut in %)", "$calc_Feuchte_geglaettet?", "c"]
]
}
Timberwolf 3500L ID:1642; Support-VPN für ElabNET ist an.
-
- Reactions:
- Beiträge: 105
- Registriert: Di Dez 24, 2024 1:24 pm
- Hat sich bedankt: 38 Mal
- Danksagung erhalten: 57 Mal
Der Prompt zur Erstellung der Custom Logik ist hier: Nutzung von KI (LLM) für Dokumentation und Custom-Logiken
Timberwolf 3500L ID:1642; Support-VPN für ElabNET ist an.