Server - pigtastic/UBQ-Smarthome Wiki

Original URL: https://github.com/pigtastic/UBQ-Smarthome/wiki/Server

Das Herzstück unserer Anwendung ist der Server. Unser Server basiert auf Apollo Server im Kombination mit Express.

Das Ziel war es die Architektur so zu gestalten, das zukünftige Weiterentwicklungen einfach integriert werden können ohne die Basis verändern zu müssen. Hierbei setzen wir auf die Graph-QL Module Bibliothek. Aktuell gibt es die zwei Module Deviceund Group. Ein einzelnes Modul enthält ein Schema, zugehörige Resolver sowie ein Provider für die Datenbankanbindung. Der Provider wird an den benötigten Stelle via Dependancy Injection injiziert.

UML

Das Diagramm zeigt schematisch den Aufbau.

Embedded MQTT Broker

Um mit MQTT Servern kommunizieren zu können, wird parallel zum Apollo Server noch ein MQTT Broker benötigt. Wir nutzen den Aedes MQTT Broker. Dieser leitet sämtlichen Traffic über eine GraphQL Mutation weiter. Somit ist die Business Logik gänzlich getrennt vom MQTT Broker. Durch diese Aufteilung ist es auch möglich, einen externen MQTT Broker zu nutzen.

Automatisiertes Anlegen von Geräten

Ein definiertes Ziel war es, das Anlegen von Geräten so einfach wie möglich zu gestalten. Daher wurde eine Möglichkeit geschaffen, die minimalsten Einsatz vom Anwender erfordert. Bei der Einrichtung der Tasmota-IoT-Geräte muss zusätzlich die IP-Adresse des MQTT Brokers sowie der Port (Standard 1883) angegeben werden. Damit ist die Konfiguration abgeschlossen und schon ist das Gerät Gaia-Ready.

Tasmota

Tasmota veröffentlich bei der Anmeldung am Broker einmalig eine Konfiguration. Diese enthält alle notwendigen Informationen, um das Gerät in Gaia anlegen zu können. Im Folgende schauen wir uns eine Konfiguration genauer an. Diese ist auf die notwendigen Eigenschaften gekürzt, die wir verarbeiten.

{
   "dn":"Ecklicht",
   "t":"tasmota_644419",
   "rl":[
      1,
      0,
      0,
      0,
      0,
      0,
      0,
      0
   ]
}

Aus diesen Werten erzeugen wir ein DeviceObjekt in unserer Datenbank.

Generalisierung

Das beschriebene Vorgehen ist stark abhängig vom Tasmota Discovery Publish. Um zukünftig auch Firmware von anderen Herstellern unterstützen zu können, ist die Verarbeitung mit dem Chain-of-Responsibility-Pattern gelöst. Das bedeutet, es gibt für jede Firmware einen Handler der von der Abstrakten Klasse ``ÀbstractHandler```erbt. Der Device-Provider hält eine Liste mit allen verfügbaren Firmware Handlern.

abstract class AbstractHandler {
  abstract canHandle(data: String): boolean; #1

  abstract handleChangeState(device: Device, fn: string, state: string, dataBaseConnection: any); #2

  abstract handleMqttPublish(topic: any, payload: any, dataBaseConnection: any); #3
}
  1. Diese Methode wird genutzt um herauszufinden, ob der Handler mit dem aktuellen Payload umgehen kann.
  2. Verarbeitung von Payload gesendet vom Client
  3. Verarbeitung von MQTT Payload

Ein Payload wird abgearbeitet, indem jeder verfügbare Handler "gefragt" wird, ob er diesen Payload verarbeiten kann. Wenn dies zutrifft, wird der Payload je nach Ursprung verarbeitet. Im Code sieht diese Prozedur wir folgt aus:

if (handler.canHandle(topic)) {
 handler.handleMqttPublish(topic, payload, mongoDevices);
}

Aktuell können wir sowohl Geräte mit Tasmota sowie unsere eigene Gaia Firmware verwalten.