„Alexa, Licht an“ – aber nur in diesem Zimmer!

Eine Lösung für Single-Room-Commands mit Alexa und ioBroker

Javascript-Code erläutert

Jetzt erweitern wir den bisherigen Code. Wir beginnen wie oben:

on('alexa2.0.History.json'/*json*/, function (obj) {
log(obj.state.val);

Der aktuelle Status (state) des übergebenen Objekts (obj) hat den Wert (val). Wir greifen mit obj.state.val darauf zu und erhalten einen String, der das JSON-Objekt darstellt. Wir wandeln den String obj.state.val in ein tatsächliches JSON-Objekt um, damit wir die Eigenschaften direkt ansprechen können.

    var jsonObj = JSON.parse(obj.state.val); 

Jetzt erhalten wir mit jsonObj.name, jsonObj.status und jsonObj.summary die unten benötigten Werte.

Es sollte nur weitergehen, wenn kein Problem aufgetreten ist. Wir fragen den Status ab:

    if (jsonObj.status == "SUCCESS") {

Wie wir im letzten Test auf der vorigen Seite festgestellt haben, kann der Befehl in der „summary“ auch ohne Aktivierungswort („Alexa“) auftreten. Bevor wir den gelesenen Befehl auswerten können, muss, falls vorhanden, das Aktivierungswort entfernt werden.

    var wakeWords = ["alexa", "echo", "computer", "amazon"]; 
var wakeWord = commandArray[0];
   if (wakeWords.indexOf(wakeWord) >= 0) {
      commandArray.shift();
   }

Der auszuführende Befehl steht in jsonObj.summary. Damit wir auf die einzelnen Wörter leichter zugreifen können, wandeln wir den String in einen Array um.

        var commandArray = jsonObj.summary.split(" ");

Damit wir etwas haben, das wir ausführen können, muss commandArray mindesten ein Befehlswort enthalten.

        if (commandArray.length >= 1) {

Wir legen einen Verteiler nach dem ersten Befehlswort an. Weitere Fälle können nun leicht hinzugefügt werden.

            switch (commandArray[0]) {
            case "licht":
               //...
               break;
            case "tür":
               //...
               break;
            case "rolllade":
               //...
               break;
            }
}
}
});

Soweit die grundlegende Struktur der Lösung. Im Folgenden findest du ein voll ausgeführtes Beispiel.

Ein komplettes Beispiel

Hier ist eine praktische Umsetzung. Etwa so ist es bei mir im Einsatz.

var wakeWords = ["alexa", "echo", "computer", "amazon"];

on('alexa2.0.History.json'/*json*/, function (json) {
log(json.state.val);

// Parameter json ist eine String; Umwandeln in ein JSON-Objekt
var jsonObj = JSON.parse(json.state.val);

// es geht nur weiter, wenn kein Problem aufgetreten ist
if (jsonObj.status == "SUCCESS") {

//Alexa-Aufruf aus jsonObj.summary in Array umwandeln
var commandArray = jsonObj.summary.split(" ");

// Entfernen des WakeWord, falls vorhanden
var wakeWord = commandArray[0];
if (wakeWords.indexOf(wakeWord) >= 0) {
    commandArray.shift();
}

// Name des Alexa-Geräts, das den Befehl empfangen hat
var deviceName = jsonObj.name.toLowerCase();

//commandArray muss mindesten ein Befehlswort enthalten
if (commandArray.length >= 1) {
log("Echo-Device " + deviceName + ": " + commandArray);

//Verteiler nach dem ersten Befehlswort
switch (commandArray[0]) {
case "licht":
calling_Licht(deviceName, commandArray);
break;
case "rolllade":
case "rollladen":
calling_Rolllade(deviceName, commandArray);
break;
}
}
}
});

/*************** Functions ****************/
function calling_Licht(deviceName, commandArray) {
switch (commandArray[1]) {
case "an":
switch (deviceName) {
case "eins": //Wohnzimmer
setState('hm-rpc.0.XXXXXXXXXX.1.STATE', true);
break;
case "zwei": //Küche
exec('pilight-send -p intertechno -i X -u X -t',
function () {
log("Küchenlampe: an", "info");
});
break;
case "drei": //Arbeitszimmer
log("deconz.0.Light_1.on: " + true, "info");
setState('deconz.0.Light_1.on'/*Light 1 on*/, true);
break;
}
break;
case "aus":
switch (deviceName) {
case "eins": //Wohnzimmer
setState('hm-rpc.0.XXXXXXXXXX.STATE', false);
break;
case "zwei": //Küche
exec('pilight-send -p intertechno -i X -u X -f',
function () {
log("Küchenlampe: aus", "info");
});
break;
case "drei": //Arbeitszimmer
log("deconz.0.Light_1.on: " + false, "info");
setState('deconz.0.Light_1.on'/*Light 1 on*/, false);
break;
}
break;
}
}

var rollladeWohnzimmerRechts = 'hm-rpc.0.XXXXXXXXXX.1.';
var rollladeWohnzimmerLinks = 'hm-rpc.0.XXXXXXXXXX.1.';
var rollladeKueche = 'hm-rpc.0.XXXXXXXXXX.1.';
var rollladeArbeitszimmer = 'hm-rpc.0.XXXXXXXXXX.1.';

function calling_Rolllade(deviceName, commandArray) {
//100 = hochgefahren, 0 = komplett heruntergefahren

switch (commandArray[1]) {
case "stopp":
case "stop": {
switch (deviceName) {
case "eins": //Wohnzimmer
setState(rollladeWohnzimmerRechts + "STOP", true);
setState(rollladeWohnzimmerLinks + "STOP", true);
break;
case "zwei": //Küche
setState(rollladeKueche + "STOP", true);
break;
case "drei": //Arbeitszimmer
setState(rollladeArbeitszimmer + "STOP", true);
break;
}
break;
}
case "hoch": {
switch (deviceName) {
case "eins": //Wohnzimmer
setState(rollladeWohnzimmerRechts + "LEVEL", 100);
setState(rollladeWohnzimmerLinks + "LEVEL", 100);
break;
case "zwei": //Küche
setState(rollladeKueche + "LEVEL", 100);
break;
case "drei": //Arbeitszimmer
setState(rollladeArbeitszimmer + "LEVEL", 100);
break;
}
break;
}
case "runter": {
switch (deviceName) {
case "eins": //Wohnzimmer
setState(rollladeWohnzimmerRechts + "LEVEL", 0);
setState(rollladeWohnzimmerLinks + "LEVEL", 0);
break;
case "zwei": //Küche
setState(rollladeKueche + "LEVEL", 0);
break;
case "drei": //Arbeitszimmer
setState(rollladeArbeitszimmer + "LEVEL", 0);
break;
}
break;
}
}
}

Die über den Verteiler aufgerufenen Funktionen „calling_Licht“ und „calling_Rolllade“ sind nicht weiter erläutert. Sie sind als Beispiele für die Integration von aktiven Elementen aus verschiedenen Bereichen unter dem Dach von ioBroker zu sehen: Homematic, Zigbee (mit dem ConBee-Gateway auf USB-Stick von dresden elektronik) und der direkte Aufruf über die Commandline (mit Pilight, einem 433Mhz-Funk-Modul für den Raspberry Pi).

Wenn dir dieser Artikel geholfen hat,
deine eigene Lösung zu verwirklichen,
dann lass‘ es mich wissen.
Schreibe einen kurzen Kommentar.
Vielen Dank!


Autor: Rai

jahrelanger Homematic-Benutzer, öffnet sich mit Hilfe von Raspberry Pi und ioBroker für Neues im Internet of Things

4 Gedanken zu „„Alexa, Licht an“ – aber nur in diesem Zimmer!“

  1. ne coole Sache. Leider habe ich das Problem, dass ich in meinem ioBroker den State vom Schalter irgendwie nicht per checkbox switchen kann. D.h. ich muss den State im Dialogfenster per Text auf TRUE setzen, so dass die Lampe angeht. Warum auch immer.

    Wenn ich dann sage Alexa: Licht AN, wird die Routinenausführung bestätigt aber das Licht geht nicht an 🙁

    Hier mal das Log:
    avascript.0 (962) script.js.LXSkript.jsCallFromEchoDevice: {„name“:“Bad Echo Dot“,“serialNumber“:“xxxxxxsdf“,“summary“:““,“creationTime“:1585122686348,“status“:“SUCCESS“,“domainApplicationId“:““,“domainApplicationName“:““,“cardContent“:““,“card“:““,“answerText“:““}
    08:51:26.954 info javascript.0 (962) script.js.LXSkript.jsCallFromEchoDevice: Echo-Device bad echo dot:
    08:51:26.978 info javascript.0 (962) script.js.LXSkript.jsCallFromEchoDevice: {„name“:“Bad Echo Dot“,“serialNumber“:“xxxxxxx“,“summary“:“licht an“,“creationTime“:1585122686526,“status“:“SUCCESS“,“domainApplicationId“:““,“domainApplicationName“:““,“cardContent“:““,“card“:““,“answerText“:““}
    08:51:26.979 info javascript.0 (962) script.js.LXSkript.jsCallFromEchoDevice: Echo-Device bad echo dot: licht,an
    08:51:27.879 info javascript.0 (962) script.js.LXSkript.jsCallFromEchoDevice: {„name“:“Bad Echo Dot“,“serialNumber“:“xxxxx“,“summary“:“sprich mir nach ok befehl“,“creationTime“:1585122686975,“status“:“SUCCESS“,“domainApplicationId“:““,“domainApplicationName“:““,“cardContent“:““,“card“:““,“answerText“:““}
    08:51:27.881 info javascript.0 (962) script.js.LXSkript.jsCallFromEchoDevice: Echo-Device bad echo dot: sprich,mir,nach,ok

    1. Hallo Alex, am Log-File bemerke ich nichts Außergewöhnliches. Vielleicht kannst du mal dein JavaScript zum Licht-An/Ausschalten posten. Gruß Rai!

    1. Hallo Pavel, danke für deine Rückmeldung. Ja, wenn es möglich ist, ziehe ich Lösungen vor, die ohne Daten in der Cloud auskommen. Denk dran, dass, wenn Alexa im Spiel ist, auf jeden Fall die Amazon Cloud im Hintergrund steht. Ganz ohne Cloud geht es also nicht immer. Gruß Rai!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.