Das IPS-Modul „Echo Remote“
Es ermöglicht die Fernsteuerung von Amazon Echo’s/Dot’s/Echo Show’s von IP-Symcon aus. Es kann Musik abspielen oder das einen Radiosender starten, gibt Sprache aus (Text to Speech) und glänzt mit vielen weiteren Funktionen, welche all die Dinge ansteuern die so ein Teil sonst noch so kann.
Damit das alles reibungslos funktioniert muss man es mit seinem Amazon Konto verbinden. Leider haben die dortigen Experten einem so manchen Stein in den Weg gelegt.
Keks oder nicht Keks, das ist hier die Frage
Initial konnte man durch Hinterlegung von Benutzername und Kennwort das schnell erledigen. Aber dann kam auch schon schnell der Ärger weil Amazon eine Art Captcha eingeführt hat. Dies wiederum konnte man durch Hinterlegung eines Cookies abwehren. Leider hielt das nur eine kurze Zeit (~ 2 Wochen) und man musste das Cookie erneuern. Meistens hat man sich gewundert warum nichts mehr geht um dann festzustellen das dass Cookie ausgelaufen ist. Was auf Dauer auch ganz schön nervte.
Findige Tüftler haben dann herausgefunden das durch Aktivierung der Zwei-Faktor-Authentisierung (2FA) man eine stabile Verbindung einrichten konnte. Jedenfalls gibt es zahlreiche Rückmeldungen das es über diesen Weg stabil funktioniert.
Leider bedeutet dieser Weg das man auch sonst im Umgang mit allen Amazon-Diensten dann die 2FA aktiviert hat. Da wir in der Familie nur einen Account haben und nutzen wollen, war jedenfalls für mich dieser Weg verbaut!
Lötzimmer und sein Token
Über den Blog (Lötzimmer) von Thorsten Gehrig bin ich schon vor längerem auf sein BASH-Shell-Script „alexa-remote-control.sh“ gestoßen. Es konnte schon damals paar Dinge die im Modul erst später kamen.
Ende des letzten Jahres veröffentlichte er einen Beitrag wo er beschreibt, wie mittels eines Tokens – ähnlich einer mobilen App – das Thema Login & Cookie gelöst wird.
Nachdem ich es im Zusammenspiel mit dem Schell-Skript ausprobiert hatte, kam mir der Gedanke beides miteinander zu verbinden. also das Login bzw. die Cookie-Erstellung vom Skript erledigen zu lassen und dieses dann im Modul zu nutzen.
Wie geht das?
Um die Kombination ans Laufen zu bekommen sind mehrere Schritte notwendig. Für den geübten Tüftler/Basteler/Programmierer sollte das kein größeres Problem darstellen. Grob gesagt sind folgende 4 Schritte notwendig:
- Installation des Alexa-Remote-Control.sh BASH Skriptes
- Erzeugen und Hinterlegen des REFRESH_TOKENs
- Einbinden des Shell-Skriptes in IPS
- Modifizieren bzw. Patchen des Echo Remote Moduls
Hinweis!
Als Grundlage der Anleitung dient meine zugrundeliegende Infrastruktur, d.h. IPS läuft auf einem Rasberry Pi (auf welchem eine frisch installierte Bullseye Debian-Version läuft).
(1) Alexa Remote Control
Ich habe mich entschieden das Shell-Skript unterhalb des „user“-Ordners zu installieren. Kann man gern anders machen, aber dann entsprechend in allen darauffolgenden Konfigurationsanweisungen selber drauf achten! Der einfachste Weg ist sich per SSH auf dem PI einzuloggen und die gleichen Befehle abzusetzen wie in der nachfolgenden Sequenz.
pi:~ $ cd /var/lib/symcon/webfront/user
pi:/var/lib/symcon/webfront/user $ sudo mkdir alexa
pi:/var/lib/symcon/webfront/user $ cd alexa
pi:/var/lib/symcon/webfront/user/alexa $ sudo wget https://loetzimmer.de/patches/alexa_remote_control.sh
--2022-03-27 16:47:21-- https://loetzimmer.de/patches/alexa_remote_control.sh
Auflösen des Hostnamens loetzimmer.de (loetzimmer.de)… 136.243.37.218
Verbindungsaufbau zu loetzimmer.de (loetzimmer.de)|136.243.37.218|:443 … verbunden.
HTTP-Anforderung gesendet, auf Antwort wird gewartet … 200 OK
Länge: 54129 (53K) [text/x-sh]
Wird in »alexa_remote_control.sh« gespeichert.
alexa_remote_control.sh 100%[===============================================================================>] 52,86K --.-KB/s in 0,02s
2022-03-27 16:47:22 (2,48 MB/s) - »alexa_remote_control.sh« gespeichert [54129/54129]
pi:/var/lib/symcon/webfront/user/alexa $ ls -la
insgesamt 64
drwxr-xr-x 2 root root 4096 27. Mär 16:47 .
drwxrwxrwx 5 root root 4096 27. Mär 16:46 ..
-rw-r--r-- 1 root root 54129 4. Feb 22:01 alexa_remote_control.sh
pi:/var/lib/symcon/webfront/user/alexa $ sudo chmod a+x alexa_remote_control.sh
pi:/var/lib/symcon/webfront/user/alexa $ ll
insgesamt 64
drwxr-xr-x 2 root root 4096 27. Mär 16:47 .
drwxrwxrwx 5 root root 4096 27. Mär 16:46 ..
-rwxr-xr-x 1 root root 54129 4. Feb 22:01 alexa_remote_control.sh
pi:/var/lib/symcon/webfront/user/alexa $
Mittels 5 einfacher Befehle sollte das Skript installiert sein. Mittels des Aufrufes ./alexa_remote_control.sh -h
bekommt man die Hilfe und kann gleichzeitig testen ob es funktioniert!
Zusammenfassung (Befehle)
cd /var/lib/symcon/webfront/user/
sudo mkdir alexa
cd alexa
sudo wget https://loetzimmer.de/patches/alexa_remote_control.sh
sudo chmod a+x alexa_remote_control.sh
JQ – JSON processor
Das SKript setzt die Installation des Json Prozessors (jq) vorau!
Falls nicht schon installiert => sudo apt install -y jq
(2) Erzeugen des REFRESH_TOKENs
Das Erzeugen des Tokens ist eigentlich sehr gut in dem erwähnten Beitrag beschrieben. Ich habe dazu das Windows-CLI-Programm auf meinen Windows-Laptop heruntergeladen und die beschriebenen Schritte ausgeführt (muss man auch nur einmal machen:
- Starten von alexa-cookie-cli-<linux|macos|windows> auf der Kommandozeile (wichtig, weil sich sonst das Kommandfenster schließen könnte!!!)
- Im Browser
http://localhost:8080/
aufrufen. - Bei Amazon anmelden
- Nach erfolgreicher Anmeldung beendet sich das Programm und gibt den REFRESH_TOKEN auf der Kommandozeile aus (z.B. Atnr|…)
Den so erzeugten Token schön aufheben – wir brauchen ihn gleich!
(3) „Broker“-Skript für Einbindung in IPS
Diesen Schritt könnte man sich bestimmt sparen, aber er ist außerordentlich nützlich um flexibel auf Updates des Originalskriptes reagieren zu können und die Logindaten (hier der Token) vom Skript zu trennen. Spart einiges an Konfigurationsaufwand. Weil – man kann dem Skript den Token auch über eine Umgebungsvariablen mitgeben. Somit muss man am Control-Skript nichts „anfassen“.
Jetzt zum Skript – man legt einfach im Verzeichnis von IPS ein neues Skript alexa.sh
mit folgendem Inhalt an:
#!/bin/bash
# github raw download url
URL="https://loetzimmer.de/patches/alexa_remote_control.sh"
# output directory prefix
DIR="/var/lib/symcon/webfront/user/alexa/"
# remote script
EXE="alexa_remote_control.sh"
# cookie file
COF="$(dirname "$(readlink -e "$0")")/alexa_cookie.txt"
TMP="/tmp/.alexa.cookie"
# process step
if [[ $1 == "-u"|| $1 == "--update" ]]
then
DO="update"
elif [[ $1 == "-r" || $1 == "--refresh" ]]
then
DO="refresh"
else
echo -e "Usage: alexa.sh [options]\n\nOptionen: \n -u oder --update \n -r oder --refresh"
fi
# execution
if [[ $DO == "update" ]]
then
wget -N -P $DIR $URL
fi
if [[ $DO == "refresh" ]]
then
REFRESH_TOKEN="<DEIN REFRESH TOKEN HIER REINKOPIEREN>"
export REFRESH_TOKEN;
$DIR$EXE -login
if [ ! -L "$COF" ]; then
if [ -e "$COF" ]; then
rm $COF
fi
ln -s "$TMP" "$COF"
fi
fi
Dann noch das Skript ausführbar machen (chmod) und alles immer schön als root-User machen!
Zusammenfassung (Befehle)
cd /var/lib/symcon/
sudo nano alexa.sh
# Inhalt von oben reinkopieren …
# Eigenen Token an der richtigen Stelle im Skript einsetzen …
# mit Strg+X speichern und Editor verlassen
sudo chmod a+x alexa.sh
Dannach kann man das neue Skript mit den Parametern „-u | –update“ oder „-r | –refresh“ aufrufen. Update lädt die neueste Version des Control-Skriptes herunter. Refresh versucht sich bei Amazon einzuloggen und legt ein neues Cookie ins /tmp Verzeichnis. Wenn alles fehlerfrei funktioniert, sollte ein Verzeichnislisting ungefähr so aussehen.
pi:/var/lib/symcon $ ls -la
insgesamt 7728
drwxrwxrwx 12 root root 4096 25. Mär 16:24 .
drwxr-xr-x 59 root root 4096 27. Feb 15:33 ..
drwxrwxrwx 2 root root 4096 25. Mär 00:04 backup
drwxr-xr-x 2 root root 4096 27. Feb 17:35 cams
drwxrwxrwx 2 root root 4096 26. Apr 2017 cert
drwxrwxrwx 9 root root 36864 21. Mär 00:00 db
drwxrwxrwx 3 root root 4096 27. Feb 17:40 media
drwxrwxrwx 2 root root 4096 27. Feb 17:40 minidump
drwxrwxrwx 4 root root 4096 11. Mär 17:33 modules
drwxrwxrwx 6 root root 20480 23. Mär 17:03 scripts
drwxrwxrwx 3 root root 4096 23. Mär 16:53 session
drwxrwxrwx 4 root root 4096 24. Mär 2018 webfront
lrwxrwxrwx 1 root root 18 27. Feb 17:43 alexa_cookie.txt -> /tmp/.alexa.cookie
-rw-rw-rw- 1 root root 27189 16. Nov 09:54 alexa_login.html
-rwxr-xr-x 1 root root 1190 4. Nov 09:48 alexa.sh
-rw-rw-rw- 1 root root 699 23. Mär 16:53 php.ini
-rw-rw-rw- 1 root root 7757656 25. Mär 16:15 settings.json
pi:/var/lib/symcon $
Wie man sehen kann, gibt es eine Datei und einen Link mit Bezug zu alexa. Warum? Das IPS Modul legt für den Login 2 Dateien an (alexa_cookie.txt & alexa_login.html). Damit das Cookie vom Control-Skript genutzt wird, welches unter /tmp/.alexa.cookie
abgelegt ist – löscht das „Broker-Skript“ die Datei vom Modul und verlinkt es mit diesem.
(4) Skripte und zyklisches Ereignis in IPS
Das so erzeugte Shell-Skript (alexa.sh
) lass ich nun in IPS aller halber Stunde aufrufen.
<?php
################################################################################
# Scriptbezeichnung: Alexa.Login.ips.php
# Version: 1.0.20211102
# Author: Heiko Wilknitz
#
# Kombi von Alexa Remote Modul und BASH Script für alexa_remote_control.sh
#
# ------------------------------ Konfiguration ---------------------------------
#
# Amazon Echo IO Instanz
$oid = #####;
# Parameter -r --refresh
$cmd = './../alexa.sh -r';
#
################################################################################
$ret = ECHOIO_CheckLoginStatus($oid);
if ($ret) {
return;
}
$ret = exec("$cmd", $out, $rc);
$ret = ECHOIO_CheckLoginStatus($oid);
if (!$ret) {
IPS_LogMessage("ALEXA", print_r($out, true));
}
################################################################################
?>
I/O Instance
In den Skripten immer die $oid durch die eigene Instanz-ID ersetzen!
Sie steht unter den I/O-Instanzen und der Name sieht ähnlich diesem aus:
AmazonEchoIO (AmazonEchoConfigurator #12345)!
(5) Echo Remote Modul Patch
Leider funktioniert das Ganze nicht ohne 2 kleine Änderungen am Modul – sorry dafür!
In der Datei "/var/lib/symcon/modules/.store/fonzo.ipsymconechoremote/Echo IO/module.php
“ muss in der Funktion LogIn() gleich ein return CheckLoginStatus() rein (HW insert):
public function LogIn(): bool
{
$this->SendDebug(__FUNCTION__, '== started ==', 0);
return $this->CheckLoginStatus(); // HW insert
if ($this->ReadPropertyBoolean('UseCustomCSRFandCookie')) {
return $this->CheckLoginStatus();
}
Die zweite Anpassung betrifft die Funktion CheckLoginStatus() selbst. Dort muss am Ende ein SetStatus rein (HW insert! Das ist nicht die feine Art, aber der Zweck heiligt die Mittel 🙂
public function CheckLoginStatus(): bool
{
$this->SendDebug(__FUNCTION__, '== started ==', 0);
// ....
if (!$authenticated) {
$this->SetBuffer('customerID', '');
$this->SetStatus(self::STATUS_INST_NOT_AUTHENTICATED);
}
else {
if($this->GetStatus() != IS_ACTIVE) { //HW: insert
$this->SetStatus(IS_ACTIVE);
}
}
return $authenticated;
}
Hinweis
Die Datei ist nicht gerade klein, deshalb hier die Zeilennummern wo die Patches ungefähr hin müssen: (1) ab Zeile 205 – (2) ab Zeile 300
(6) Abschlussarbeiten
Zusätzlich habe ich mir noch 3 kleine Skripte in IPS geschrieben und ins Webfront gelegt um bei Problemen schnell und direkt reagieren zu können.
Check Login Status – fragt einfach nur den Login-Status ab und gibt ihn aus
<?php
################################################################################
# Scriptbezeichnung: Alexa.CheckLogin.ips.php
# Version: 1.0.20211017
# Author: Heiko Wilknitz
#
# Call Proxy Script für alexa_remote_control.sh
#
# ------------------------------ Konfiguration ---------------------------------
#
# Amazon Echo IO
$oid = #####;
#
################################################################################
$ret = ECHOIO_CheckLoginStatus($oid);
if ($ret) {
echo 'Sie sind angemeldet';
}
else {
echo 'Sie sind nicht angemeldet.';
}
################################################################################
?>
Referesh Login Token – startet ein manuelles Erzeugen des Cookies
<?php
################################################################################
# Scriptbezeichnung: System.RefreshToken.ips.php
# Version: 1.0.20211017
# Author: Heiko Wilknitz
#
# Call Proxy Script für alexa_remote_control.sh
#
# ------------------------------ Konfiguration ---------------------------------
#
# Parameter -r --refresh
$cmd = './../alexa.sh -r';
#
################################################################################
$ret = exec("$cmd", $out, $rc);
//var_dump($ret); // last output line
//var_dump($rc); // int(0)
foreach ($out as $line) {
echo $line.'<br />';
}
################################################################################
?>
Update Control Script – prüft und lädt bei neuer Version das Control-Skript herunter!
<?php
################################################################################
# Scriptbezeichnung: System.UpdateScript.ips.php
# Version: 1.0.20211017
# Author: Heiko Wilknitz
#
# Call Proxy Script für alexa_remote_control.sh
#
# ------------------------------ Konfiguration ---------------------------------
#
# Parameter -u --update
$cmd = './../alexa.sh -u 2>&1';
#
################################################################################
$ret = exec("$cmd", $out, $rc);
//var_dump($ret); // last output line
//var_dump($out); // int(0)
//var_dump($rc); // int(0)
foreach ($out as $line) {
echo $line.'<br />';
}
################################################################################
?>
Fazit
Es ist schon etwas an Arbeit das Zusammenspiel von Shell-Skript und IPS-Modul fehlerfrei zu realisieren, aber für mich hat sich der Aufwand gelohnt. Seit dieser Zeit habe ich Ruhe und die Familie ist im Notfall auch in der Lage übers Webfront die Lösung herbeizuführen.
4 Kommentare
Peter · 30. März 2022 um 19:43
Zusammenfassung (Befehle)
cd /var/lib/symcon/webfront/ <—– fehlt hier nicht noch ein: sudo mkdir user & cd /user?
sudo mkdir alexa
Heiko · 31. März 2022 um 9:00
Hi Peter,
danke für Dein richtigen Hinweis. Da fehlt wirklich das „user“ – nur man muss es normalerweise nicht erzeugen, sondern sollte schon da sein! Ich verbessere es.
Danke Heiko
Jan S. · 7. Februar 2023 um 19:50
Nur ganz kurz zu Deiner folgenden Aussage:
„[..] . Da wir in der Familie nur einen Account haben und nutzen wollen, war jedenfalls für mich dieser Weg verbaut! [..]“
Du kannst den initialen generierten Setup 2FA Code / QR-Code parallel auf so vielen Geräten wie möglich nutzen. So kann jeder aus der Familie mit seinen eigenen Geräten ein und denselben Amazon Account zum Shoppen verwenden.
Heiko · 23. Februar 2023 um 12:08
Hi Jan,
danke – das ist ja interessant, auch wenn ich es noch nicht wirklich verstehe. Bekommen dann beim Loginversuch alle eine Meldung auf ihr Handy – oder woher will er wissen wer sich gerade anmeldet? Werde mal recherchieren 😉