Ankündigung

Einklappen
Keine Ankündigung bisher.

Alexa mit Homeautomation Skill

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    Alexa mit Homeautomation Skill

    steffen79
    Ich mache mal einen neuen Post auf, weil es in dem anderen etwas untergeht, denn ich versuche deinen Homeautomation Skill umzusetzen.
    Zitat von steffen79 Beitrag anzeigen
    Die Skills für Alexa werden auf https://developer.amazon.com definiert. Dort kann man die erkennbaren Sprachbefehle definieren.
    Grundsätzlich hat man die Möglichkeit, alles selber zu definieren ("Custom Skill") oder das fertige Home Automation Skill von Amazon zu benutzen.

    Die Logik kann (Custom Skill) bzw muss (Home Automation Skill) auf https://aws.amazon.com/ implementiert werden.

    Custom Skill
    Vorteil: Mehr Flexibilität, Möglichkeit direkt https-Requests von dort aus an eigene Server schicken (aber zb. ohne http-Client-Zertifikate)
    Nachteil: Man muss alles selber definieren. Wenn ich das richtig verstanden habe muss außerdem ein weiteres "Hot-Word" wie beispielsweise "Haus" (Beispiel von ThorstenGehrig ) definieren

    Fertiges Home Automation Skill:
    Vorteil: Amazon hat viel vordefiniert, die wichtigsten Sachen laufen sehr flüssig und in verschiedenen Variation (Von: "Alexa, Wohnzimmer" an bis zu "Alexa, mach bitte das Licht im Wohnzimmer an")
    Nachteil: Es funktioniert nur mit Amazon-Lambda zusammen, außerdem muss man noch diese einmalig nervige Authentifizierung ("OAuth") machen.

    Ich habe mich für das fertige Home Automation Skill entschieden. Dazu muss man sich an zwei Amazon Seiten registrieren (developer & aws). Bei aws muss man dabei auch sofort seine Zahlugsdaten (Adresse & Kreditkarte) hinterlegen. Kostet aber nischt für unseren Zweck.
    Hier ist es gut beschrieben, obwohl ich bei meiner Einrichtung dieses wiki noch nicht kannte: http://www.fhemwiki.de/wiki/Alexa-Fhem
    Also, ich habe mich 2x registriert und das Home Automation Skills (developer) mit meiner Lambda-Funktion (aws) verknüpft.

    Kurzer Exkurs: Was macht eine Lambda-Funktion?
    Die kann bestimmt noch viel mehr, weiß ich nicht, aber in meinem Fall macht Sie genau zwei Sachen:
    - Discovery
    - Control
    Generell bekommt die Lambda einen Input-Parameter (quasi von Alexa). In der Objektstruktur dieses Parameters steht der Befehl (Discovery oder Control) und einige andere vom Befehl abhängige Parameter. Als Antwort wird auch wieder ein Objekt zurückgegeben. Bei Discovery eine Liste von Geräten, bei Control ein "ok" oder "nicht ok".
    Diese Antworten beschreibe ich kurz weiter unten.
    Die beim Discovery gefunden Geräte müssen in der Alexa einmalig "importiert" werden: "Meine Geräte suchen" (Das löst auch dann den Request zur Lambda-Funktion aus)

    Das Prinzip ist also bei mir:
    Ich rede mit Alexa, Alexa erkennt Home-Automation-Befehl und sendet das an meine Lambda-Funktion.
    Die Idee der Lambda-Funktion habe ich auch von FHEM übernommen: Die komplette Frage wird als JSON-String an meinen eigenen Webserver mit Client-Zertifikat geschickt. Client-Zertifikat bedeutet, dass nur dieser Amazon-Rechner überhaupt mit meinem Server reden darf. Dieses Client-Zertifikat ist die einzige Änderung gegenüber dem Skript von FHEM. Wie man diese Client-Zertifikate grundsätzlich erstellet, habe ich in meiner "Externer-Zugang-Fallstudie" beschrieben: https://knx-user-forum.de/forum/proj...terner-zugriff
    Als Antwort bekommt der Amazon-Rechner wieder das entsprechende Objekt via JSON zurück.

    Mein php-Skript, dass auf dem edomi Rechner läuft, antwortet also live auf Discovery Requests oder auf Controls (zb Licht schalten).
    Außerdem kommuniziert es mit der Remote-Schnittstelle von edomi.
    Das Skript liest seine "bekannten Geräte" aus einer Textdatei:
    <KO1>; <Name1>
    <KO2>; <Name2>
    KO ist dabei direkt eine Gruppenadresse (die in Edomi natürlich explizit für Fernsteuerung/remote freigeschaltet werden muss!)

    Das funktioniert jetzt soweit alles. Der Echo-Dot hat wirklich eine gute Spracherkennung. Selbst mit TV im Hintergrund noch ganz gut.
    Was jetzt noch fehlt, sind Anpassungen in meinem lokalen alexa.php-Skript, damit auch andere Geräte wie Dimmer angesprochen werden können.
    Das sollten aber nur kleine Modifikationen im alexa.php sein (Andere discoverte Geräte zurückgeben, ein wenig anders aus Control reagieren).

    Viel Spaß beim Ausprobieren,
    Steffen


    Anhänge:
    index.js (umbenennen!) ist meine Lambda-Funktion. Diese muss im ZIP mit client.crt und client.key hochgeladen werden, falls man die Client-Zertifikate benutzen will)
    alexa.php (umbenennen!) liegt lokal auf dem Edomi-Rechner bei mir wird durch Amazon aufgerufen. Dieses Skript ruft edomi-remote auf und liest meine Konfiguration aus.
    config.txt: Meine Konfiguration. KOs aus den Gruppenadressen von Edomi raussuchen und für Fernzugriff freischalten


    Als "PS:" gibt es hier noch zur Erklärung kleine Beispiele für die Kommunikation Alexa->Lambda->´mein alexa.php Skript (das Lambda leitet eigtl nur weiter, muss aber zwingend für home-automation-skill benutzt werden)

    Bei Klick auf "Meine Geräte suchen" in Amazon App gibt es discovery-Request:
    Code:
    {
    "header":{
    "namespace":"Alexa.ConnectedHome.Discovery",
    "name":"DiscoverAppliancesRequest",
    "payloadVersion":"2",
    "messageId":"06c4efaf-da9b-4deb-8561-54412400382c"
    },
    "payload":{
    "accessToken":"BLA BLA aber brauchen wir nicht(?)"
    }
    }
    Meine Antwort für Küche und Schlafzimmer. Mehr hab ich aktuell nicht, kann aber fix in der config.txt hinzugefügt werden. Im Device-Namen verstecke ich die KO-ID:
    Code:
    {
    "header":{
    "namespace":"Alexa.ConnectedHome.Discovery",
    "name":"DiscoverAppliancesResponse",
    "payloadVersion":"2"
    },
    "payload":{
    "discoveredAppliances":[
    {
    "applianceId":"device00524",
    "manufacturerName":"Steffen",
    "modelName":"ST01",
    "version":"VER01",
    "friendlyName":"Wohnzimmer",
    "friendlyDescription":"Das Licht im Wohnzimmer (device00524)",
    "isReachable":true,
    "actions":[
    "turnOn",
    "turnOff"
    ]
    },
    {
    "applianceId":"device00526",
    "manufacturerName":"Steffen",
    "modelName":"ST01",
    "version":"VER01",
    "friendlyName":"K\u00fcche",
    "friendlyDescription":"Das Licht im K\u00fcche (device00526)",
    "isReachable":true,
    "actions":[
    "turnOn",
    "turnOff"
    ]
    }
    ]
    }
    }

    Schaltbefehle bzw allgemeine Steuerungsbefehle. Im Beispiel für device00524 = KO 524 = Wohnzimmer
    Code:
    {
    "header":{
    "namespace":"Alexa.ConnectedHome.Control",
    "name":"TurnOffRequest",
    "payloadVersion":"2",
    "messageId":"81c27978-cc0c-4ae8-b1bc-09510c597a60"
    },
    "payload":{
    "accessToken":"BLA BLA BLA",
    "appliance":{
    "applianceId":"device00524",
    "additionalApplianceDetails":{
    }
    }
    }
    }
    Meine OK Antwort damit Alexa keine Fehlermeldung (sondern ein "okay") an den Benutzer ausgibt. Hier die passende TurnOffConfirmation:
    Code:
    {
    "header":{
    "namespace":"Alexa.ConnectedHome.Control",
    "payloadVersion":"2",
    "messageId":"81c27978-cc0c-4ae8-b1bc-09510c597a60",
    "name":"TurnOffConfirmation"
    }
    }
    Ich habe mich dabei grundsätzlichen an die Anleitung im Wiki von fhem gehalten. Die Client-Zertifikate möchte ich zum Testen erstmal nicht verwenden und habe daher folgende Zeilen 31 und 32 in deinem Skript auskommentiert:
    PHP-Code:
            //key:   fs.readFileSync('client.key'),  // Secret client key
            //cert:  fs.readFileSync('client.crt'),  // Public client key 
    Das Skript liegt bei mir, wie bei jonofe geschildert, im lbs-Ordner und ist extern erreichbar über folgende URL:
    https://xxxxx.selfhost.me/edomi/admin/lbs/alexa_sh.php
    und wenn ich es direkt aufrufe wird folgendes ausgegeben:
    Code:
    {"header":{"namespace":"Alexa.ConnectedHome.Discovery","name":"DiscoverAppliancesResponse","payloadVersion":"2"},"payload":{"discoveredAppliances":[{"applianceId":"devicewohnzimmer-licht","manufacturerName":"Steffen","modelName":"Model LichtDimmer","version":"VER01","friendlyName":"wohnzimmer licht","isReachable":true,"friendlyDescription":"Licht\/Dimmer im wohnzimmer licht (devicewohnzimmer-licht)","actions":["turnOn","turnOff","setPercentage","incrementPercentage","decrementPercentage"]},{"applianceId":"devicewohnzimmer-indirekt","manufacturerName":"Steffen","modelName":"Model Licht","version":"VER01","friendlyName":"wohnzimmer indirekt","isReachable":true,"friendlyDescription":"Licht im wohnzimmer indirekt (devicewohnzimmer-indirekt)","actions":["turnOn","turnOff"]}]}}
    In Lambda habe ich die Pfade auch angepasst:
    Code:
    const PORT=443;
    const HOST='xxxx.selfhost.me';
    
    // namespaces
    const NAMESPACE_CONTROL = "Alexa.ConnectedHome.Control";
    const NAMESPACE_DISCOVERY = "Alexa.ConnectedHome.Discovery";
    
    // errors
    const ERROR_TARGET_OFFLINE = "TargetOfflineError";
    const ERROR_UNSUPPORTED_OPERATION = "UnsupportedOperationError";
    const ERROR_UNEXPECTED_INFO = "UnexpectedInformationReceivedError";
    
    // entry
    exports.handler = function (event, context, callback) {
    
        log("Received Directive", JSON.stringify(event));
    
        var postData = JSON.stringify(event);
        fs =    require('fs');
        var options = {
            hostname: HOST,
            port: PORT,
            //family: 6,
            rejectUnauthorized: false,
            path: '/edomi/admin/lbs/alexa_sh.php',
            method: 'POST',
            //ca: fs.readFileSync('client.crt'),
    
            //key:   fs.readFileSync('client.key'),  // Secret client key
            //cert:  fs.readFileSync('client.crt'),  // Public client key
    
            headers: {
                'Content-Type': 'application/json',
                'Content-Length': Buffer.byteLength(postData)
            }
        };
    ...
    Der Skill ist aktiviert und taucht auch unter "Meine Smarthome Skills" bei alexa.amazon.com auf. Aber beim Suchen von neuen Geräten wird kein Logeintrag in "alexa-log.txt erzeugt und auch unter cloudwatch taucht nichts auf. Wenn ich bei AWS Lambda auf test gehe, dann taucht ein leerer response im log und cloudwatch auf, ist vermutlich i.O. da nicht richtig konfiguriert:
    Code:
    Tue, 27 Dec 2016 11:22:25 +0100 =======================================================================================================
    Tue, 27 Dec 2016 11:22:25 +0100 Request: {"key3":"value3","key2":"value2","key1":"value1"}
    Tue, 27 Dec 2016 11:22:25 +0100 -------------------------------------------------------------------------------------------------------
    Tue, 27 Dec 2016 11:22:25 +0100 Response: []
    Tue, 27 Dec 2016 11:22:25 +0100 =======================================================================================================
    Nur wie suche ich jetzt den Fehler? Hast du ein paar Tipps für mich?

    Edit: Die Screenshot von der Seite "Configuration" angehängt, passt das soweit?
    Configuration.png
    Zuletzt geändert von panzaeron; 27.12.2016, 11:45.

    #2
    Wenn Du in der Alexa App auf "Meine Geräte"/"Geräte suchen" gehst, muss das AWS Lambda aufgerufen werden. Und das siehst du im Log (teilweise ca. 10 Sekunden zeitverzögert)
    Ich bin nicht tief genug drin um den Fehler zu erkennen, aber anscheinend sind AWS und das developer dingens noch nicht korrekt verknüpft.

    Kommentar


      #3
      Hast du im AWS bei der Lambvbda function den trigger gesetzt?
      Fängt bei mir an mit:
      Alexa Smart Home
      Application Id: amzn1.ask.skill.4797418d-38........................

      Kommentar


        #4
        Jetzt geht es, der Trigger war falsch, die Geräte werden jetzt aufgeführt, danke dir...

        Kommentar

        Lädt...
        X