Added TTS and Album play

* 2018-06-12: v0.10 introducing TTS and more
		(thanks to Michael Geramb and his openHAB2 Amazon Echo Control binding)
		https://github.com/openhab/openhab2-addons/tree/master/addons/binding/org.openhab.binding.amazonechocontrol
		(thanks to Ralf Otto for implementing this feature in this script)

* 2018-06-13: v0.10a added album play of imported library
pull/14/head
Alex 2018-06-18 17:56:30 +02:00 committed by GitHub
parent f671ba247b
commit 435fb1d124
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 138 additions and 24 deletions

View File

@ -28,6 +28,12 @@
# 2018-02-27: v0.9 unsuccessful logins will now give a short info how to debug the login # 2018-02-27: v0.9 unsuccessful logins will now give a short info how to debug the login
# 2018-03-09: v0.9a workaround for login problem, force curl to use http1.1 # 2018-03-09: v0.9a workaround for login problem, force curl to use http1.1
# 2018-05-17: v0.9b update browser string and accept language # 2018-05-17: v0.9b update browser string and accept language
# 2018-05-23: v0.9c update accept language (again)
# 2018-06-12: v0.10 introducing TTS and more
# (thanks to Michael Geramb and his openHAB2 Amazon Echo Control binding)
# https://github.com/openhab/openhab2-addons/tree/master/addons/binding/org.openhab.binding.amazonechocontrol
# (thanks to Ralf Otto for implementing this feature in this script)
# 2018-06-13: v0.10a added album play of imported library
# #
### ###
# #
@ -41,7 +47,7 @@
EMAIL='amazon_account@email.address' EMAIL='amazon_account@email.address'
PASSWORD='Very_Secret_Amazon_Account_Password' PASSWORD='Very_Secret_Amazon_Account_Password'
LANGUAGE="de,en-US" LANGUAGE="de-DE"
#LANGUAGE="en-US" #LANGUAGE="en-US"
AMAZON='amazon.de' AMAZON='amazon.de'
@ -75,9 +81,13 @@ GUIVERSION=0
LIST="" LIST=""
LOGOFF="" LOGOFF=""
COMMAND="" COMMAND=""
TTS=""
SEQUENCECMD=""
STATIONID="" STATIONID=""
QUEUE="" QUEUE=""
SONG="" SONG=""
ALBUM=""
ARTIST=""
TYPE="" TYPE=""
ASIN="" ASIN=""
SEEDID="" SEEDID=""
@ -90,13 +100,17 @@ LASTALEXA=""
usage() usage()
{ {
echo "$0 [-d <device>|ALL] -e <pause|play|next|prev|fwd|rwd|shuffle|vol:<0-100>> | -b [list|<\"AA:BB:CC:DD:EE:FF\">] | -q | -r <\"station name\"|stationid> | -s <trackID> | -t <ASIN> |" echo "$0 [-d <device>|ALL] -e <pause|play|next|prev|fwd|rwd|shuffle|vol:<0-100>> |"
echo " -u <seedID> | -v <queueID> | -w <playlistId> | -i | -p | -P | -S | -a | -m <multiroom_device> [device_1 .. device_X] | -lastalexa | -l | -h" echo " -b [list|<\"AA:BB:CC:DD:EE:FF\">] | -q | -r <\"station name\"|stationid> |"
echo " -e : run command" echo " -s <trackID|'Artist' 'Album'> | -t <ASIN> | -u <seedID> | -v <queueID> | -w <playlistId> |"
echo " -i | -p | -P | -S | -a | -m <multiroom_device> [device_1 .. device_X] | -lastalexa | -l | -h"
echo
echo " -e : run command, additional SEQUENCECMDs:"
echo " weather,traffic,flashbriefing,goodmorning,singasong,tellstory,speak:'<text>'"
echo " -b : connect/disconnect/list bluetooth device" echo " -b : connect/disconnect/list bluetooth device"
echo " -q : query queue" echo " -q : query queue"
echo " -r : play tunein radio" echo " -r : play tunein radio"
echo " -s : play library track" echo " -s : play library track/library album"
echo " -t : play Prime playlist" echo " -t : play Prime playlist"
echo " -u : play Prime station" echo " -u : play Prime station"
echo " -v : play Prime historical queue" echo " -v : play Prime historical queue"
@ -179,6 +193,11 @@ while [ "$#" -gt 0 ] ; do
fi fi
SONG=$2 SONG=$2
shift shift
if [ "${2#-}" = "${2}" -a -n "$2" ] ; then
ALBUM=$2
ARTIST=$SONG
shift
fi
;; ;;
-t) -t)
if [ "${2#-}" != "${2}" -o -z "$2" ] ; then if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
@ -286,6 +305,29 @@ case "$COMMAND" in
exit 1 exit 1
fi fi
;; ;;
speak:*)
SEQUENCECMD='Alexa.Speak'
TTS=$(echo ${COMMAND##*:} | sed -r 's/[^-a-zA-Z0-9_,?!]//g')
TTS=",\\\"textToSpeak\\\":\\\"${TTS}\\\""
;;
weather)
SEQUENCECMD='Alexa.Weather.Play'
;;
traffic)
SEQUENCECMD='Alexa.Traffic.Play'
;;
flashbriefing)
SEQUENCECMD='Alexa.FlashBriefing.Play'
;;
goodmorning)
SEQUENCECMD='Alexa.GoodMorning.Play'
;;
singasong)
SEQUENCECMD='Alexa.SingASong.Play'
;;
tellstory)
SEQUENCECMD='Alexa.TellStory.Play'
;;
"") "")
;; ;;
*) *)
@ -421,13 +463,25 @@ list_devices()
# #
# execute command # execute command
# (SequenceCommands by Michael Geramb and Ralf Otto)
# #
run_cmd() run_cmd()
{ {
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\ if [ -n "${SEQUENCECMD}" ]
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\ then
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d ${COMMAND}\ echo "Sequence command: ${SEQUENCECMD}"
"https://${ALEXA}/api/np/command?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}" COMMAND="{\"behaviorId\":\"PREVIEW\",\"sequenceJson\":\"{\\\"@type\\\":\\\"com.amazon.alexa.behaviors.model.Sequence\\\",\\\"startNode\\\":{\\\"@type\\\":\\\"com.amazon.alexa.behaviors.model.OpaquePayloadOperationNode\\\",\\\"type\\\":\\\"${SEQUENCECMD}\\\",\\\"operationPayload\\\":{\\\"deviceType\\\":\\\"${DEVICETYPE}\\\",\\\"deviceSerialNumber\\\":\\\"${DEVICESERIALNUMBER}\\\",\\\"locale\\\":\\\"${LANGUAGE}\\\",\\\"customerId\\\":\\\"${MEDIAOWNERCUSTOMERID}\\\"${TTS}}}}\",\"status\":\"ENABLED\"}"
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d ${COMMAND}\
"https://${ALEXA}/api/behaviors/preview"
else
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d ${COMMAND}\
"https://${ALEXA}/api/np/command?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}"
fi
} }
# #
@ -446,9 +500,15 @@ ${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep
# #
play_song() play_song()
{ {
if [ -z "${ALBUM}" ] ; then
JSON="{\"trackId\":\"${SONG}\",\"playQueuePrime\":true}"
else
JSON="{\"albumArtistName\":\"${ARTIST}\",\"albumName\":\"${ALBUM}\"}"
fi
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\ ${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\ -H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d "{\"trackId\":\"${SONG}\",\"playQueuePrime\":true}"\ -H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d "${JSON}"\
"https://${ALEXA}/api/cloudplayer/queue-and-play?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}&shuffle=false" "https://${ALEXA}/api/cloudplayer/queue-and-play?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}&shuffle=false"
} }
@ -707,7 +767,7 @@ if [ -n "$COMMAND" -o -n "$QUEUE" ] ; then
for DEVICE in $(jq -r '.devices[] | select( .deviceFamily == "ECHO" or .deviceFamily == "KNIGHT" or .deviceFamily == "ROOK" or .deviceFamily == "WHA") | .accountName' ${DEVLIST} | sed -r 's/ /%20/g') ; do for DEVICE in $(jq -r '.devices[] | select( .deviceFamily == "ECHO" or .deviceFamily == "KNIGHT" or .deviceFamily == "ROOK" or .deviceFamily == "WHA") | .accountName' ${DEVLIST} | sed -r 's/ /%20/g') ; do
set_var set_var
if [ -n "$COMMAND" ] ; then if [ -n "$COMMAND" ] ; then
echo "sending cmd:${COMMAND} to dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER}" echo "sending cmd:${COMMAND} to dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER} customerid:${MEDIAOWNERCUSTOMERID}"
run_cmd run_cmd
else else
echo "queue info for dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER}" echo "queue info for dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER}"
@ -717,7 +777,7 @@ if [ -n "$COMMAND" -o -n "$QUEUE" ] ; then
else else
set_var set_var
if [ -n "$COMMAND" ] ; then if [ -n "$COMMAND" ] ; then
echo "sending cmd:${COMMAND} to dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER}" echo "sending cmd:${COMMAND} to dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER} customerid:${MEDIAOWNERCUSTOMERID}"
run_cmd run_cmd
else else
echo "queue info for dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER}" echo "queue info for dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER}"

View File

@ -3,7 +3,7 @@
# Amazon Alexa Remote Control (PLAIN shell) # Amazon Alexa Remote Control (PLAIN shell)
# alex(at)loetzimmer.de # alex(at)loetzimmer.de
# #
# 2018-05-17: v0.9b (for updates see http://blog.loetzimmer.de/2017/10/amazon-alexa-hort-auf-die-shell-echo.html) # 2018-06-13: v0.10a (for updates see http://blog.loetzimmer.de/2017/10/amazon-alexa-hort-auf-die-shell-echo.html)
# #
### ###
# #
@ -16,7 +16,7 @@
EMAIL='amazon_account@email.address' EMAIL='amazon_account@email.address'
PASSWORD='Very_Secret_Amazon_Account_Password' PASSWORD='Very_Secret_Amazon_Account_Password'
LANGUAGE="de,en-US" LANGUAGE="de-DE"
#LANGUAGE="en-US" #LANGUAGE="en-US"
AMAZON='amazon.de' AMAZON='amazon.de'
@ -51,9 +51,13 @@ GUIVERSION=0
LIST="" LIST=""
LOGOFF="" LOGOFF=""
COMMAND="" COMMAND=""
TTS=""
SEQUENCECMD=""
STATIONID="" STATIONID=""
QUEUE="" QUEUE=""
SONG="" SONG=""
ALBUM=""
ARTIST=""
ASIN="" ASIN=""
SEEDID="" SEEDID=""
HIST="" HIST=""
@ -65,13 +69,17 @@ LASTALEXA=""
usage() usage()
{ {
echo "$0 [-d <device>] -e <pause|play|next|prev|fwd|rwd|shuffle|vol:<0-100>> | -b [list|<\"AA:BB:CC:DD:EE:FF\">] | -q | -r <stationid> | -s <trackID> | -t <ASIN> |" echo "$0 [-d <device>|ALL] -e <pause|play|next|prev|fwd|rwd|shuffle|vol:<0-100>> |"
echo " -u <seedID> | -v <queueID> | -w <playlistId> | -a | -m <multiroom_device> [device_1 .. device_X] | -lastalexa | -l | -h" echo " -b [list|<\"AA:BB:CC:DD:EE:FF\">] | -q | -r <\"station name\"|stationid> |"
echo " -e : run command" echo " -s <trackID|'Artist' 'Album'> | -t <ASIN> | -u <seedID> | -v <queueID> | -w <playlistId> |"
echo " -a | -m <multiroom_device> [device_1 .. device_X] | -lastalexa | -l | -h"
echo
echo " -e : run command, additional SEQUENCECMDs:"
echo " weather,traffic,flashbriefing,goodmorning,singasong,tellstory,speak:'<text>'"
echo " -q : query queue" echo " -q : query queue"
echo " -b : connect/disconnect/list bluetooth device" echo " -b : connect/disconnect/list bluetooth device"
echo " -r : play tunein radio" echo " -r : play tunein radio"
echo " -s : play library track" echo " -s : play library track/library album"
echo " -t : play Prime playlist" echo " -t : play Prime playlist"
echo " -u : play Prime station" echo " -u : play Prime station"
echo " -v : play Prime historical queue" echo " -v : play Prime historical queue"
@ -141,6 +149,11 @@ while [ "$#" -gt 0 ] ; do
fi fi
SONG=$2 SONG=$2
shift shift
if [ "${2#-}" = "${2}" -a -n "$2" ] ; then
ALBUM=$2
ARTIST=$SONG
shift
fi
;; ;;
-t) -t)
if [ "${2#-}" != "${2}" -o -z "$2" ] ; then if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
@ -245,6 +258,29 @@ case "$COMMAND" in
exit 1 exit 1
fi fi
;; ;;
speak:*)
SEQUENCECMD='Alexa.Speak'
TTS=$(echo ${COMMAND##*:} | sed -r 's/[^-a-zA-Z0-9_,?!]//g')
TTS=",\\\"textToSpeak\\\":\\\"${TTS}\\\""
;;
weather)
SEQUENCECMD='Alexa.Weather.Play'
;;
traffic)
SEQUENCECMD='Alexa.Traffic.Play'
;;
flashbriefing)
SEQUENCECMD='Alexa.FlashBriefing.Play'
;;
goodmorning)
SEQUENCECMD='Alexa.GoodMorning.Play'
;;
singasong)
SEQUENCECMD='Alexa.SingASong.Play'
;;
tellstory)
SEQUENCECMD='Alexa.TellStory.Play'
;;
"") "")
;; ;;
*) *)
@ -437,13 +473,25 @@ set_var()
# #
# execute command # execute command
# (SequenceCommands by Michael Geramb and Ralf Otto)
# #
run_cmd() run_cmd()
{ {
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\ if [ -n "${SEQUENCECMD}" ]
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\ then
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d ${COMMAND}\ echo "Sequence command: ${SEQUENCECMD}"
"https://${ALEXA}/api/np/command?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}" COMMAND="{\"behaviorId\":\"PREVIEW\",\"sequenceJson\":\"{\\\"@type\\\":\\\"com.amazon.alexa.behaviors.model.Sequence\\\",\\\"startNode\\\":{\\\"@type\\\":\\\"com.amazon.alexa.behaviors.model.OpaquePayloadOperationNode\\\",\\\"type\\\":\\\"${SEQUENCECMD}\\\",\\\"operationPayload\\\":{\\\"deviceType\\\":\\\"${DEVICETYPE}\\\",\\\"deviceSerialNumber\\\":\\\"${DEVICESERIALNUMBER}\\\",\\\"locale\\\":\\\"${LANGUAGE}\\\",\\\"customerId\\\":\\\"${MEDIAOWNERCUSTOMERID}\\\"${TTS}}}}\",\"status\":\"ENABLED\"}"
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d ${COMMAND}\
"https://${ALEXA}/api/behaviors/preview"
else
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d ${COMMAND}\
"https://${ALEXA}/api/np/command?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}"
fi
} }
# #
@ -462,9 +510,15 @@ ${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep
# #
play_song() play_song()
{ {
if [ -z "${ALBUM}" ] ; then
JSON="{\"trackId\":\"${SONG}\",\"playQueuePrime\":true}"
else
JSON="{\"albumArtistName\":\"${ARTIST}\",\"albumName\":\"${ALBUM}\"}"
fi
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\ ${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\ -H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d "{\"trackId\":\"${SONG}\",\"playQueuePrime\":true}"\ -H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d "${JSON}"\
"https://${ALEXA}/api/cloudplayer/queue-and-play?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}&shuffle=false" "https://${ALEXA}/api/cloudplayer/queue-and-play?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}&shuffle=false"
} }
@ -658,7 +712,7 @@ fi
if [ -n "$COMMAND" ] ; then if [ -n "$COMMAND" ] ; then
set_var set_var
if [ -n "$COMMAND" ] ; then if [ -n "$COMMAND" ] ; then
echo "sending cmd:${COMMAND} to dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER}" echo "sending cmd:${COMMAND} to dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER} customerid:${MEDIAOWNERCUSTOMERID}"
run_cmd run_cmd
fi fi
elif [ -n "$LEMUR" ] ; then elif [ -n "$LEMUR" ] ; then