Fibaro LUA Grundlagen

Advertisements

Der Internet of Things (IoT) und Smart-Home-Nachrüstmarkt ist hart umkämpft, so dass fast monatlich neue Lösungen erscheinen und auf den Einsatz in unseren Haushalten warten. Bei den Herstellern ist der Druck des schnellen „Go-To-Market“ und die zu adressierende Zielgruppe offenbar so groß, dass es sich bei den meisten Neuerscheinungen um Insellösungen handelt. Sie ermöglichen die einfache Interaktion mit smarten Geräten und sind meist mit einer eigenen App ausgestattet. Interaktion mit Fremdgeräten sucht man vergeblich. Vereinfacht ausgedrückt geht es bei diesen Lösungen um das Ein- und Ausschalten von Aktoren und ggf. die Visualisierung von Sensorwerten. Nur einige wenige Lösungen bieten die Implementierung von Bedingungen und Abhängigkeiten. Hier scheint Plug-and-Play wichtiger zu sein als vollständige Integration und (nahezu) uneingeschränkte Möglichkeiten.

Lua Grundlagen

Für Otto-Normalverbraucher, der zur Bedienung seiner Heizthermostate oder Philips Hue Lampen das Smartphone nutzen möchte, sind diese Lösungen zielgerichtet und sicher auch „smart“ genug. Ein Smart Home wird aber erst durch die Möglichkeit der vollständigen Integration und Programmierung so richtig „smart“. Das Home Center 2 von Fibaro bietet durch die „freie“ Programmierung von Szenen die idealen Rahmenbedingungen dafür. Basierend auf der Programmiersprache LUA sind den Möglichkeiten fast keine Grenzen gesetzt. Jedoch ist LUA eine Programmiersprache und nicht jeder Besitzer eines Home Center 2 hat bisher etwas mit Programmierung zu tun gehabt. Daher möchte ich In diesem Artikel die Fibaro LUA Grundlagen vermitteln und hoffe damit helfen zu können.

„Wie lerne ich LUA?“

Die alles entscheidende Frage, wenn es um das Home Center 2 von Fibaro geht! Diese und ähnliche Fragen tauchen immer wieder in Foren und Kommentarspalten auf. Die Antworten darauf sind immer etwas zurückhaltend und meist beschränken sie sich auf den guten Hinweis sich fertige Szenen anzusehen, das gelesene zu verstehen und dann einfach ausprobieren.

So kann man sich eine Programmiersprache aneignen und genau das werden die meisten Fibaro User tun bzw. getan haben. Um aber auch komplexere Szenen entwickeln zu können und die Möglichkeiten der Smart Home Lösung auszuschöpfen bedarf es meiner Meinung nach ein bisschen mehr Theorie. Daher dieser Artikel in dem ich – zugegeben – langweilige Theorie, aber eben auch Grundlagen der Programmierung mit einer Skriptsprache vermitteln möchte. Aber keine Sorge, ich versuche die Texte möglichst praxisnah und leichtverständlich zu schreiben.

Eine kleine Anmerkung

Ich möchte hier nicht die siebenundzwanzigste Sammlung von Erklärungen der Fibaro Funktionen in einem Artikel veröffentlichen. Dazu gibt es mehr als genug Informationen im Netz. Auch wird Der Artikel bei Weitem nicht alles abdecken was mit LUA möglich ist, aber es sollte reichen um Dir zu ermöglichen komplexe Dinge mit dem HC2 zu realisieren. Über Anmerkungen, Kritik und Ergänzungen freue ich mich und arbeite diese gern in den Artikel ein.

Das Handwerkszeug

Die ersten Ideen für tolle Szenen kommen den meisten Usern kurz nach dem Kauf des Home Center 2 und so machen sich viele dran den Editor im Webinterface mit allerhand Code zu füllen. Dies ist – für den Start – eine durchaus praktikable Möglichkeit sich mit dem System vertraut zu machen. Das Ergebnis sind aber meist viele kleine und wenig robuste Insellösungen.

Für den Start der Entwicklung einer Szene empfehle ich immer Papier und Bleistift zur Hand zu nehmen. Sich also Notizen machen was die Szene bewirken soll. So ist es leichter den roten Faden während der Programmierung nicht zu verlieren und das Ziel immer vor Augen zu haben.

Ist erstmal ein wenig Erfahrung mit der Programmierung vorhanden kann auf den Einsatz von Papier und Bleistift gut und gerne verzichtet werden. Ich selbst mache es aber noch heute so, dass ich mir erst ein Konzept erstelle und dann mit der Programmierung beginne. So lassen sich Stolperfallen von vornherein umgehen und die Ergebnisse werden einfach deutlich besser. Aber nun zu Lua.

Was ist LUA?

LUA wurde 1993 von der Computer Graphics Technology Group der Päpstlichen Katholischen Universität von Rio de Janeiro entwickelt und ist freie Software.

Lua (portugiesisch für Mond) ist eine imperative und erweiterbare Skriptsprache zum Einbinden in Programme, um diese leichter weiterentwickeln und warten zu können. Eine der besonderen Eigenschaften von Lua ist die geringe Größe des kompilierten Skript-Interpreters.

Bitte was? Für einen Laien stecken allein in der Einleitung zum Wikipedia Artikel zu LUA mindestens fünf neue Fragen ohne auch nur eine einzige beantwortet zu haben.

Für Jemanden der „nur“ Szenen für sein HC2 entwickeln möchte ist es egal, ob die Skript-Interpreter nun groß oder klein und die Sprache leicht erweiterbar ist. Eine im Fibaro Umfeld wichtige Information steckt jedoch in dieser Einleitung. Bei LUA handelt es sich um eine Skriptsprache. In der Programmierung zeichnen sich Skriptsprachen dadurch aus, dass sie von einem Interpreter eingelesen, analysiert, ausgeführt und nicht kompiliert werden. Schon wieder diese Fachbegriffe. Ich versuche es verständlich zu erklären.

Der LUA Interpreter Deines HC2 ist ein ausführbares Programm welches die Szenen im Klartext entgegen nimmt, diese analysiert und ausführt. Die Szene selbst wird nicht erst durch einen Compiler zu einem ausführbaren Programm, sondern wird durch den Interpreter ausgeführt. Er ist die Schnittstelle zwischen Soft- und Hardware. Für kleine Programme – und nichts Anderes sind LUA Szenen – werden oft Skriptsprachen herangezogen um die Aufwände in Programmierung und Kompilierung zu minimieren. Weitere Vorteile von LUA sind die Plattformunabhängigkeit sowie die hohe Geschwindigkeit.

Skriptsprachen zeichnen sich also dadurch aus, dass der Interpreter das ausführt was geschrieben steht. Er führt exakt aus was in den Szenen geschrieben steht. Die erste Zeile Deiner Szene wird als erstes ausgeführt und die letzte zuletzt. Die Chronologie einer Fibaro Szene ist also von „oben nach unten“.

Operatoren

Wie jede Programmiersprache braucht auch LUA Operatoren die festlegen wie bestimmte Operationen im Code zu hinterlegen sind und diese bei der Ausführung interpretiert werden. Für Fibaro Szenen sind die Operatoren für Grundrechenarten und Vergleiche die wichtigsten. Weiterhin gibt es Verknüpfungsoperatoren.

Grundrechenarten

Grundrechenart Operator Beispiel
Addition + a + b = c
Subtraktion a – b = c
Multiplikation * a * b = c
Division / a / b = c
Potenzierung ^ a ^ b = c

Vergleichsoperatoren

Vergleichsart Operator Beispiel
Ist gleich == a == b
Ist ungleich ~= a ~= b
Kleiner als < a < b
Kleiner gleich <= a <= b
Größer > a > b
Größer gleich >= a >= b

Verknüpfungen

Verknüpfung Operator Beispiel
und and a == b and c == d
oder or a == b or c == d

Variablen

Möchtest Du beispielsweise in einer Szene einen Dimmer steuern. So wird dessen ID einmal in eine Variable dimmerID geschrieben und ist somit an jeder beliebigen Stelle der Szene verfügbar. Soll derselbe Quellcode zum Steuern eines anderen Dimmers verwendet werden, so muss lediglich an einer einzigen Stelle die Variable geändert werden.

In der Programmierung spielen Variablen eine wichtige Rolle. In Variablen werden Werte zwischengespeichert um diese an unterschiedlichen Stellen innerhalb des Programmes wieder verwenden zu können, ohne immer wieder denselben Wert fest im Quellcode zu verankern. Dies fördert neben der Übersichtlichkeit auch die Wartbarkeit.

Variablen-Typen

Die Definition und Initialisierung einer Variable erfolgt mit LUA durch Zuweisung eines Wertes. Die Bezeichnung der Variable ist dabei (fast) frei wählbar, darf aber nur einmal vorkommen bzw. wird bei erneuter Zuweisung eines Wertes überschrieben. Ausgenommen bei der Benennung von Variablen sind Schlüsselworte der Programmiersprache selbst (if, then, else, function, etc.).

textVariable = "Dies ist der Inhalt meiner Variable"
numVariable = 1234
boolVariable = true
arrayVariable = {77,30,45}

Die vier dargstellten Variablen decken die unter LUA verfügbaren Typen von Variablen ab. Wobei der Inhalt den Typ der Variable bestimmt.

  • textVariable ist durch Anführungszeichen (doppelte oder einfache) begrenzter Text
  • numVariable ist ein Zahlenwert
  • boolVariable ist eine boolesche Variable (true oder false)
  • arrayVariable ist ein Array. Ein Array kann mehrere Werte gleichen Types beinhalten.

Arrays bzw. Tables

Ein Array bzw. in der LUA Sprache eine Table ist eine Variablen die mehrere Werte unabhängig voneinander speichern kann. Dafür wird innerhalb der Table ein sogenannter Index erstellt welcher den Zugriff auf die Einzelwerte ermöglicht. Ein Array wird durch {}-Klammern definiert.

arrayVariable = {77, 30, 45}

In diesem Array sind also die Werte 77, 30 und 45 gespeichert. Innerhalb der Table wird jeder Wert einer eindeutigen Position zugeordnet, dem sogenannten Index. Index und Wert bilden dabei ein eindeutiges Paar welches der Reihenfolge der Werte in der Definition entspricht. Im Beispiel oben sind diese Pärchen also:

  • Index 1 -> Wert 77
  • Index 2 -> Wert 30
  • Index 3 -> Wert 45

Die Ausgabe einer Table im Debug ist nicht ohne weiteres möglich. Der Versuch der Debug-Ausgabe wird mit dem Hinweis quittiert, dass es sich um eine Table handelt.

fibaro:debug(arrayVariable)

Ausgabe:
[DEBUG] 12:28:41: table: 0x93d83a0

Um einzelne Werte der Table auszugeben und zu verwenden muss zusätzlich zum Namen der Variable der Index des gewünschten Wartes mit angegeben werden.

fibaro:debug(arrayVariable[1]) --> 77
fibaro:debug(arrayVariable[2]) --> 30
fibaro:debug(arrayVariable[3]) --> 45

Gesamte Table ausgeben

Während der Entwicklung von Szenen in denen Tables verwendet werden ist es oftmals notwendig den Inhalt dieser zu kontrollieren. Den gesamten Inhalt im Debug-Fenster auszugeben ist mit dem folgenden Code möglich:

for k, v in pairs( tableName ) do
   print(k, v)
end

Lokale und globale Variablen

Innerhalb von Fibaro Szenen gibt es zwei unterschiedliche Arten von Variablen. Lokale und globale Variablen. Wobei der Begriff „Globale Variable“ im Home Center 2 doppelt belegt ist. Die hier gemeinten globalen Variablen beziehen sich ausschließlich auf Variablen die innerhalb einer Szene gefüllt – und damit definiert – und verwendet werden. Zu den im Webinterface erstellbaren „Globalen Variablen“ komme ich später.

Eine in einer Szene definierte Variable – beispielsweise die oben erstellte Variable numVariable – ist grundsätzlich global. Wobei global hier bedeutet, dass sie innerhalb der Szene an jeder Stelle verfügbar ist. Eine lokale Variable hingegen ist nur innerhalb ihres Blocks bzw. ihrer Funktion verfügbar und wird mit local gekennzeichnet.

Beispiel globale und lokale Variable:

-- globale Variable initialisieren und befüllen
textVariable = "Beispieltext"

-- lokale Variable initialisieren und befüllen
local textVariable = "Beispieltext"

Um den Unterschied deutlich zu machen ein kleines Beispiel. Ich definiere die Variable textVariable mit dem Wert „Hallo Welt!“ und gebe diese aus (–> stellt die Ausgabe dar)

textVariable = "Hallo Welt!"
print(textVariable)
--> Hallo Welt!

Nun erstelle ich eine Funktion in der ich einer lokalen Variable mit demselben Namen einen den Wert „Servus Welt!“ zuordne.

textVariable = "Hallo Welt!"
do
 local textVariable = "Servus Welt!"
end
print(textVariable)
--> Hallo Welt!

Obwohl innerhalb der do-Funktion der Variable textVariable ein anderen Wert zugewiesen wurde, wird dieser nicht global gespeichert, sondern hat nur innerhalb der Funktion mit dem Wert „Servus Welt!“. gibt man die Variable dort zusätzlich aus wird der Wert der lokalen – nur innerhalb der Funktion gültigen – Variable ausgegeben.

textVariable = "Hallo Welt!"
do
 local textVariable = "Servus Welt!"
 print(textVariable)
 --> Servus Welt!
end
print(textVariable)
--> Hallo Welt!

Einmal lokal, immer lokal

Der Zustand lokal und global einer Variablen bleibt erhalten. Ist eine Variable in einer Szene einmal als lokal definiert, so ändert auch eine spätere Wertzuweisung ohne den local Zusatz nichts daran.

local textVariable = "Hallo Welt!"

textVariable = "Servus Welt!"

Merke: Jede einmal als lokal definierte Variable bleibt eine lokale Variable! Bei der Erstellung von Fibaro Szenen ist es im Normalfall nicht notwendig lokale Variablen zu erstellen. Gerade am Anfang ist es sinnvoll ausschließlich globale Variablen zu definieren um die Verwendung der gespeicherten Werte nicht unnötig kompliziert zu machen.

 

Bildquellen

  • Lua Grundlagen: pixabay.com - CC0
Posted in Basics and tagged .

11 Comments

  1. Hallo Bastian, bin gerade im Urlaub und hab mir es gestern alles durchgelesen. Echt super geschrieben. Ich glaub das wird mir und Anderen helfen.

  2. Hallo Bastian,

    ein starker Artikel, aus dem ich direkt ein paar Zeilen Code entwenden kann:-)
    Jetzt habe ich das auch endlich mit dem fibaro:sleep verstanden.

    Danke für die Arbeit. Das hat bestimmt eine Weile gedauert.

    VG
    Mr.Coffee

  3. Hallo Bastian,
    vielen Dank für Deine Fleißarbeit! Ich habe sie zum Anlass genommen, einen zweiseitigen, kompakten Überblick zur LUA-Syntax und verschiedenen Fibaro-Befehlen zu erstellen:
    https://www.subreality.de/blog/wp-content/uploads/2017/02/lua_syntax_fibaro_befehle.pdf
    Das kann noch Flüchtigkeitsfehler enthalten und es ist sicherlich auch noch nicht „vollständig“, denn ich bin noch dabei, mich schrittweise einzuarbeiten. Aber zumindest mit leistet dieses Dokument, laminiert auf der Tischplatte, bisher gute Dienste. Ich werde es ggf. nach und nach erweitern.
    Beste Grüße, Rüdiger

    • Hallo Rüdiger,

      vielen Dank für die netten Worte und Deine Mühe mit dem PDF! Den Link veröffentliche ich natürlich gern und bin mir sicher, dass er dem Ein oder Anderen User helfen wird.

      Gruß
      Bastian

  4. Hallo Bastian,
    ich kann mich auch nur Bedanken. Ich fange gerade an, mich mit Lua zu beschäftigen. Es ist toll, wenn man sich einmal komplett an einem Beispiel orientieren kann. Mir hat es sehr geholfen die krptischen Zeichen zu verstehen.
    An deiner Seite sollten sich mehr Foren orientieren. In den meisten Foren bekommt man immer nur Schnipsel und muss dann wieder nachfragen.

    großes DANKE an dich
    Gruß Manfred

    • Hi Modell75,

      schau Dir mal das Kapitel „Variablen-Typen“ an. Mit der Funktion tonumber() kannst Du den Typ einer Variable von String zu Number ändern. Dies ist insbesondere wichtig, wenn Du mit Variablen Rechnen oder Vergleichen möchtest. Das geht nämlich mit Texten nicht 😉

      Gruß
      Bastian

  5. Hallo Bastian
    ich bin auch neu in der LUA Programmierung, da wir gerade einen Neubau planen.
    Dank deinen super Beiträgen habe ich einen wesentlich leichteren Einstieg ins Thema und gute Beispiele zum nachlesen und üben.
    Danke vielmals für deinen Aufwand!

    Liebe Grüsse
    Clemens

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Ich akzeptiere