Zuhause, als Fan von tollen technischen Spielsachen, herrscht Philips Hue über das Licht. Gerade Nachts, wenn ich beim Basteln mal wieder die Zeit vergessen habe, dann habe ich zwei Optionen:

a) mein Handy suchen und mich durch die App quälen
b) Alexa zuflüstern "Alexa, schalte Wohnzimmer aus" "Alexa, schalte Arbeitszimmer aus"

Beides nicht so die epischen Lösungen! Aber als Träumer und Bastler denke ich direkt an den roten Panik-Knopf! Projekt "Shutdown"- ist geboren (man braucht immer einen coolen Projektnamen).

Hardware

Durchführung

Ziel ist es, wenn der Reset-Button des ESP8266 gedrückt wkrd, dass dann das System neustartet und alle Lampen ausschlatet. Um den ESP8266 möglichst lang an einer externen Stromversorgung wie ein Akku oder ähnliches zubetreiben kann man nach dem Boot und Ausführung des Ausschalten den ESP8266 in ein DeepSleep schicken, um möglichst viel Strom zu sparen.

Reset Button -> Boot -> mit Webservice Lampen ausschalten -> DeepSleep zum Stromsparen

Account für Philips Hue Entwickler API einrichten

Damit wir die Hue Bridge von Philips ansprechen können, müssen wir uns einen Entwickler-Account auf der Bridge einrichten.

Dafür gehen wir wie folgt vor - aber zuerst müsst ihr die IP eurer Philips Hue Bridge herausfinden. Am besten schaut in eurem Router nach.

Habt ihr die IP gefunden, dann rufen wir im Browser folgende Adresse auf, wobei die 192.168.13.37 mit euer Philips Hue Bridge IP ersetzt werden muss.

http://192.168.13.37/debug/clip.html
URL der Philips Hue Bridge API GUI

Eine wunderschöne Benutzeroberfläche wie diese sollte erscheinen:

Erster Aufruf Philips Hue CLIP API Debugger

Die API ist eine normale REST-Api, welche mit Hilfe von JSON kommuniziert.

Wem die Übertragungsmethoden auf anhieb nicht so klar sind, der kann diese hier nachlesen: https://de.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Argument%C3%BCbertragung

TL;DR (too long; didn't read): GET (aus dem engl. erhalten) ist zum Holen von Informationen. POST/PUT ist zum Senden von Informationen gedacht.

Um einen neuen Entwickler anzulegen, müssen wir nun mit POST ein Gerät registrieren.

Dazu rufen wir die API wie folgt auf:

URL: /api
Message Body: {"devicetype": "Welcher_Name_Auch#Immer"}

Gerät in der Philips Hue API registrieren

und drücken auf den POST-Button. Jetzt solltet ihr im Bereich Command Response folgende Nachricht erhalten.

[
	{
		"error": {
			"type": 101,
			"address": "",
			"description": "link button not pressed"
		}
	}
]

Überraschung - wir müssen auf der Bridge noch den großen runden Knopf drücken, um zu beweisen, dass wir wirklich anwesend sind und uns nicht ins Netzwerk gehackt haben.

Für Berechtigung den Button auf der Bridge drücken

*Booooop* und schon drücken wir nochmal im CLIP API Debugger auf den POST-Button.

Habt ihr das mit dem Button erledigt und erneut auf den POST-Button gedrückt, dann solltet ihr im Bereich Command Response eine Antwort ähnliche wie folgende Antwort erhalten.

[
	{
		"success": {
			"username": "gs54nbCoOri9qh6IXy1hXuKrs97sCBKUI0Avgu57"
		}
	}
]

Den Wert von dem username-Attribut müsst ihr euch jetzt gut notieren, sonst ist der für immer verloren.

Als nächsten Schritt müssen wir die Lampen holen, welche in unserem Philips Hue Netzwerk verwaltet werden. Dazu rufen wir folgende API auf.

/api/gs54nbCoOri9qh6IXy1hXuKrs97sCBKUI0Avgu57/lights

Mit dem Klicken des GET-Buttons erhalten wir alle Geräte, welche als Licht innerhalb unseres Philips Hue Netzwerkes verwaltet werden.

Wir brauchen die Nummern (mesitens 1-n) die am Anfang des Arrays stehen, welche als ID des Gerätes dienen.

Rot markiert ist die ID einer Lampe als Beispiel

Um eine Lampe aus oder einzuschalten, können wir über folgenden Webservice arbeiten.

/api/gs54nbCoOri9qh6IXy1hXuKrs97sCBKUI0Avgu57/lights/1/state

Der GET-Button holt den Zustand (engl. state) der Lampe.

Mit dem PUT-Button und dem Message Body

{"state":true}

schalten wir die Lampe an und mit

{"state":false}

schalten wir die Lampe aus.

Ok, da jetzt die Basics funktioniern können wir ein Script auf dem ESP bauen. Dafür sollten wir alle Lampen raussuchen die wir an- oder ausschalten wollen. Leider reicht der Speicher des ESP8266 nicht aus, um die Lampen automatisch auszulesen.

ESP8266 als "Alle Lichter aus"-Schalter für Philips Hue programmieren

Wir entwickeln wie immer in der Web IDE von Espruino ( hier erklärt ) mit JavaScript für den ESP8266 oder dem ESP32.

const wifi = require("Wifi");
const http = require("http");

// #### Einstellungen

// Username und IP von der Hue Bridge
const username = "gs54nbCoOri9qh6IXy1hXuKrs97sCBKUI0Avgu57";
const hue_ip = "192.168.13.37";

// WLAN Daten
const wlan_ssid = "WLAN";
const wlan_password= "SuperSecret?";

// Alle Lampen-Id´s, die aus dem JSON /api/username/lights an und ausgeschaltet werde sollen.
const devices = [1, 2, 3, 7, 8, 9, 10, 11];

// Alle Lampen an = true, Alle Lampen aus = false
const ausOderAn = false;

// ############################################################################## //

// function zum An- oder Ausschlaten von Lampen.
// Als Übergabe ein "true" oder "false" und die Id der Lampe.
function lampeAusOderAn(onOrOff,id) {
    var message = onOrOff ? '{ "on": true }' : '{ "on": false }';
    return new Promise(function(resolve, reject){
        // HTTP Request, um die Lampe an oder auszuschalten.
        var req = http.request({
            host: hue_ip, 
            port: 80,
            path: '/api/' + username + '/lights/'+id+'/state',
            method: 'PUT',
            protocol: 'http:',
            headers: { "Content-Length": message.length }
        }, function (res) {
            res.on("close", function () {
                resolve(true);
            });
            res.on("err", function (err) {
                reject(err);
                console.log(err);
            });
        });

        req.write(message);
        req.end();
    });
}

// Verbindung mit dem WLAN herstellen.
wifi.connect(wlan_ssid, { password: wlan_password }, function (err) {
    if (err) {
        console.log("Wifi Connect Error: " + err);
    }
    var alleLampenStatus = [];
    // Alle Lampen an odder ausschalten
    for(var device in devices){
        alleLampenStatus.push(lampeAusOderAn(ausOderAn, devices[device]));
    }

    Promise.all(alleLampenStatus).then(function(){
        // Wenn alle Lampen an oder aus gestellt wurden,
        // könnte hier ein DeepSleep implementiert werden.
        console.log(ausOderAn ? "Alle Lampen an" : "Alle Lampen aus.");
    });
});

Projekt Shutdown wurde erfolgreich umgesetzt!

Cheers Jörg