heute möchte ich einen Einblick in die Logikverarbeitung meines IoT-Systems geben. Grund dafür ist, dass ich gestern einige Änderungen durchgeführt habe, auf welche ich weiter unten eingehen werde.
Wie ich bereits in einem vorherigen Post beschrieben habe, besteht die Logikverarbeitung aus Logikvorlagen "Pattern" und Logikinstanzen "Instances". Die eigentliche Logik ist innerhalb der Vorlage beschrieben. Eine Vorlage besitzt drei prinzipielle Komponenten: Eingänge, Ausgänge und Logikelemente. Die Logikelemente wiederum besitzen abhängig vom Typ des Elements wieder Ein- und Ausgänge.
Der Screenshot aus meiner Editor-Software zeigt eine Logikvorlage für einen einfachen Lichtschalter. Links sind die Ausgänge, rechts die Ausgänge und dazwischen die Logikelemente angeordnet. Wie zu erkennen ist, haben sämtliche Ein- und Ausgänge eine Farbe. Diese gibt deren Typ an. Grün stellt beispielsweise den Typ "Boolean" dar. Wird in den Eingang einer Logikstruktur ein Wert gegeben, so werden alle daran angekoppelte Elemente neu berechnet. Ändert sich dadurch ihr Ausgang, so werden daran angekoppelte Elemente ebenfalls neu berechnet. Dies wird fortgeführt, bis keine Änderungen mehr auftreten. Kommt es dazu, dass einer der Ausgänge auf der rechten Seite erreicht wird, so wird dessen Wert ebenfalls aktualisiert.
Nun stellt sich die Frage, was an die Ein- und Ausgänge der Struktur gekoppelt werden kann. Dafür sind die Logikinstanzen verantwortlich. Die Instanz erstellt eine Kopie der Struktur und verbindet deren Ein- und Ausgänge jeweils mit hinterlegten Ein- und Ausgängen von realen Geräten.
Das Bild zeigt die Instanzverwaltung einer Instanz, welche die oben gezeigte Vorlage verwendet. Im unteren Bereich ist es möglich, die Verbindungen von Ein- und Ausgängen festzulegen.
Nun bestehen Logikvorlagen nicht nur aus einem Logikelement, sondern aus vielen. Folgende Struktur verwende ich beispielsweise für eine RGB-LED-Leise unter meinem Bett, welche den Boden beleuchtet. Nachts soll sie bei Bewegung weiß leuchten und ansonsten optional ein Farbspiel durchführen. (Zum Vergrößern anklicken)
Ich habe die Struktur zur Erklärung in Bereiche mit Nummern unterteilt. Die Bereiche haben folgende Funktionen:
- Die Bewegungserkennung. Wird eine Bewegung erkannt, so wird der Ausgang eingeschalten. Ist die Bewegung beendet, so wird der Ausgang nach 15 Sekunden wieder abgeschalten.
- Dieser Bereich stellt fest, ob es aktuell zwischen 18 Uhr Abends und 7 Uhr Morgens ist. Dadurch wird die Bodenbeleuchtung bei Bewegung lediglich Nachts eingeschalten.
- Diese beiden Elemente stellen fest, ob das Farbspiel stattfinden soll. Praktisch könnte man die beiden Elemente weglassen und den Eingang direkt mit Bereich 5 verbinden. Ich habe sie denoch eingesetzt, da ich so weitere Bedingungen einfügen kann.
- Dieser große Bereich erzeugt alle 15 Sekunden eine zufällige Farbe. Die Multiplikationen am Ende sind notwendig, da das"HSV to RGB"-Element Werte von Null bis Eins erzeugt, die Ausgänge aber einen Wertebereich von Null bis 255 besitzen.
- Hier wird ermittelt, welcher Modus aktuell stattfinden soll. Als Modi stehen Aus, Farbwechsel und Ein zur Verfügung.
- Dieses Element legt fest, welche Farbe angezeigt werden soll, wenn weder Farbspiel noch Nachtbeleuchtung aktiv sind.
- Diese beiden Konstanten legen die Farbwechselzeiten fest. Das Nachtlicht soll innerhalb einer halben Sekunde (500ms) an und aus gehen. Das Lichtspiel dagegen darf fünf Sekunden (5000ms) beanspruchen.
- Hier wird die Farbe der Nachtbeleuchtung festgelegt. Die Werte habe ich über die Zeit immer wieder angepasst, um ein Licht zu erzeugen, welches im Dunkeln ausreichend hell ist, aber auch nicht blendet.
- In diesem Bereich wird mit Hilfe der Bedingungen aus Bereich fünf die Lichtwerte ausgewählt.
- Im letzten Bereich werden alle Lichtwerte (Rot, Grün, Blau, Wechselzeit) zu einem Bytearray zusammengeführt. Dies ist notwendig, da das verbundene Gerät somit alle Werte gleichzeitig erhält.
Die Änderung sieht nun vor, dass Ein- und Ausgänge von Elementen variabel funktionieren. Sie passen sich daher an den jeweils angeschlossenen Typ an. Dabei ist natürlich definiert, welche Datentypen angeschlossen werden können, beispielsweise kann eine Addition nicht mit boole'schen Daten umgehen.
Die Vorteile dieser Änderung liegen auf der Hand: Es werden weniger eigenständige Elemente benötigt, was die Auswahlpalette drastisch reduziert. Außerdem muss jedes Element einzeln programmiert werden. Soll ein Element mit jedem Datentyp umgehen können, so waren bisher sieben Elemente notwendig, welche alle programmiert werden mussten. Nun ist nurnoch die Programmierung eines Elementes notwendig, welche aber dafür ein wenig komplexer ist. Trotzdem ist der Gesamtaufwand wesentlich geringer als sieben einzelne Elemente zu programmieren.
Damit verabschiede ich mich für diesen Eintrag und wünsche ein schönes restliches Wochenende!
Keine Kommentare:
Kommentar veröffentlichen