OpenKNX-Modul zur Definition zustandsbehaftetem Verhalten auf Basis von Deterministischen Endlichen Automaten (DEA)
Implementierung von Zustandsmodellen für KNX, konfigurierbar über die ETS.
Von Cornelius Köpp 2023-09 -- 2025
Hinweis: Die OpenKNX StateEngine dient als Referenz-Applikation für dieses Modul und bietet eine besonders hohe Anzahl von unabhängigen Automaten-Definitionen/Kanäle. Eine geringere Anzahl von Automaten ist u.A. auch im OpenKNX RaumController integriert.
Dieses Modul erlaubt eine universelle Modellierung von zustandsabhängigem Verhalten:
Jeder Kanal repräsentiert eine Automaten-Definition mit 16 verschiedenen Zuständen.
Zwischen den Zuständen kann durch 8 verschiedenen Eingabeereignisse oder Ablauf eines zustandsabhängigen Timeouts gewechselt werden.
Über 4 Ausgangskanäle können zustandsspezifische Werte mit zustandsspezifischem Sendeverhalten ausgegeben werden,
in verschiedenen gängigen DPTs.
Zusätzlich erfolgt eine Ausgabe des aktuellen Zustands.
Optional kann auch ein Direktaufruf des Zustands erlaubt werden,
eine Unterbrechung der Ausführung,
sowie Rekonstruktion des letzten Zustands und Status nach einem Neustart.
Die Definition in der ETS erfolgt über eine (zwei-dimensionale) Zustandsübergangstabelle.
Zur Konfiguration in der ETS siehe Applikationsbeschreibung
- Einsatz
- Beispiele
- Grundidee in Anlehnung an gängige formale Definitionen
- Für Entwickler: Integration in OpenKNX OAMs
Das Modul kann eingesetzt werden, um zustandsabhängiges Verhalten zu definieren, das abhängig ist von der Reihenfolge, oder sogar genauer definierten zeitlichen Abfolge, von Ereignissen. Die Verarbeitung erfolgt Ereignis-orientiert, bei Eingang von Telegrammen vom Bus, Aktualisierung von Logik-Ausgängen in der Vorverarbeitung (oder anderer KOs), oder nach Ablauf eines zustandsabhängigen Timeouts.
Verhalten das nur von aktuellen Werten (z.B. logische Verknüpfung von mehreren Eingängen) oder der Uhrzeit abhängt, oder Umwandlung und Berechnung von Werten, kann mit dem OpenKNX Logikmodul beschrieben werden. Dies ist in vielen Fällen nützlich oder notwendig zur Vorbereitung von Eingangswerten dieses Moduls, daher können Ausgänge von Logikkanälen direkt als Eingänge gewählt werden.
Für Standardprobleme sollten spezialisierte Module wie z.B. OpenKNX PresenceModule genutzt werden; dieses bieten eine auf den jeden Anwendungsfall optimierte Konfiguration.
- Warum ist die Auswahl und Definition des Startzustands so wichtig?
- Warum ist es problematisch, wenn man Ausgabewerte für einzelne Zustände einfach weglässt?
- Kann ich die Eingabe der vielen Parameter irgendwie beschleunigen?
- Was kann ich tun, wenn die 4 Ausgänge nicht ausreichen?
- Einführungsbeispiel für KNX-Nutzer:
Virtueller Schaltaktor mit Sperre und Treppenhaus-Funktion - Beispiel zur Vorverarbeitung durch Logik-Kanäle:
Umwandlung von DPT2 (Zwangsführung) in Eingabesymbole
Informatikern wird das Modell bekannt und vertraut vorkommen; bei genauerem Hinsehen werden allerdings gewisse Abweichungen deutlich um das Konzept an den Praxisbedarf anzupassen.
... wird als Teilmenge von DPT17.001 (Szenen: {0=Szene1,..,63=Szene64}) dargestellt. In der aktuellen Implementierung eingeschränkt auf die Zustände 1 bis 16. Bei Erreichen eines Zustandes können, durch die Ausgabe der korrespondierenden Szene, unmittelbar mehrere unabhängige Aktionen gleichzeitig ausgelöst werden. Ergänzend können mehrere individuelle Ausgangswerte je Zustand definiert werden.
... wird beim Einschalten als erster Zustand angenommen, sofern nicht ein zuvor gewählter Zustand rekonstruiert wird.
... umfasst Symbole deren Eingabe (bzw. das damit verbundene Ereignis) eine Zustandsänderung bewirken kann. Abhängig von der Konfiguration setzt sich das Eingabealphabet aus den folgenden Symbol-Mengen zusammen:
-
Die Symbole A bis H werden durch bis zu 8 unabhängige DPT1 Eingabekanälen erzeugt; bei Eingang von 1 und/oder 0. Durch optionale Konfiguration als Eingabesymbolpaar kann z.B. ohne weiter Vorverarbeitung auf das Auftreten oder den Wegfall von erkannter Präsenz reagiert werden.
-
Das Symbol T wird erzeugt, wenn innerhalb eines zustands-spezifisch konfigurierten Zeitintervalls keine Eingabe erfolgt (bzw. kein anderes Ereignis eingetreten) ist.
-
Abhängig von der Konfiguration kann durch Eingabe in einen DPT17.001 Zustandseingang ein entsprechendes Symbol erzeugt werden.
Das Eingabealphabet kann die Form X=Xe∪Xt oder X=Xe∪Xt∪Xz aufweisen.
... beschreibt für jede Kombination aus Ausgangszustand und Eingabesymbol, ob und wenn ja in welchen Folgezustand bei Eingabe gewechselt wird. Nicht angegebene Zustandsübergabe werden ignoriert und führen nicht in einen Fehlerzustand.
Falls Xz⊂X (Direktes Setzen von Zuständen ist erlaubt), so gilt d(z,zi)=zi für alle zi∈Xz\{z} (ignorieren von erneutem Aufruf des bereits gesetzten Zustands), oder sogar für alle zi∈Xz (Neustart von bereits gesetztem Zustand).
... werden nicht explizit abgebildet. Im Rahmen einer Nachverarbeitung kann jedoch leicht ermittelt werden, ob ein Zustand aus dieser Menge eingenommen wurde. Es können Zustände definiert werden, die nicht mehr durch Eingabe eines Symbols verlassen werden.
Wichtig: Die Anzahl der Kanäle muss vor einer Integration kritisch abgewogen werden, da die je Kanal enthaltenen Anzahl von Parametern und der erforderliche Parameterspeicher deutlich größer sind als bei anderen OpenKNX-Modulen. Eine zu hohe Anzahl von Kanälen kann sich negativ auf die Performance in der gesamten erzeugten ETS-Applikation auswirken. Mit einem Bedarf von knapp 1 KB Parameterspeicher je Kanal wird u.U. eine Anpassung des Speicherlayouts erforderlich.
Dieses Modul besteht aus einem Applikationsteil und einem Firmware-Modul. Diese müssen beide innerhalb eines OpenKNX-Applikations-Projektes eingebunden werden, wie unten gezeigt.
Das Modul erfordert die gleichzeitige Integration des OpenKNX Logikmoduls. Da dieses i.d.R. in allen OpenKNX-Applikationen enthalten ist, stellt dies in der Praxis keine besondere Anforderung dar.
Das Modul stellt folgende KOs bereit:
- 30 für jeden Kanal (Automatendefinition)
- keine kanalunabhängigen KOs
Achtung:
ModulTypemuss auf einen Wert im Bereich 2 bis 9 gesetzt werden, da ein vergrößerter Namespace für Parameter verwendet wird. Ein solcher einstelliger ModulTypementspricht einer gleichzeitigen Belegung des vollständigen Bereichs von ModuleType10*mbis ModuleType10*m+9, d.h. es darf kein anderes Modul mit einem ModulType in diesem Bereich in der Applikation eingebunden werden.Beispiel: Der nachfolgend gezeigte ModulType
2verbietet andere Module mit meinem ModulType von20bis29.
An der gewünschten Stelle in der jeweiligen {ApplikationName}.xml den folgenden Code einbinden:
<!-- Number of visible channels before configuration, can be defined in separate config file: -->
<op:config name="%DFA_NumChannelsDefault%" value="2" />
<!-- 30 KOs / Channel, NO central KOs -->
<!-- IMPORTANT: ModuleType must be set to 1-digit value from 2 to 9, without conflict to 2-digit values starting with the same digit; see documentation! -->
<op:define prefix="DFA"
share="../lib/OFM-DFA/src/DfaModule.share.xml"
template="../lib/OFM-DFA/src/DfaModule.templ.xml"
NumChannels="%DFA_NumChannels%"
KoOffset="30"
ModuleType="2" >
<op:verify File="../lib/OFM-DFA/library.json" ModuleVersion="%DFA_VerifyVersion%" />
</op:define>
// ...
#include "Logic.h"
#include "DfaModule.h"
// ...
void setup()
{
// ...
openknx.addModule(1, openknxLogic);
openknx.addModule(2, openknxDfaModule);
// ...
}
// ...