Ankündigung

Einklappen
Keine Ankündigung bisher.

Amazon Echo - Lautsprecher von amazon mit Alexa Spracherkennung

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

    #31
    Moin zusammen,

    ich bin zwar noch Neuling mit Alexa, aber habe das System schon rudimentär an Edomi angebunden.

    Ich beschreibe mal kurz meinen aktuellen Stand:

    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"
       }
    }
    Angehängte Dateien
    Zuletzt geändert von steffen79; 13.11.2016, 08:41.

    Kommentar


      #32
      Coole Wurst, sieht hammer aus. Muss ich mir mal in Ruhe noch genauer anschauen. Möglicherweise kann ich das portieren in SmarHome.py. Ich finde es gut, dass du das config File auslagerst. So muss sich der Benutzer nur um seine "ITEMS" (in smarthome Sprache) kümmern und nicht um den Mechanismus.

      Danke mal für die Vorarbeit.
      Könnte ich eventuell mal auf dich zukommen, wenn ich Fragen dazu habe?

      Grüße,
      Patrick

      Kommentar


        #33
        Moin, na klar kannst Du gerne fragen. Aber ruhig im Forum, dann haben alle was davon. Bin aber wie gesagt im Prinzip noch Neuling und habe habe auch kein SmartHome sondern Edomi...
        Joa wollte die GrundKonfig auch möglichst klein, flexibel und überschaubar in einer separaten Datei haben.
        Da werd ich später noch ein Feld/Spalte für Typ (Licht an/aus, Dimmer, <was auch immer Alexa kann>) zufügen...

        Gruß,
        Steffen

        Kommentar


          #34
          Okay ich hab mir das jetzt mal etwas genauer angeschaut. Sehe ich das richtig, dass deine Anfrage einfach nur zusammengebaut wird und du nachher einen POST auf http://hostort/remote... machst? Kann ich das vielleicht dann auch so zusammenbauen mit der smarthome network API? Diese nutzt folgendes Format:

          http://iport/item|PFAD.DES.ITEMS|1 (1 für an, 0 für aus).

          Meinst du man kann das einfach portieren?

          Ich müsste dann doch meine Lampen praktisch nur so angeben:

          Gruppenadresse; EG.Wohnzimmer.Lampe.Schalten

          zum Beispiel.

          Danke mal vorab für den Denkanstoß.

          Grüße,
          Patrick

          Kommentar


            #35
            Ja das sollte sehr einfach portierbar sein.
            Wie du erkannt hast sendet mein lokales Alexa nur per GET einen Wert in der Prozedur setValue.
            Da mütest Du vor allem die Zeile
            PHP-Code:
            $out "GET $url?".implode($params'&')." HTTP/1.1\r\n"
            und die Parameter
            PHP-Code:
            urlencode('login')."=".urlencode('remote'),
            urlencode('pass')."=".urlencode('remote'),
            urlencode('koid')."=".urlencode($koId),
            urlencode('kovalue')."=".urlencode($koValue
            anpassen. Falls Du mehr Informationen speichern musst eben noch den Aufbau der config datei und das entsprechende einlesen:

            PHP-Code:
            foreach ($configLines as $line) {
                    if (
            trim($line)!="") {
                        
            $subStrings explode(';'$line);
                        if (
            count($subStrings)==2) {
                            
            $koConfig[trim($subStrings[0])*1]=trim($subStrings[1]);
                        }
                    }
                } 
            Gruß,
            Steffen

            Kommentar


              #36
              HI Steffen,
              hut ab und danke für das Code veröffentlichen.
              Was mir echt noch fehlt ist der Weg Alexa fernzusteuern (z.B. automatisch Musik an wenn man ins Bad geht - oder ausschalten wenn man das Bad verlassen hat).
              Hast du da schon was gefunden?
              Ich denke bisher geht nur: wav-dateien mit dem gesprochenen Befehl an Amazon schicken. Nicht sonderlich "smart" - aber wenigstens mal ein Weg... Leider habe ich das noch nicht umgesetzt bekommen...
              Irgendwelche Ideen dazu?

              Gruß
              Thorsten

              Kommentar


                #37
                Hi Thorsten,

                ne sorry ich habe da noch keinen Weg gefunden (aber auh noch nicht lange gesucht) um Alexa derart fernzusteuern.
                Habe aber auch nur den Dot, daher werd ich den eh nicht zum Musik abspielen verwenden...

                Anbei meine aktualisierte Version, diese kann jetzt auch Dimmen und Heizung einstellen.
                Das config-Format wurde dafür geändert, siehe Beispiel...


                Gruß,
                Steffen
                Angehängte Dateien

                Kommentar


                  #38
                  Mir scheint dein Quellcode immer klarer zu werden. Was ich noch nicht ganz verstehe sind die 3 ersten Funktionen readConfig, setVlaue und getValue. Mir ist hier noch nicht ganz klar geworden, wie ich das wohl auf meinen Anwendungsfall umbiegen kann. Außerdem ist mir noch nicht ganz klar, wie die Gesamtkommunikation funktioniert.

                  Du hast also einen Apache und der hat die alexa.php drauf. Du machst also ne virtual site und fragst ein Client Zertifikat ab, das du deiner Lambda Funktion mitgegeben hast.
                  Dann verweist du in der virtual site auf die alexa.php als index und die verarbeitet dann das JSON, was die Lambda Funktion liefert?

                  Und die Möglichkeiten, die die alexa.php vorgibt sind also alle Items, die in der config.txt stehen?

                  Das heißt ich muss nur das trimming und exploding, so wie die Host Parameter auf das Network Plugin von SmartHome umbiegen?
                  Das sollte machbar sein denke ich.

                  Kommentar


                    #39
                    Ja ich hab nen Apache, der direkt über den Router von aussen auf Port 443 erreichbar ist. Dieser Apache läßt aber nur Verbindungen mit https und ganz bestimmten Client-Zertifikaten zu. Amazon-Lambda (eigenes Skript, siehe oben, das die Client-Zertifikate benutzt) schickt Anfragen an meinen apache (mit alexa.php) und bekommt auch die Antworten von da.
                    readConfig parst nur die Konfigurationsdatei und speichert sie in einem Array-Objekt.
                    getValue und setValue sind "dumme" Funktionen die einen Wert an edomi schreiben bzw von dort lesen. Diese müsstest Du ändern, das config.txt auch ein wenig, falls Du für SH mehr als nur einfach Zahlen benötigst.

                    Kommentar


                      #40
                      Okay habe ich soweit verstanden. Das wird sicherlich eine Gewaltsaufgabe für mich, da ich im Programmieren nicht so der Oberprofi bin. Aber ich denke mit etwas Gehirnschmalz und ein wenig Zeit werde ich das schon portiert bekommen Sollte es was Neues zu deinem Plugin geben wäre ich dir dankbar, wenn du das mit uns teilen könntest.

                      Grüße,
                      Patrick

                      Kommentar


                        #41
                        Mach ich irgendwas falsch? Hab jetzt nen Apache2 aufgesetzt und mit Client Zertifikat Auth versehen. Und dann habe ich die alexa.php hinterlegt und die index.js mit dem crt und dem key hochgeladen. Dann habe ich das auf meine dyndns angepasst.

                        Wenn ich nun ein Discovery hinschicke meldet die AWS Console

                        Code:
                         
                         START RequestId: ae7e548e-ac04-11e6-9724-83b11e870fa2  Version: $LATEST  2016-11-16T13:57:58.996Z	ae7e548e-ac04-11e6-9724-83b11e870fa2	Received Directive: {"header":{"namespace":"Alexa.ConnectedHome.Discovery","name":"DiscoverAppliancesRequest","payloadVersion":"2","messageId":"06c4efaf-da9b-4deb-8561-54412400382c"},"payload":{"accessToken":"BLA BLA aber brauchen wir nicht(?)"}}  2016-11-16T13:57:59.958Z	ae7e548e-ac04-11e6-9724-83b11e870fa2	STATUS: 400  2016-11-16T13:57:59.958Z	ae7e548e-ac04-11e6-9724-83b11e870fa2	HEADERS: {"date":"Wed, 16 Nov 2016 13:57:59 GMT","server":"Apache/2.4.10 (Debian)","content-length":"316","connection":"close","content-type":"text/html; charset=iso-8859-1"}  2016-11-16T13:57:59.998Z	ae7e548e-ac04-11e6-9724-83b11e870fa2	No more data in response.  2016-11-16T13:57:59.998Z	ae7e548e-ac04-11e6-9724-83b11e870fa2	Response: : <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">  <html><head> <title>400 Bad Request</title> </head><body> <h1>Bad Request</h1> <p>Your browser sent a request that this server could not understand.<br /> </p> <hr> <address>Apache/2.4.10 (Debian) Server at virtual.heneronline.de Port 8080</address> </body></html>  2016-11-16T13:58:00.057Z	ae7e548e-ac04-11e6-9724-83b11e870fa2	SyntaxError: Unexpected token <     at Object.parse (native)     at IncomingMessage.<anonymous> (/var/task/index.js:51:20)     at emitNone (events.js:72:20)     at IncomingMessage.emit (events.js:166:7)     at endReadableNT (_stream_readable.js:905:12)     at nextTickCallbackWith2Args (node.js:437:9)     at process._tickDomainCallback (node.js:392:17) END RequestId: ae7e548e-ac04-11e6-9724-83b11e870fa2 REPORT RequestId: ae7e548e-ac04-11e6-9724-83b11e870fa2	Duration: 1237.84 ms	Billed Duration: 1300 ms 	Memory Size: 128 MB	Max Memory Used: 7 MB	 Process exited before completing request
                        Ich habe zwar noch nicht das Parsing angepasst, aber ich hätte wenigstens eine Antwort von meinem Server erwartet. Kann ich das Script irgendwie anders testen, als von AWS aus?

                        Kommentar


                          #42
                          Code 400 heiß BAD REQUEST.
                          Ich würde folgende Reihenfolge testen:
                          Geht Dein https mit client-auth? Teste lokal im Netz
                          Geht Dein https mit client-auth von extern (router ok)? Teste von extern, zb über handy
                          Geht alexa? Nimm den test-string, pack den (recht weit unten) in die Variable $postdata. Ruf alexa.php zum test von kommandozeile auf (php alexa.php) und/oder über webbrowser.

                          Irgendwo da sollte es schon haken....

                          Kommentar


                            #43
                            beide https Verbindungen gehen ohne Problem.

                            Das Testszenario solltest du mir nochmal genauer beschreiben. Ich soll den Teststring wohin packen und das wie aufrufen!?
                            Danke und Grüße,
                            Patrick

                            Kommentar


                              #44
                              Wenn ich auf der CLI php5 alexa.php aufrufe bekomme ich folgende Ausgabe (ohne dass ich irgendeinen String angepasst habe)

                              Code:
                              {"header":{"namespace":"Alexa.ConnectedHome.Discovery","name":"DiscoverAppliancesResponse","payloadVersion":"2"},"payload":{"discoveredAppliances":[{"applianceId":"deviceTest","manufacturerName":"Patrick","modelName":"Model LichtDimmer","version":"VER01","friendlyName":"Test","isReachable":true,"friendlyDescription":"Licht\/Dimmer im Test (deviceTest)","actions":["turnOn","turnOff","setPercentage","incrementPercentage","decrementPercentage"]}]}}
                              Das passt so halbwegs zu meiner Testconfig (config.txt)

                              Kommentar


                                #45
                                Ja sieht doch gut aus, dann läuft auf der Seite doch alles?
                                Dann trigger doch mal über alexa die lambda funktion und schau mal was dein alexa-log.txt bei dir anzeigt und vergleich nochmal die aws logs
                                Hast Du vielleicht doch was mit http bzw https verwechselt?
                                aws sollte nach meinem vorschlag ja über https und client zertifikat laufen.
                                Was sagen Deine apache log files?

                                Kommentar

                                Lädt...
                                X