Im vorherigen Artikel haben wir den Weg von Events von IFTTT zu tapio-ready Maschinen implementiert. Jetzt wollen wir den umgekehrten Weg, von tapio-ready Maschinen zu IFTTT implementieren.
Zuerst brauchen wir eine Möglichkeit, ein Event auf unserer Testmaschine auszulösen. Wir haben uns für einen AM312 und PIR-Bewegungsmelder entschieden, der über die GPIO-Schnittstelle direkt mit unserer Testmaschine verbunden werden kann. Wenn er ordnungsgemäß mit einem Erdungspin, einem Spannungspin und einem generischen GPIO-Datenpin verbunden ist, gibt er einen Strom auf dem GPIO-Pin aus, wenn vor dem Sensor eine Bewegung stattfindet.
Nachdem unser Sensor nun bereit ist, müssen wir ihn auf Statusänderungen überwachen, um folgend auf Bewegungs-Events reagieren zu können. Microsofts GPIO-Bibliothek System.Device.Gpio stellt eine Methode RegisterCallbackForPinValueChangedEvent
zur Verfügung, mit welcher man einen Callback für steigende oder fallende Ströme registrieren kann. Mit Hilfe dieser Methode haben wir uns einen kleinen Wrapper geschrieben, um die Dinge ein wenig zu vereinfachen:
Nachdem wir nun in der Lage sind, auf Statusänderungen zu reagieren, möchten wir, dass diese im OPC UA Server unserer Testmaschine als Werte eines Knoten wiedergespiegelt werden, so dass die Events dann über den tapio CloudConnector, der auch auf unserer Testmaschine läuft, an tapio weitergeleitet werden können. Also müssen wir dem Adressraum unseres OPC UA Servers einen Knoten hinzufügen:
Dann müssen wir unserem Knotenmanager eine Methode hinzufügen, welche unseren MotionSensorState
Knoten aktualisieren kann:
Schließlich müssen wir unseren Bewegungsmelder-Monitor mit der Aktualisierungs-Methode verbinden:
Jetzt sind wir in der Lage, Bewegungen vor unserem PIR-Bewegungsmelder automatisch als OPC UA Knotenwertänderungen darzustellen. Der CloudConnector kann diese Statusänderungen dann an tapio weiterleiten, wenn wir das Datenmodul des CloudConnectors korrekt konfigurieren. Auf den konfigurierten SrcKey
kommen wir gleich zurück.
Da tapio das Streaming dieser Daten in einen Azure Event Hub unterstützt, haben wir uns schnell einen Event Hub über das Azure Portal bereitgestellt und eine App in my tapio konfiguriert, welche die Streaming-Daten an unseren Event Hub weiterleitet.
Daten die in einem Azure Event Hub ankommen, können problemlos für Anwendungen von Drittanbietern verarbeitet, gespeichert oder bereitgestellt werden. Da wir Ereignisse, nur verarbeiten und weiterleiten wollen, haben wir uns wieder für einen serverlosen Ansatz entschieden, mit einer weiteren Azure Function, welche Events aus unseren Event-Hub konsumiert.
Hier sehen wir, wie eine in unserem Event-Hub von tapio eingespeiste Event-Nachricht aussieht:
Streaming-Daten von tapio, die von unserem Event-Hub empfangen werden, können unterschiedliche Strukturen aufweisen. Wir sind nur an Daten der Form Item Data interessiert, weil wir nur die Statusänderungen unseres PIR-Bewegungsmelder-Monitorknotens überwachen wollen. Wir können Streaming-Daten vom Typ Item Data
erkennen, wenn wir einen Blick auf die Eigenschaft msgt
(Nachrichtentyp) werfen. Streaming-Daten vom Typ Item Data
haben immer den Nachrichtentyp itd
.
Die Eigenschaft msg
enthält die eigentliche Nachricht als JSON-Objekt. Hier interessieren wir uns nur für Nachrichten, deren k
der zuvor konfigurierte SrcKey
ist. Der weitergeleitete Wert, welcher ein Event darstellt, verbirgt sich hinter dem Schlüssel v
. Um die Dinge weiter einfach zu halten, übertragen wir nur eine einfache Zeichenkette (hier motiondetected
), aber später könnte man natürlich auch beliebig komplexe Events übertragen, wenn man sie beispielsweise als JSON-Objekt serialisiert.
Unten sehen wir eine vereinfachte Version unserer Event-Hub-Prozessor-Azure-Function:
Ähnlich wie bei unserer [anderen Azure Function][article_2] konsumieren wir hier einfach Nachrichten von unserem Event Hub und leiten sie dann an IFTTT weiter. Die SendEventToIFTTT
-Methode macht dabei nichts anderes als einen einfach HTTP-Request an den IFTTT Webhook-Dienst zu senden:
POST https://maker.ifttt.com/trigger/<name of the event>/with/key/<hier webhook service account schlüssel eintragen>
Den Webhook-Service-Schlüssel erhält man hier (wenn man bei IFTTT eingeloggt ist). Der Webhook-Service ist auch in der Lage, einen application/json
Body zu interpretieren, wenn er die folgende Struktur hat:
Wenn man den Body benutzt kann man jede Art von Ereignisdaten an IFTTT übertragen.
Schließlich müssen wir noch ein Applet in IFTTT konfigurieren, um unsere Implementierung zu testen. Wir haben beispielsweise Google Sheets mit dem Webhook-Service kombiniert:
Fazit
Das war's! Zwei Azure Functions, ein Event Hub, ein Raspberry Pi und drei Werktage später konnten wir einen funktionierenden Prototyp präsentieren. Für unsere Demo am vierten Tag haben wir Bewegungssensordaten über unseren tapio-IFTTT-Konnektor in ein Google Drive Tabelle geschrieben, eine RGB-LED per Widget-Taste auf einem Smartphone eingeschaltet und ein neues IFTTT-Applet live konfiguriert. Wir haben kein direkt verkaufbares Produkt entwickelt, aber einen funktionierenden Proof of Concept im tapio Ökosystem geschaffen, der in ein echtes Produkt umgesetzt werden kann. Authentifizierung, Autorisierung und eine Webanwendung zur Konfiguration von Events wären beispielsweise für eine saubere Implementierung noch zu realisieren und unser Code hätte auch noch ein großes Refactoring nötig... :D
Aber neben dem Lösen der Herausforderungen war #hackthewood2019 vor allem eine lustige Veranstaltung mit tollen Teilnehmern, die sich gegenseitig jederzeit geholfen haben und eine tolle Zeit zusammen in Berlin hatten!
Dies ist der dritte und letzte Teil der Blogpost-Serie "Connecting the digital worlds".