From da697c39d1f4cafe42a03931220a932adc49378e Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 18 Jun 2018 20:26:09 +0200 Subject: [PATCH 1/4] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 33046e3..671f21b 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,8 @@ alexa-remote-control [-d |ALL] -e [device_1 .. device_X] | -lastalexa -e : run command, additional SEQUENCECMDs: - weather,traffic,flashbriefing,goodmorning,singasong,tellstory,speak:'' + weather,traffic,flashbriefing,goodmorning,singasong,tellstory, + speak:'',automation:'' -b : connect/disconnect/list bluetooth device -q : query queue -r : play tunein radio @@ -30,7 +31,7 @@ alexa-remote-control [-d |ALL] -e Date: Mon, 18 Jun 2018 20:27:31 +0200 Subject: [PATCH 2/4] Added Alexa routines execution --- alexa_remote_control.sh | 61 +++++++++++++++++++++++++---------- alexa_remote_control_plain.sh | 5 +-- 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/alexa_remote_control.sh b/alexa_remote_control.sh index f70e138..7bf8ceb 100644 --- a/alexa_remote_control.sh +++ b/alexa_remote_control.sh @@ -34,6 +34,7 @@ # 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 +# 2018-06-18: v0.10b added Alex routine execution # ### # @@ -82,6 +83,7 @@ LIST="" LOGOFF="" COMMAND="" TTS="" +UTTERANCE="" SEQUENCECMD="" STATIONID="" QUEUE="" @@ -106,7 +108,7 @@ usage() echo " -i | -p | -P | -S | -a | -m [device_1 .. device_X] | -lastalexa | -l | -h" echo echo " -e : run command, additional SEQUENCECMDs:" - echo " weather,traffic,flashbriefing,goodmorning,singasong,tellstory,speak:''" + echo " weather,traffic,flashbriefing,goodmorning,singasong,tellstory,speak:'',automation:''" echo " -b : connect/disconnect/list bluetooth device" echo " -q : query queue" echo " -r : play tunein radio" @@ -307,9 +309,13 @@ case "$COMMAND" in ;; speak:*) SEQUENCECMD='Alexa.Speak' - TTS=$(echo ${COMMAND##*:} | sed -r 's/[^-a-zA-Z0-9_,?!]//g') + TTS=$(echo ${COMMAND##*:} | sed -r 's/[^-a-zA-Z0-9_,?! ]//g' | sed 's/ /_/g') TTS=",\\\"textToSpeak\\\":\\\"${TTS}\\\"" ;; + automation:*) + SEQUENCECMD='automation' + UTTERANCE=$(echo ${COMMAND##*:} | sed -r 's/[^-a-zA-Z0-9_,?! ]//g') + ;; weather) SEQUENCECMD='Alexa.Weather.Play' ;; @@ -469,8 +475,29 @@ run_cmd() { if [ -n "${SEQUENCECMD}" ] then - echo "Sequence command: ${SEQUENCECMD}" - 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\"}" + if [ "${SEQUENCECMD}" = 'automation' ] ; then + + ${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 GET \ + "https://${ALEXA}/api/behaviors/automations" > "${TMP}/.alexa.automation" + + AUTOMATION=$(jq --arg utterance "${UTTERANCE}" -r '.[] | select( .triggers[].payload.utterance == $utterance) | .automationId' "${TMP}/.alexa.automation") + if [ -z "${AUTOMATION}" ] ; then + echo "ERROR: no such utterance '${UTTERANCE}' in Alexa routines" + rm -f "${TMP}/.alexa.automation" + exit 1 + fi + SEQUENCE=$(jq --arg utterance "${UTTERANCE}" -rc '.[] | select( .triggers[].payload.utterance == $utterance) | .sequence' "${TMP}/.alexa.automation" | sed 's/"/\\"/g' | sed "s/ALEXA_CURRENT_DEVICE_TYPE/${DEVICETYPE}/g" | sed "s/ALEXA_CURRENT_DSN/${DEVICESERIALNUMBER}/g" | sed "s/ALEXA_CUSTOMER_ID/${MEDIAOWNERCUSTOMERID}/g" | sed 's/ /_/g') + rm -f "${TMP}/.alexa.automation" + + echo "Running routine: ${UTTERANCE}" + COMMAND="{\"behaviorId\":\"${AUTOMATION}\",\"sequenceJson\":\"${SEQUENCE}\",\"status\":\"ENABLED\"}" + else + echo "Sequence command: ${SEQUENCECMD}" + 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\"}" + fi +echo $COMMAND ${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}"\ @@ -625,21 +652,21 @@ show_queue() PARENTDEVICE=$(jq --arg serial ${PARENTID} -r '.devices[] | select(.serialNumber == $serial) | .deviceType' ${DEVLIST}) PARENT="&lemurId=${PARENTID}&lemurDeviceType=${PARENTDEVICE}" fi + + ${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 GET \ + "https://${ALEXA}/api/np/player?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}${PARENT}" | jq '.' -${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 GET \ - "https://${ALEXA}/api/np/player?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}${PARENT}" | jq '.' + ${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 GET \ + "https://${ALEXA}/api/media/state?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}" | jq '.' -${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 GET \ - "https://${ALEXA}/api/media/state?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}" | jq '.' - -${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 GET \ - "https://${ALEXA}/api/np/queue?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}" | jq '.' + ${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 GET \ + "https://${ALEXA}/api/np/queue?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}" | jq '.' } # diff --git a/alexa_remote_control_plain.sh b/alexa_remote_control_plain.sh index 499242d..6dc8d8a 100644 --- a/alexa_remote_control_plain.sh +++ b/alexa_remote_control_plain.sh @@ -3,7 +3,7 @@ # Amazon Alexa Remote Control (PLAIN shell) # alex(at)loetzimmer.de # -# 2018-06-13: v0.10a (for updates see http://blog.loetzimmer.de/2017/10/amazon-alexa-hort-auf-die-shell-echo.html) +# 2018-06-18: v0.10b (for updates see http://blog.loetzimmer.de/2017/10/amazon-alexa-hort-auf-die-shell-echo.html) # ### # @@ -260,7 +260,7 @@ case "$COMMAND" in ;; speak:*) SEQUENCECMD='Alexa.Speak' - TTS=$(echo ${COMMAND##*:} | sed -r 's/[^-a-zA-Z0-9_,?!]//g') + TTS=$(echo ${COMMAND##*:} | sed -r 's/[^-a-zA-Z0-9_,?! ]//g' | sed 's/ /_/g') TTS=",\\\"textToSpeak\\\":\\\"${TTS}\\\"" ;; weather) @@ -481,6 +481,7 @@ if [ -n "${SEQUENCECMD}" ] then echo "Sequence command: ${SEQUENCECMD}" 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\"}" +echo $COMMAND ${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}"\ From a087579c3cd88bdf481a7da75e8c44bcdce2bc4a Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 18 Jun 2018 20:29:30 +0200 Subject: [PATCH 3/4] Escaped spaces in JSON --- alexa_remote_control_plain.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/alexa_remote_control_plain.sh b/alexa_remote_control_plain.sh index 6dc8d8a..1ccfffc 100644 --- a/alexa_remote_control_plain.sh +++ b/alexa_remote_control_plain.sh @@ -481,7 +481,6 @@ if [ -n "${SEQUENCECMD}" ] then echo "Sequence command: ${SEQUENCECMD}" 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\"}" -echo $COMMAND ${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}"\ From c5975dae43842e4f98dc38ac0d72530bf63b1032 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 18 Jun 2018 20:31:09 +0200 Subject: [PATCH 4/4] Added Alexa routines execution --- alexa_remote_control.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/alexa_remote_control.sh b/alexa_remote_control.sh index 7bf8ceb..6abdad9 100644 --- a/alexa_remote_control.sh +++ b/alexa_remote_control.sh @@ -497,7 +497,6 @@ if [ -n "${SEQUENCECMD}" ] echo "Sequence command: ${SEQUENCECMD}" 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\"}" fi -echo $COMMAND ${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}"\