IFTTT Actions im Intranet mit Adafruit IO & MQTT

IoT

Ich freue mich immer wenn Entwickler von IoT Geräten Möglichkeiten einbauen auf Ereignisse zu reagieren. Bestes Beispiel ist der Echo*, dem Amazon mit IFTTT ein paar nette Trigger spendiert, z.B. wenn der Timer ausläuft oder ein Wecker losgeht.

Worüber ich nicht besonders freue, ist das diese Trigger meistens nur mit IFTTT funktionieren. Klar, Amazon versucht damit einer größere Zielgruppe von Bastlern zu erreichen als wenn Sie z.B. HTTP Requests einbauen würden. Dafür erreiche ich meine Smarthome Geräte nicht mehr, die alle hinter meiner FRITZ!Box im Intranet stehen. Während ich darauf warte das Amazon für mich diese Trigger einbaut, hab ich mich nach Übergangslösung angeschaut, wie ich (möglichst sicher) IFTTT Actions in meinem Intranet auslösen kann.

Der erste Gedanke ging natürlich an den IFTT Maker Channel, Portfreigabe im Router und ein nginx o.ä. der die Requests entgegen nimmt und Skripte ausführt. Ehrlich gesagt war mir immer etwas mulmig bei dem Gedanken Zugriff von außen in mein Intranet zu ermöglichen… Klar, mit fail2ban etc kann man vieles verhindern aber am liebsten war mir eine Möglichkeit in die andere Richtung.

Danke es sehr guten Tipps von Nils (Danke!) habe ich mir mal MQTT angeschaut, ein offenes Protokoll für M2M Kommunikation. Der häufigste Anwendungsfall im Bereich MQTT wird vermutlich sein, das Sensoren oft und ohne Aufwand Werte an einen Server schicken sollen, und Clients diese Auswerten und reagieren. Für mich besonders interessant war aber die Möglichkeit das Clients sich mit dem „Broker“ verbinden, und die Nachrichten dann in Echtzeit gepusht bekommen, es gibt kein Polling. Ein paar Sekunden Verzögerung könnte viele Aktionen schon unnütz werden lassen.

Ich habe im ersten Versuch einen MQTT Server bei CloudMQTT gemietet, und über den IFTTT Maker Channel einen PHP Datei aufgerufen die MQTT Events erstellt hat. Beim Basteln bin ich dann auf Adafruit IO getoßen. Adafruit IO bietet sogenannte Feeds. Die können auch vielen verschiedenen Quellen beschrieben werden und z.B. mit MQTT ausgelesen werden, Außerdem hat es eine native IFTTT Integration und war in meinen Tests noch ein paar Sekundenbruchteile fixer als mit PHP. Ein Applet für Alexa könnte z.B. so aussehen:

 

 

Damit wäre der Broker auch schon fertig. Als Client kann theoretisch alles fungieren; Es gibt für viele Programmiersprachen fertige Bibliotheken. Bei läuft die komplette Hausautomation auf einem C.H.I.P., und dort fast alles über Node.js. Ich hab mich deshalb auch entschieden den Client in JavaScript zu schreiben, die passende Bibliothek für Node.js trägt den passenden Namen mqtt.

So sieht mein Code im Moment aus:

var mqtt = require('mqtt');
var request = require('request');
var exec = require('child_process').exec;
var url = 'mqtts://io.adafruit.com';
var options = {
	username: 'pattyland',
	password: '*******',
};
var client = mqtt.connect(url, options);
client.on('connect', function() {
	console.log("connected");
	client.subscribe('pattyland/feeds/alexa-timer');
})
client.on('message', function(topic, message) { 
	console.log(new Date().toJSON() + " " + topic);
	switch (topic) {
	case "pattyland/feeds/alexa-timer":
		exec("/home/chip/pause-fire-tv.sh");
		request({
			url: 'http://localhost:8465/api/username/lights/4/state',
			method: 'PUT',
			json: {
				on: "true"
			}
		});
		break;
	}
})Code-Sprache: JavaScript (javascript)

Kurz erklärt:

Verbinde dich über MQTT mit io.adafruit.com und abonniere (subscribe) meinen Feed „alexa-timer“. Hier können beliebig viele Feeds abonniert werden.  Spanned wird’s dann beim Listener. Hier warte ich bis eine „message“ ankommt und schaue in welchem Feed diese gepostet worden ist, die eigentliche Nachricht ignoriere ich im Moment. Da ist hier im Intranet bin, stehen mir alle Möglichkeiten offen: In meinen Fall weise ich meine ha-bridge die Lampe Nr. 4 einzuschalten, was dazu führt das mein selbstgebautes Ambilight rot blinkt. Außerdem starte ich ein Skript dass sich via ADB mit meinem Fire TV verbindet und die Pause-Taste simuliert, damit ich den Timer nicht aus Versehen verpasse weil ein Film oder Musik läuft.

Hier ist nochmal eine kleine Grafik die den Weg von Alexa zum IoT Gerät beschreibt:

So könnte sieht das ganze dann im Ergebnis aus:

Hyperion mit Alexa steuern

IoT

Schon seit ein paar Tagen habe ich nun auch ein paar LED-Streifen hinter meinem Fernseher, die dank Hyperion auf einem Raspberry Pi* mich in den Genuss von Philips Ambilight kommen lassen. Eine Demo davon gibt’s zum Beispiel hier.

Nun steht seit kurzem auch ein Echo Dot* auf meinem Wohnzimmertisch, und ich habe natürlich direkt geschaut, welche Geräte man noch mit Alexa steuern kann, die nicht im Standardrepertoire enthalten sind.

Der „normale“ Weg über AVS, bei dem ich extern einen Dienst mit SSL-Zertifikat usw. hosten muss, kam für mich erstmal nicht in Frage. Viel besser fand ich den Ansatz der ha-bridge. Diese emuliert eine Bridge für Philips-Hue-Geräte für Alexa und lässt einen für diese beliebige Aktionen festlegen. In Kombination mit hyperion-remote, das netterweise direkt mit Hyperion ausgeliefert wird, lässt sich das ganze sehr einfach mit Alexa steuern:

  1. ha-bridge downloaden und starten (Wichtig: Java 1.8. Wenn ihr kein Google Home habt, nehmt einen Port > 1024, damit ihr keine Root-Rechte braucht)
  2. Shellscript erzeugen, das sich via SSH auf dem Computer einloggt, auf dem Hyperion läuft und mit hyperion-remote die gewünschte Farbe/Effekt einstellt. Beispiel
    #!/bin/bash ssh pi@hyper "hyperion-remote --effect 'Knight rider'"
  3. Gerät in ha-bridge anlegen, das das Skript beim gewünschten Event aufruft

DDanach muss man Alexa nur noch sagen, dass sie neue Geräte suchen soll, und nach ein paar Sekunden sollte Alexa in der Lage sein:

Elgato Avea mit Siri & Homekit steuern

IoT

Nachdem ich hier recht abenteuerlich beschrieben habe, wie man die Avea von Elgato* an IFTTT anbinden kann, habe ich immer wieder Ausschau nach neuen Möglichkeiten gehalten. Die Lösung mit der App war sehr langsam, unzuverlässig und stromfressend.

Da mein ursprüngliches Ziel immer die Anbindung an Siri war, hatte ich schon länger ein Auge auf Homebridge geworfen, eine Möglichkeit, Geräte in HomeKit einzubinden, die nicht mit HomeKit kompatibel sind.

Und siehe da, vor ein paar Wochen hat jemand aus einer sehe rudimentären Implementierung des Avea Protokolls auf node Basis sich daran gemacht, daraus ein Plugin für HAP-NodeJS zu schreiben, das Tool, was die Basis für das etwas weiter entwickelte Homebridge ist. Da man beide Dienste parallel laufen lassen kann, war das aber kein Problem.

Da die genaue Installation je nach System sehr unterschiedlich sein kann, gehe ich im Folgenden nur auf die grundlegenden Schritte ein:

  1. Node.js installieren
  2. HAP-NodeJS installieren
  3. avea_node Modul für Node.js installieren
  4. Accessory für HAP-NodeJS installieren

Es gibt eine Datei, die nur mit einer Birne arbeitet, dort muss nur der Name angepasst werden und los geht’s! Das andere Beispiel ist für den Betrieb mit mehreren Birnen; da ich nur eine habe, habe ich das nicht getestet. Das Wiki dort ist eine gute Anlaufstelle für mehr Details und häufige Probleme!

Diese Lösung ist deutlich schneller und zuverlässiger als die erste. Außerdem kann ich mit Siri nun auch direkt die Helligkeit und Farbe meiner Avea steuern! Sogar die Einbindung in Szenen und die Nutzung von Auslösern ist möglich; ich nutze z.B. einen Amazon Dash Button* in Kombination mit Homebridge um die Birne auch ohne Siri ein- und ausschalten zu können.

So sieht das Ganze dann in der iOS 10 Home App aus. Da meine Birne in einer IKEA PS 2014 steckt heißt sie Todesstern. Die Szene „Angriffsmodus“ schaltet die Avea auf rot 😉

  

Elgato Avea mit IFTTT steuern

IoT

Die Avea Bulb von Elgato* war vor ein paar Jahren mein erstes Smart Home Gerät. Smart ist leider ein bisschen übertrieben, denn wirklich smart ist sie nicht. Über die iOS App oder eine Apple Watch lässt sich die Glühbirne ein- und ausschalten und verschiedene Farben/Szenen anzeigen; Automatisiertes steuern mit z.B. HomeKit oder Siri wird auf einer extra dafür eingerichteten Supportseite ausgeschlossen.

Ohne ein Reverse Engineering der iOS App wäre es vermutlich auch dabei geblieben, aber Elgato hat nach guten 2 Jahren eine App für Android nachgereicht. Ich hatte gehofft eventuell direkt die eine Aktivität der App steuern zu können, aber das geht scheinbar nicht. Nach einer kurzen Suche bin allerdings auf eine andere App gestoßen und möchte in diesem Blogpost meinen Proof of Concept für die Steuerung für Avea mit IFTTT vorstellen