Girder: Smart Home mit dem "item Manager"

11.07.2016

Girder besitzt bereits ein offenes plugin-Konzept zur Erweiterung des Funktionsumfangs. Außerdem gibt es seit girder version 5 einen sogenannten Device Manager. Damit kann man speziell Gerätearten hinzufügen und damit leichter in Ereignisse und Aktionen einbinden. Trotzdem habe ich mich entschieden, ein eigenes Erweiterungskonzept auf girder aufzusetzen, weil ich spezielle Anfoderungen hatte die die bisherigen Verfahren nicht erfüllen. Ich nenne es den item-Manager iM.

Die Problemstellung

Die vorhandenen Verfahren für die Einbindung von smarten Geräten haben nach meiner Bewertung folgende Schwächen:

  1. Die Übersetzung der Geräte im Device Manager ist Geräte-zentrisch. Das bedeutet dass Geräte mit mehreren Funktionen immer als eine geschlossene Einheit abgebildet werden und nicht als eine Anzahl von Teilfunktionen. Ein Vierfach-Relais wird also immer behandelt als ein gerät mit vier Funktionen obwohl diese vier Funktionen unter Umständen nichts miteinander zu tun haben.
  2. Im Device Manager werden Geräte von verschiedenen Herstellern auch unterschiedlich behandelt. Auch wenn diese Geräte die gleiche Funktion übernehmen wie z.B. ein Zwischenstecker von Firma A und ein zweiter von Firma B. Eigentlich sollte dem Ersteller einer Automatisierungsregel egal sein von welchem Hersteller das Gerät ist aber bei girder muss man das immer als Information beachten um das Gerät eindeutig ansprechen zu können.
    Diese beiden Schwachpunkte wil ich in meinem eigenen item-Manager überwinden.

    Der iM item Manager

    Der item Manager ist eine LUA Bibliothek für girder 6 und bietet ein generisches Management der Funktionen von smarten Geräten und Services. Das ist eine Alternative Lösung zum Device Manager von girder. der item Manager besteht aus standardisierten LUA Funktionen um gleichartig auf die Teilfunktionen von geräten verschiedener Hersteller zuzugreifen. Wer den item Manager benutzt, muss sich nicht mehr darum kümmern, von welchen Hersteller ein Gerät oder ein Dienst kommt. Geräte, die mehrere Funktionen haben, werden im item Manager zu sogenannten items übersetzt. Jedes Item ist genau einer Funktion eines Gerätes zugeordnet. Der item Manager ist somit vollständig item-orientiert und kennt keine Geräte.

    Begriffe

    • item Manager iM: LUA Bibliothek mit den kern Funktionen
    • Gerät: Beschreibt die physikalische Sicht, also die Gruppe aller Funktionen uns somit eine Gruppe von Items.
    • Item: Das ist im Item Manager nur noch ein LUA Objekt welches eine Funktion eines Gerätes beschreibt. Das Objekt beinhaltet alle zugeordneten Methoden und Daten
    • Modul: Das ist die LUA Bibliothek über die eine Geräteart in den item Manager integriert wird. enthalten sind die Übersetzung der Geräte-spezifischen proprietären API auf die generischen item Manager Funktionen.
    • Modul Objekt: LUA Objekt, welches die Daten und Methoden für eine Instanz eines Modules enthält. Es können je Modul unter Umständen mehrere Instanzen angelegt werden die dann zum Beispiel mehrere Dienstekonten oder mehrere likale Gateways repräsentieren.

Datei-Struktur und Integration in die girder Installation

Der item Manager ist eine Gruppe von girder Modulen im LUA-Sinne. das bedeutet sie werden in der Girder Installation im Verzeichnis /LUA/in einem eigenen Unterordner "iM/" abgelegt.

  • init.lua: Beinhaltet die kernfunktionen des item Managers
  • kit.lua: Beinhaltet übergreifende Hilfsfunktionen um item Manager Module zu unterstützen. Das sind Funktionen wie XML-Parser, md5-Generator, JSON Encoder/Decoder usw.
  • iM_xx.lua: Beinhaltet den Code für ein item Manager Modul
    Diese Bibliotheken werden beim Start von girder katalogisiert und durch das folgende LUA Kommando aktiviert/gestartet:
    require("iM")
    require("iM_xx")

Items

Kernelement den item Managers sind die Item-Objekte. Sie sind Herstellerunabhängig und beschreiben ein item völlig generisch über seine einzige Funktion. Das sind im wesentlichen Parameter und Methoden.

Parameter

  • smid: source module id aus dem iM Modul (eindeutig pro Modul)
  • smoid: source module object id aus dem iM Modul (eindeutig pro Modul Objekt)
  • smiid: source module item id comming aus dem Modul Objekt (eindeutig pro Item in einem Modul Objekt)
  • itemid: item id des Item Objekts (Format iM_xxxxx); (eindeutig pro Item)
  • itemname: Sprechender Name des Items (nicht eindeutig)
  • itemtype: Festlegung des Item Typs. type of item; out of the iM.itemtype table
  • value: Aktueller Wert der Funktion
  • valueold: Wert der Funktion vor der letzten Änderung
    -valuetime: Zeitstempel wann sich der Wert zum letzten mal geändert hat
  • valueupdate: Zeitstempel, wann der Wert zum letzten Mal aktualisiert wurde (kann auch ohne Änderung sein)

Methoden

  • itemevent: Methode wird aufgerufen vom Modul, wenn der Wert des items sich ändert
  • itemset: Methode wird aufgerufen um den Wert des Items zu setzen
  • itemget: Methode wird aufgerufen, um den Wert des Items auszulesen

Metadaten

  • tags: LUA Tabelle mit Metadaten wie Raum, Gewerk usw.
  • Status: LUA Tabelle mit Statusdaten wie Batteriestand, Online/Offline usw.
  • vendordata: LUA Tabelle mit herstellerspezifischen Informationen. diese werden vom item Manager nicht verwendet, stehen aber grundsätzlich zur Verfügung.

Item Typen

Die Liste der Item Typen ist hier exemplarisch dargestellt. Sie kann ggf. bei bedarf zukünftig erweitert werden. Wichtig zu verstehen ist, dass jedes Item durch diese Typ-Deklaration festgelegt ist auf seine Fähigkeiten (Sensor, Aktor) und mögliche Werte.

iM.itemtype = {
    button =        {functype="event";      actions={itemset=false; itemget=false;  itemevent=true}};
    switch =        {functype="onoff";      actions={itemset=true;  itemget=true;   itemevent=true}};
    notifier =      {functype="pushevent";  actions={itemset=true;  itemget=false;  itemevent=true}};
    contact =       {functype="onoff";      actions={itemset=false; itemget=true;   itemevent=true}};
    activity =      {functype="onoff";      actions={itemset=false; itemget=true;   itemevent=true}};
    light =         {functype="onoff";      actions={itemset=true;  itemget=true;   itemevent=true}};
    dimmer =        {functype="percent";    actions={itemset=true;  itemget=true;   itemevent=true}};
    colorlight =    {functype="color";      actions={itemset=true;  itemget=true;   itemevent=true}};
    meter =         {functype="number";     actions={itemset=false; itemget=true;   itemevent=true}};
    counter =       {functype="number";     actions={itemset=false; itemget=true;   itemevent=true}};
    thermostat =    {functype="number";     actions={itemset=true;  itemget=true;   itemevent=true}};
    thermometer =   {functype="number";     actions={itemset=false; itemget=true;   itemevent=true}};
    smoke =         {functype="onoff";      actions={itemset=false; itemget=false;  itemevent=true}};
    motion =        {functype="onoff";      actions={itemset=false; itemget=false;  itemevent=true}};
    illuminance =   {functype="number";     actions={itemset=false; itemget=true;   itemevent=true}};
    humidity =      {functype="number";     actions={itemset=false; itemget=true;   itemevent=true}};
    moistness =     {functype="number";     actions={itemset=false; itemget=true;   itemevent=true}};
    barometer =     {functype="number";     actions={itemset=false; itemget=true;   itemevent=true}};
    microphone =    {functype="audio";      actions={itemset=false; itemget=true;   itemevent=true}};
    camera =        {functype="video";      actions={itemset=false; itemget=true;   itemevent=true}};
    player =        {functype="player";     actions={itemset=true;  itemget=true;   itemevent=true}};
    shutter =       {functype="percent";    actions={itemset=true;  itemget=true;   itemevent=true}};
    lock =          {functype="lock";       actions={itemset=true;  itemget=true;   itemevent=true}};
    opener =        {functype="pushevent";  actions={itemset=true;  itemget=false;  itemevent=true}};
    generic_actor = {functype="value";      actions={itemset=true;  itemget=true;   itemevent=true}};
    generic_sensor ={functype="value";      actions={itemset=false; itemget=true;   itemevent=true}}
    }

Das ist jetzt sicherlich sehr abstrakt aber ich werde in den kommenden Wochen einzelne Module vorstellen und dann wird hoffentlich klarer wie das Ganze zu verstehen ist.

Zurück