Update:
Dieser Post ist inzwischen überholt. FHEM Lazy ist FHEM Connector. Bitte lese den Anleitungs-Wiki
https://wiki.fhem.de/wiki/FHEM_Connector_f%C3%BCr_Amazon_Alexa.
Kurzfassung:Ich habe einen Alexa-Skill fertig, der FHEM deutlich einfacher als das bisherige Verfahren einbindet und suche Beta-Tester, die ich per Email einladen kann.
Das Ganze ist zu 90% das großartige Werk von justme1968 wie bisher, aber jetzt mit eleganterer Connectivity.
Konkrete Ziele waren, folgende Pain-Points zu beseitigen:
- Notwendigkeit, einen Port ins Internet zu öffnen (mit den entsprechenden Schwierigkeiten der Routerkonfiguration oder gar DSlite-Anschlüsse)
- Sich als Entwickler bei Amazon registrieren zu müssen
- Eigene Lambda-Funktionen zu installieren
- Einen eigenen Skill zu installieren
- Die teils etwas grottige Antwortszeit zu verbessern.
Es bleibt dabei, einen lokalen NodeJS installieren zu müssen
Bevor Ihr weiterlest:
Für die Phase 1 bis zur Veröffentlichung (bzw. Einreichung bei Amazon) suche ich ca. 10 Tester, die
- sich bewusst sind, Tester zu sein
- keine Schwierigkeiten haben, z.B. das Debug-Protokoll von SSH zu lesen, oder zu gucken, ob SSH den richtigen Key verwendet.
- nodeJS kennen
- Englisch verstehen
Perfekterweise
- läuft eigentlich schon Alexa über den eigenen Skill
- bastelst Du vielleicht sogar am HTML der Registrierungsseite mit (HTML ist nicht meine Stärke)
- bist Du bereit, den Wiki mitzuschreiben
- oder Du guckst Dir an, ob Du Sicherheitslücken findest.
Konkret gesprochen: Ich kann keinen Anfängersupport bereitstellen (Family, Firma, das übliche etc.).
Wie funktioniert es?Die Idee, die mich begeistert hat, ist der Dienst
http://serveo.net. Am besten an dieser Stelle einfach mal die Webseite aufrufen. Wenn es bei Dir dann so wie bei mir läuft: „
Genial einfache Idee, so kann man das Tunnel-Problem lösen“, dann vollziehst Du meinen „So muss man das machen“-Gedanken vor ein paar Wochen: Der Tunnel auf den heimischen PC wird über
ssh -R <anyport>:localhost:3000 zielserveriminter.netaufgebaut.
Jetzt zum Unterschied: Bei serveo.net ist damit „Dein Internet-Port“ auch wirklich im Internet. Bei mir ist das wie folgt gelöst: Bei der Aktivierung des Skills wird ein OAuth-Token von meinem Server vergeben. Endpunkt für die Lambda-Funktionen ist
https://fhem.garnix.de/alexa - für alle Nutzer. Anhand des Bearer-Tokens wird entschieden, in welchen verbundenen SSH-Reverse-Tunnel die Pakete geroutet werden. Damit gelangen also nur die TCP-Verbindungen auf Deinen Rechner, die per OAuth zu Deinem Account zugeordnet werden. Dein nodejs-Prozess hängt also nicht „offen im Internet“.
Die Authentifizierung läuft wie folgt:
Vor der Inbetriebnahme des Skills muss man sich einmal per SSH „voranmelden“.
ssh fhem.garnix.de register email=<adresse>
Die Angabe der Email ist freiwillig, allerdings halte ich es für sinnvoll, ggf. Änderungen oder gar
die Einstellung des Dienstes kommunizieren zu können. Meine Datenschutzerklärung habe ich noch nicht fertig, aber da wird dann das übliche Anständige drinstehen (keine Werbung, Weitergabe etc.)
Jetzt generiert der Server ein 64-Bit-Passwort (also einen entsprechenden Hex-String), der Dein Passwort darstellt. Gespeichert wird serverseitig nur der SHA256-Hash. Du erhälst als Antwort einen Schlüssel der Form
<Hashcode-Deines-Public-SSH-Key>-<generiertes Passwort>
Bei der Aktivierung des Skills gibst Du diesen Schlüssel an. Mein Server generiert einen Access-Code für Amazon und mit den daraus generierten Bearer-Codes weiß der Server, welches Bearer-Token zu welchem verbundenen SSH-Client gehört.
Netztechnisch spricht die Echo-Cloud also mit meiner zentralen Lambda-Funktion (im Kern unverändert, nur fischt sie das Bearer-Token aus der Requeststruktur und schreibt es standardkonform in den Header). Die Lambda-Funktion spricht mit meinem Tomcat-Webserver (ist eine normale Amazon-EC2-Instanz in Irland). Der Java-Prozess hat über Apache-MINA-SSH andererseits den SSH-Server, mit dem sich Dein Client verbindet, und routet die Requests zu Deinem Server.
Das Ganze ist deutlich flotter in der Reaktion als der klassische Weg - ich komme auf ca. 150 ms Lambda-Laufzeit versus 650 ms mit dem klassischen Weg.
Nötige Anpassungen am nodejs-Prozess (alexa-Prozess)- Der nodejs-Prozess sollte unbedingt nicht mehr im Internet stehen, denn die Validierung
der Tokens auf der lokalen Seite entfällt. - Da SSH bereits Verschlüssellung realisiert, habe ich mich gegen eine doppelte Verschlüsselung
entschieden: Der nodejs läuft auf HTTP - Die Tokenvalidierung im nodeJS muss ausgebaut werden.
Das läuft wie folgt:
In .alexa/config.json unter „Alexa“ folgendes eintragen:
...
"alexa":
...
"ssl": false,
"bind-ip": "127.0.0.1",
"trustAny": true,
...
„ssl“ und „bind-ip“ sind dabei „klassische“ Settings, „trustAny“ ist die „gefährliche Neuerung“, auf die Validieren von BearerTokens zu verzichten.
Um „trustAny“ zu verstehen, in lib/server.js die Zeile 708 wie folgt erweitern:
} else if( (token === accepted_token && Date.now() < expires) || this._config.alexa.trustAny === true) {
handler.bind(this)( event, callback );
Ich hoffe, ich habe nun abschreckend genug geschrieben, um nicht in die Verlegenheit zu kommen, npn zu erklären :-)
Ziel ist natürlich, im Laufe des Beta-Tests das Ganze bullet-proof und maximal anwenderfreundlich hinzubekommen, um die aktuelle Anleitung auf ein Drittel zu kürzen…
Bis hierhin durchgekommen und motiviert? Dann ...
Die Schritte in Kürze- Optional: Die lokale Installation von NodeJS und Alexa-FHEM gemäß Wiki, Abschnitt Installation, durchführen. Ende ist da, wo nodejs läuft und Du Dich mit Amazon rumschlagen müsstest. Alternativ hast Du Alexa-FHEM idealerweise schon fertig eingerichtet
- Auf dem User, auf dem der SSH-Prozesse laufen soll, anmelden, und
ssh fhem.garnix.de register email=xyz@abc.de
ausführen.
Geht nicht? Dann hast Du vermutlich noch keinen SSH-Key generiert.
Antwort kommt? Code wegsichern - der kommt nur einmal! - Endlosschleife für
ssh -R 1234:localhost:3000 fhem.garnix.de
installieren, am besten mit Log. Achtung: Je nach SSH-Version trennt sich SSH nach einigen Minuten idle-Time, allein dafür ist die Endlosschleife nötig. Wenn permanent neue SSH-Prozesse gestartet werden, verwendest Du offenbar für die Endlosschleife einen anderen SSH-Key als bei der Registrierung - Config von nodejs anpassen (ssl:false, etc.), siehe oben
- Code von lib/server.js anpassen, siehe oben
- nodejs-Prozess restarten
- curl http://localhost:3000/ sollte jetzt einen sinnvollen Textfehler ausspucken
- Mich anschreiben, und zwar unter gvz mit der Domain garnix.de . Formloses „bitte lade mich ein“ reicht. Dann lade ich Dich als Beta-Tester ein
- Derweil schon mal unter https://fhem.garnix.de/register/ die Seite aufrufen, zu der Du nachher bei der Anmeldung
kommst. Hier ist ein minimaler Funktionstest implementiert - Wenn die Einladung von Amazon kommt: Skill „FHEMlazy“ hinzufügen und den Schlüssel eingeben
- Über die Erfahrungen bitte hier berichten :-)
Schöne Weihnachtstage!
Georg