Im Winter, in der Dunkelheit, morgens am Auto und alle Scheiben zugefroren. Das warme Smart Home, in dem das sich mit meiner Bewegung durch die Räume einschaltende Licht gerade wieder erlischt, hat das nicht gekümmert. Mich aber jetzt umso mehr, während ich mit kalten Händen die Scheiben vom Eis befreie.
Wäre das Licht, welches mich beim Aufstehen im Flur begrüßt nicht nur von morgenfreundlicher Helligkeit gewesen, sondern in einer Farbe, die der Außentemperatur angepasst ist, die Warnung wäre angekommen. Dass es heut‘ mal wieder etwas länger dauert und die Handschuhe besser dabei sind, wäre mir „einleuchtender Weise“ übermittelt worden. Aber dafür reicht es nicht mit der „Intelligenz“ des Smart Home.
Die Daten sind vorhanden. Die Interfaces sie abzufragen und sie entgegenzunehmen auch. Nur wie finden diese beiden Enden zusammen?
Digitalisierung überall
In immer mehr Häusern findet man jetzt Smart Home Installationen, die auf Basis eines ZigBee Funknetzwerks arbeiten. Auch von IKEA ist inzwischen mit Trådfri eine kostengünstige Lösung zu bekommen. Wenig anders sieht es in vielen Betrieben aus, in denen die Zahl der Sensoren und Aktoren ständig steigt und doch die Hürde der Digitalisierung nicht kleiner wird.
Wie eine für die Digitalisierung von KMUs gedachte Plattform uns bei diesem Problem aus der Heimautomatisierung helfen kann und warum auch solch scheinbar kleine Problemstellungen aufzeigen wie Digitalisierung in der Industrie vor sich gehen kann, macht unser kleines Maker Projekt deutlich.
Schlauer werden
Um das Licht jetzt schlauer zu machen, lässt sich hier mit einem Rasperry Pi einem ZigBee Gateway und einer No-Code Plattform nachhelfen. Ein experimenteller Aufbau aus einem Dataflow in der titan Platform , einem Gateway zur Lichtsteuerung und einer Lampe soll exemplarisch dabei einmal zeigen, was mit Daten alles machbar ist. Also machen mein Kollege und ich uns ans Werk.
ZigBee Gateway
Zutaten Hardware:
- RasperryPi
- RaspBee II
- Smartes Leuchtmittel z.B.: Müller Licht – tint White & Color oder IKEA Trådfri
Beim Aufbau des Smart Homes ist es genauso wie in der Industrie bei der Wahl der Steuerung. Man kann sich an einen Hersteller wie z.B. Philips Hue oder Osram Lightify binden. Damit ist man dann aber ebenso an die Launen eben dieses Herstellers gebunden. So fiel die Wahl hier auf das offenere Gateway von Dresden Elektronik. Nicht zuletzt, da es eine gut dokumentierte, Open Source REST API anbietet (https://github.com/dresden-elektronik/deconz-rest-plugin).
Zutaten Software:
- deCONZ
- deCONZ REST Plugin
Der Aufbau des Gateways und auch die Installation der nötigen Software gestalten sich dankbar einfach. Es gilt an dieser Stelle der detaillierten Dokumentation auf der Website des Herstellers zu folgen. In der deCONZ GUI oder über die Phoscon APP kann danach das erste Leuchtmittel angelernt werden. Wer nicht immer die GUI geöffnet haben möchte, damit das REST Interface zur Verfügung steht, betreibt dieses im headless Modus, kann danach jedoch auch nicht mehr die deCONZ GUI nutzen. Für Debugging und ähnliche Zwecke muss man dann etwas hin und her wechseln. Auf der Kommandozeile ist dazu der entsprechende Dienst auf enable
zu setzen und zu starten.
sudo systemctl enable deconz
sudo systemctl start deconz
Ohne große Mühe haben wir jetzt dank Dresden Elektronik schon eine mit etlichen nützlichen Features wie Lichtgruppen, Zeit Steuerung, Szenen und weiterem ausgestattet Steuerung. Für sich schon smart, aber nicht smart genug, um mit im Web leicht verfügbaren Informationen mehr aus der Sache zu machen.
Bring Farbe in Dein Leben
Zutaten:
- titan Plattform
- Datenfluss basierte Programmierung
Die Temperaturdaten für die farbliche Steuerung der Lampe gibt es aus dem Web. Wir nutzen hier die nach einer Anmeldung frei verfügbare Variante der REST API von OpenWeatherMap (https://openweathermap.org/api), mit der auch für deinen Ort auf dem Globus Wetterdaten verfügbar sein sollten. Das Abfragekontingent ist großzügig, wenn man es benötigt. Für echte Bastler lässt sich unser Beispiel natürlich auch mit der eigenen Wetterstation realisieren.
Um jetzt auf der einen Seite die Daten abzuholen und auf der anderen Seite als Steuerinformationen an das Gateway zu übergeben, benötigen wir „Glue Code“, der die Arbeit für uns verrichtet. Damit dieser wartbar und veränderbar bleibt, schreiben wir erst gar keinen Code, sondern nutzen die Möglichkeiten der titan Plattform per Datafluss Programmierung eben diese Daten zu holen, zu transformieren und an das Gateway zu senden. Die Elemente der Programmierung werden Bricks genannt und es stehen uns eine Reihe generischer Bricks zur Verfügung, mit denen schon eine Vielzahl an Aufgaben erledigt werden können.
Am Anfang des Flows steht ein HTTP Request an die REST API von Open Weather. Dafür nutzen wir in titan den HTTPClient
Brick mit dem wir die Daten aus dem WWW abfragen können.
Eine Anfrage zusammen mit dem zuvor bei OpenWeather generierten API Schlüssel für z.B.:
https://api.openweathermap.org/data/2.5/weather?q=Kiel&units=metric&appid=15a3102429698031a2aacb41b8598bc0
liefert dann neben weiteren Informationen zum aktuellen Wetter die begehrte derzeitige Temperatur am abgefragten Ort:
{
"name": "Kiel",
...
"main": {
"temp": 6.39,
...
},
}
Den Startpunkt haben wir, muss nur noch eine Farbe daraus werden, mit der die Lampe gefüttert werden kann. Der HTTPClient
liefert den gesamten Body zurück, aus dem wir dann nur die benötigten Daten extrahieren. Der JSONParser
wandelt uns zuerst das universelle textuelle Ergebnis in eine Key-Value Map, welche die titan Plattform besser versteht. Den Inhalt der Map, oder besser der Teil der uns interessiert legen wir am Portmapping des Ausgangsports fest. Das von OpenWeather erhaltene JSON enthält den Schlüssel main und darin die begehrte Temperatur. Dazu fügen wir der resultmap ein Element main von Typ map und darunter das Element temp vom Typ float32 hinzu. Das Port Mapping erledigt den Rest für uns, wenn wir das Feld temp auf das Feld celsius des nächsten Bricks zuweisen.
Aus der Temperatur werde Farbe. Dies ist eine speziellere Rechenaufgabe für die wir in titan noch keinen generischen Brick gefunden haben mit dem sich dies erledigen ließ. Also doch ein wenig Programmierung. Ein neues Brick Paket muss her, in dem der TemperatureToHUE
Brick implementiert wird. Die Anleitung „How To Write a Brick“ und das Template für Brick Pakete helfen bei der Erstellung. Das neue Paket stellen wir dann, dem Open Source Gedanken der Plattform folgend, auch gleich als Repository zur Verfügung. Die Nächsten, die sich einer ähnlichen Aufgabe wie wir stellen, haben den Brick dann gleich zur Verfügung oder müssen zumindest nur noch das entsprechende Paket in Ihrer Instanz hochladen.
Damit es, wenn es im Winter draußen schön kalt ist, tiefblau leuchtet und im Sommer rot, erstellen wir zuerst einen linearen Gradienten aus dem HLS Farbkreis. Mit der aktuellen Temperatur ermitteln wir dann später den anzuzeigenden Farbton aus diesem Gradienten. Sobald unser neuer Brick in der Plattform hochgeladen ist, erledigt das Port Mapping am Input und Output des Bricks.
from ujotypes import UjoUInt16
import titanfe.log
from titanfe.brick import BrickBase
log = titanfe.log.getLogger(__name__)
HUE_MAX = 65535 # 360°
HUE_COLD = int(HUE_MAX / 360 * 250) # deep blue at 250°
HUE_HOT = 0 # red at 0°
TEMP_MIN = -20.0
TEMP_MAX = 40.0
def make_gradient(hue_min, hue_max, temp_min, temp_max):
""" create evenly spaced gradient from low to high"""
temp_range = range(int(temp_min * 10), int(temp_max * 10) + 1)
return {
temp: int(hue_min + step * (hue_max - hue_min) / (len(temp_range) - 1))
for step, temp in enumerate(temp_range)
}
class Brick(BrickBase):
temp_color_gradient = make_gradient(HUE_COLD, HUE_HOT, TEMP_MIN, TEMP_MAX)
def process(self, input, port):
try:
temperature = float(input.value)
except (ValueError, TypeError) as error:
log.error("Temperature is not a numeric value: %s", error)
log.debug("Failed to floatify: %s", input.value, exc_info=True)
return
temp = max(min(float(temperature), TEMP_MAX), TEMP_MIN) # fix temp between -20 to 40°
temp = round(temp, 1) * 10
return UjoUInt16(self.temp_color_gradient[temp])
Damit der Farbton bei der Anzeige auch passt, muss dem Kommando an die Lampe auch noch die Sättigung und die Helligkeit mit übermittelt werden. Wer weiß, welche Lichtstimmung zuletzt im Flur angesagt war. Für die Aufgabe Festwerte in den Datenstrom des Flows zu injizieren gibt es die Konstanten im Portmapping, die mit den passenden Werten belegt und in das Payload
Feld des HTTPWriter
gemappt werden.
Das Kommando an das ZigBee Gateway geht dann per HTTPWriter
im Body des Request raus. Dazu muss am Brick nur die aufzurufende URL parametrisiert und per Port Mapping die einzelnen Felder aus dem Datenstrom an das Payload
Feld des Bricks übergeben werden. Den Aufbau der Map für den Payload wird im Portmapping Dialog der Verbindung zum HTTPWriter angelegt. Die nötigen Infos über die Parameter des Kommandos finden sich in der deCONZ API Dokumentation beim Set State Kommando für Lampen. Die Umwandlung des UJO Objekts aus dem Flow in JSON übernimmt das Port Mapping und der Brick.
{
"bri": 10,
"hue": 15170,
"sat": 255
}
Bereit für die nächste Stufe
Für den nächsten kalten Tag, an dem ich jetzt rechtzeitig gewarnt werde, dass Eiskratzen angesagt ist, sorgt die Natur. Mehr Ideen, was man noch alles mit Daten aus dem Netz und Datenfluss Programmierung machen kann, kommen bestimmt auch noch. Wie einfach sich Digitalisierung erreichen lässt und dass es uns mit der Plattform, den Bricks und Flows möglich sein wird, diese in iterativer und einfach Form anzugehen, hat der Ausflug in die Heimautomation gezeigt. Die meisten Aufgaben waren mit allgemeinen Bausteinen lösbar. Nur dort, wo wirklich spezielle Dinge benötigt werden, muss noch Hand angelegt werden.
Übertragbar ist dies in den industriellen Bereich. Auch dort gibt es einen Reichtum an Daten, die nur darauf warten, in die passende Form gebracht und den ebenfalls schon bereitstehenden Endpunkten übergeben zu werden . Klein anzufangen und einen Datenfluss dann fortlaufend zu erweitern und an die Gegebenheiten anzupassen, anstelle einer großen Lösung auf einmal, erscheint dabei völlig natürlich.