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

[Erfahrungsbericht] [V4.5 IP3] Schritt für Schritt Umsetzung einer (Dusch)-Lüftersteuerung

Hier bitte Eure Diskussionen und Feature Requests zu neuen Logikmodulen und Funktionen des Logik-Editors

Robert_Mini
Reactions:
Beiträge: 3895
Registriert: So Aug 12, 2018 8:44 am
Hat sich bedankt: 1259 Mal
Danksagung erhalten: 2205 Mal

#31

Beitrag von Robert_Mini »

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
Timberwolf Server 2500 / #117 (VPN offen + reboot nach Rückfrage) / zusätzlich: 3500M/#935, 3500L/#1297

Ersteller
Franky
Reactions:
Beiträge: 105
Registriert: Di Dez 24, 2024 1:24 pm
Hat sich bedankt: 38 Mal
Danksagung erhalten: 57 Mal

#32

Beitrag von Franky »

super, danke für die Info. dann werde ich das mal heute Abend umsetzen
Timberwolf 3500L ID:1642; Support-VPN für ElabNET ist an.

Ersteller
Franky
Reactions:
Beiträge: 105
Registriert: Di Dez 24, 2024 1:24 pm
Hat sich bedankt: 38 Mal
Danksagung erhalten: 57 Mal

#33

Beitrag von Franky »

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?
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.
Es gibt kein switch-case für die Kapselung von Modulbausteien , sondern "nur" auf Variablenebene, durch den Multiplexer-Befehl, richtig?
Claude 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.
Daaaaaanke für :idea: :D

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.

Ersteller
Franky
Reactions:
Beiträge: 105
Registriert: Di Dez 24, 2024 1:24 pm
Hat sich bedankt: 38 Mal
Danksagung erhalten: 57 Mal

#34

Beitrag von Franky »

Hier ein neuer Zwischenstand. Ich muss gestehen, dass mir Antrophic Claude 3.7 (KI) geholfen hat :oops: Hab ihm die Timberwolf Wiki zum Fraß vorgeworfen und er kann Custom-Logiken programmieren, tse, tse, tse

Das vorher angedachte

Code: Alles auswählen

["Monoflop","$Schwellwert_Status","$I_Sperre","$NachlaufTimerStatus","$I_Nachlaufzeit",1],
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:

Code: Alles auswählen

["Monoflop", "-$calc_Feuchte_is_UeberEinschaltOffset", "$calc_Feuchte_is_UeberEinschaltOffset", "$calc_Nachlauf_is_Aktiv", "$in_param_Nachlaufzeit", 4],
Der Code ist syntaktisch ok, getestet habe ich ihn aber noch nicht

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"]
    ]
}
Fehlt noch:
Robert_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 😉.
kommt als nächstes

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.

Ersteller
Franky
Reactions:
Beiträge: 105
Registriert: Di Dez 24, 2024 1:24 pm
Hat sich bedankt: 38 Mal
Danksagung erhalten: 57 Mal

#35

Beitrag von Franky »

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:
  • Erhöhte Feuchtigkeit über einem Schwellwert
  • Nachlaufzeit nach Rückgang der Feuchtigkeit
  • Manuelle Aktivierung per Taster
Sicherheitsmechanismen:
  • Maximale Laufzeitbegrenzung
  • Externe Sperrfunktion
Kommunikationssteuerung:
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
Entscheidungslogik
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
Der Lüfter wird deaktiviert, wenn:
  • Die maximale Laufzeit erreicht ist ODER
  • Die externe Sperre aktiv ist ODER
  • Keine der Aktivierungsbedingungen mehr erfüllt ist
Ausgabesteuerung
  • Normale Ausgabe bei Änderungen oder Timern
  • Explizites Senden des aktuellen Status bei Bus-Reset
Schlüsselkomponenten im Detail
  • 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
Nachlaufsteuerung
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
Manuelle Aktivierung
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
Sicherheitsabschaltung
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
Besondere Merkmale und Stärken des Designs
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
Modularer Aufbau
Die klare Trennung in Funktionsblöcke macht den Code:
  • Leicht verständlich
  • Gut wartbar
  • Einfach erweiterbar für zusätzliche Funktionen
Benutzerfreundlichkeit
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
Abschließende Bemerkungen
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.

fechter65
Reactions:
Beiträge: 240
Registriert: Mo Aug 13, 2018 10:44 am
Hat sich bedankt: 220 Mal
Danksagung erhalten: 171 Mal

#36

Beitrag von fechter65 »

Franky hat geschrieben: So Mär 23, 2025 11:04 pm Hier ein neuer Zwischenstand. Ich muss gestehen, dass mir Antrophic Claude 3.7 (KI) geholfen hat :oops: Hab ihm die Timberwolf Wiki zum Fraß vorgeworfen und er kann Custom-Logiken programmieren, tse, tse, tse
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

Robert_Mini
Reactions:
Beiträge: 3895
Registriert: So Aug 12, 2018 8:44 am
Hat sich bedankt: 1259 Mal
Danksagung erhalten: 2205 Mal

#37

Beitrag von Robert_Mini »

Sehr cool! Damit kann (könnte) man perfekt die Doku zu Custom Logiken machen.

Lg
Robert
Timberwolf Server 2500 / #117 (VPN offen + reboot nach Rückfrage) / zusätzlich: 3500M/#935, 3500L/#1297

Ersteller
Franky
Reactions:
Beiträge: 105
Registriert: Di Dez 24, 2024 1:24 pm
Hat sich bedankt: 38 Mal
Danksagung erhalten: 57 Mal

#38

Beitrag von Franky »

fechter65 hat geschrieben: Di Mär 25, 2025 7:18 am 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, [...]
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.

Ersteller
Franky
Reactions:
Beiträge: 105
Registriert: Di Dez 24, 2024 1:24 pm
Hat sich bedankt: 38 Mal
Danksagung erhalten: 57 Mal

#39

Beitrag von Franky »

Aktueller Stand der custom-Logik (V47) für die Lüftersteuerung (statemachine, work in progress, noch nicht final)

(Hobby, ökonomische Betrachtung irrelevant :lol: )

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.
work in progress, noch nicht final

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"]
  ]
}
"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."
Timberwolf 3500L ID:1642; Support-VPN für ElabNET ist an.

Ersteller
Franky
Reactions:
Beiträge: 105
Registriert: Di Dez 24, 2024 1:24 pm
Hat sich bedankt: 38 Mal
Danksagung erhalten: 57 Mal

#40

Beitrag von Franky »

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.
Antworten

Zurück zu „Feature Requests & Diskussionen Timberwolf Logik (Module & Editor)“