Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Cloud Dienste
    4. ALEXA spricht endlich beliebigen text !!!

    NEWS

    • Monatsrückblick - April 2025

    • Minor js-controller 7.0.7 Update in latest repo

    • Save The Date: ioBroker@Smart Living Forum Solingen, 14.06.

    ALEXA spricht endlich beliebigen text !!!

    This topic has been deleted. Only users with topic management privileges can see it.
    • P
      Praxxos last edited by

      @liv-in-sky:

      Nein, leider nicht.

      Nach dem Login soll ich einen Captcha im lynx eingben den ich im lynx logischerweise nicht sehen kann 😉 (soweit mir bekannt) .

      Für das Captcha Problem bei mir habe ich eine Lösung:

      • lynx wie von dir beschrieben starten und auf die Loginseite gehen.
      • User-Namen eingegeben.
      • Auf der nächsten Seite, Passwort eingegeben und das Feld "Angemeldet bleiben" nicht aktiviert.
      Wenn "Angemeldet bleiben" aktiv ist bekomme ich die Captcha Aufforderung.
      
      Wenn das Feld "Angemeldet bleiben" nicht aktiviert ist, bekomme ich via SMS den Code zugeschickt den ich dann auf der nächsten Seite eingeben kann. 
      

      Leider funktioniert es noch nicht da lynx zumindes auf Debian 9 keine Cookies per default Konfiguration speichert.

      Hab das dann mit Hilfe der Datei ./usr/share/doc/lynx-common/docs/README.cookies herausgefunden und die Konfiguration von lynx –>lynx.cfg angepasst. In der README.cookies steht was man einstellen muss.

      Wenn ich die 2 Faktor Authentifizierung deaktiviere und das cookie vom alexa_remote_control.sh (Ordner: /tmp/) mit dem von lynx (Ordner:je nach Konfiguration) von oben vergleiche und an das cookie von alexa_remote_control.sh (deaktivierte 2 Faktor Authentifizierung) anpasse kann ich mich zwar anmelden aber leider habe ich noch keine Sprachausgabe.

      Bekomme zwar keine Fehlermeldung zurück aber einen http header. In dem header steh zb. type, serial vom Dot und meine customerid.

      Hier der header den ich bekomme, gewisse Daten habe ich durch XXXXXXXXXXXXXX ersetzt (serial ist zb. der Echo Dot):

      sending cmd:speak:Test Test to dev:Badezimmer type:XXXXXXXXXXXXXX serial:XXXXXXXXXXXXXX customerid:XXXXXXXXXXXXXX
      Sequence command: Alexa.Speak
      HTTP/1.1 0 x-amzn-RequestId: XXXXXXXXXXXXXX
      Access-Control-Allow-Origin: https://alexa.amazon.de
      Content-Encoding: deflate
      Vary: Origin
      Access-Control-Expose-Headers: x-amzn-dat-gui-client-upgrade,X-Amzn-Error,loginUrl,X-Amzn-RequestId,x-amzn-alt-domain,Date,Location
      Access-Control-Allow-Credentials: true
      Date: Wed, 18 Jul 2018 XXXXXXXXXXXXXX GMT
      Connection: close
      
      

      Kommt dir oder jemand anderem das bekannt vor?

      lg & Danke Praxxos

      1 Reply Last reply Reply Quote 0
      • liv-in-sky
        liv-in-sky last edited by

        also so ganz genau verstehe ich nicht, was du da machst 😞

        bei mir funktioniert das script, nachdem ich den code eingegeben habe - ich kümmere mich garnicht um das cookie - das macht später das script.

        das captcha problem ist ja gelöst. das script kann sich wieder einloggen. vielleicht musst du erst mal das script mit "-l" laufen lassen um alles zu löschen.

        ich bin kein profi aber ich denke, es ist wichtig, das die user agent id im script und in lynx gleich sind ! amazon soll ja denken es ist das selbe login!

        bei der 2FA bin ich eh raus - kenn ich garnicht und habe ich auch nicht aktiviert - ich denke das script kann das nicht.

        bist du sicher, du hast das neuste script - mein script hat eine ganz andere ausgabe - hier eine kopie

        ! #!/bin/sh
        ! #
        ! # Amazon Alexa Remote Control
        ! # alex(at)loetzimmer.de
        ! #
        ! # 2017-10-10: v0.1 initial release
        ! # 2017-10-11: v0.2 TuneIn Station Search
        ! # 2017-10-11: v0.2a commands on special device "ALL" are executed on all ECHO+WHA
        ! # 2017-10-16: v0.3 added playback of library tracks
        ! # 2017-10-24: v0.4 added playback information
        ! # 2017-11-21: v0.5 added Prime station and playlist
        ! # 2017-11-22: v0.6 added Prime historical queue and replaced getopts
        ! # 2017-11-25: v0.6a cURL is now configurable
        ! # 2017-11-25: v0.7 added multiroom create/delete, playback of library playlist
        ! # 2017-11-30: v0.7a added US config, fixed device names containing spaces
        ! # 2017-12-07: v0.7b added Bluetooth connect/disconnect
        ! # 2017-12-18: v0.7c fixed US version
        ! # 2017-12-19: v0.7d fixed AWK csrf extraction on some systems
        ! # 2017-12-20: v0.7e moved get_devlist after check_status
        ! # 2018-01-08: v0.7f added echo-show to ALL group, TuneIn station can now be up to 6 digits
        ! # 2018-01-08: v0.8 added bluetooth list function
        ! # 2018-01-10: v0.8a abort when login was unsuccessful
        ! # 2018-01-25: v0.8b added echo-spot to ALL group
        ! # 2018-01-28: v0.8c added configurable browser string
        ! # 2018-02-17: v0.8d no need to write the cookie file on every "check_status"
        ! # 2018-02-27: v0.8e added "lastalexa" option for HA-Bridge to send its command to a specific device
        ! # (Markus Wennesheimer: https://wennez.wordpress.com/light-on-w … each-room/)
        ! # 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-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-add ... chocontrol
        ! # (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
        ! #
        ! ###
        ! #
        ! # (no BASHisms were used, should run with any shell)
        ! # - requires cURL for web communication
        ! # - (GNU) sed and awk for extraction
        ! # - jq as command line JSON parser (optional for the fancy bits)
        ! #
        ! ##########################################
        ! EMAIL='XXXXX'
        ! PASSWORD=XXXXX'
        ! LANGUAGE="de-DE"
        ! #LANGUAGE="en-US"
        ! AMAZON='amazon.de'
        ! #AMAZON='amazon.com'
        ! ALEXA='layla.amazon.de'
        ! #ALEXA='pitangui.amazon.com'
        ! # cURL binary
        ! CURL='/usr/bin/curl'
        ! # cURL options
        ! # -k : if your cURL cannot verify CA certificates, you'll have to trust any
        ! # --compressed : if your cURL was compiled with libz you may use compression
        ! # --http1.1 : cURL defaults to HTTP/2 on HTTPS connections if available
        ! OPTS='--compressed --http1.1'
        ! #OPTS='-k --compressed --http1.1'
        ! # browser identity
        ! #BROWSER='Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:99.0) Gecko/20100101 Firefox/99.0'
        ! BROWSER='Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'
        ! #BROWSER='Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36'
        ! ###########################################
        ! # nothing to configure below here
        ! #
        ! TMP="/tmp"
        ! COOKIE="${TMP}/.alexa.cookie"
        ! DEVLIST="${TMP}/.alexa.devicelist.json"
        ! GUIVERSION=0
        ! LIST/>! LOGOFF/>! COMMAND/>! TTS/>! UTTERANCE/>! SEQUENCECMD/>! STATIONID/>! QUEUE/>! SONG/>! ALBUM/>! ARTIST/>! TYPE/>! ASIN/>! SEEDID/>! HIST/>! LEMUR/>! CHILD/>! PLIST/>! BLUETOOTH/>! LASTALEXA/>! usage()
        ! {
        ! echo "$0 [-d <device>|ALL] -e <pause|play|next|prev|fwd|rwd|shuffle|vol:<0-100>> |"
        ! echo " -b [list|<"AA:BB:CC:DD:EE:FF">] | -q | -r <"station name"|stationid> |"
        ! 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>',automation:'<routine name="">'"
        ! echo " -b : connect/disconnect/list bluetooth device"
        ! echo " -q : query queue"
        ! echo " -r : play tunein radio"
        ! echo " -s : play library track/library album"
        ! echo " -t : play Prime playlist"
        ! echo " -u : play Prime station"
        ! echo " -v : play Prime historical queue"
        ! echo " -w : play library playlist"
        ! echo " -i : list imported library tracks"
        ! echo " -p : list purchased library tracks"
        ! echo " -P : list Prime playlists"
        ! echo " -S : list Prime stations"
        ! echo " -a : list available devices"
        ! echo " -m : delete multiroom and/or create new multiroom containing devices"
        ! echo " -lastalexa : print device that received the last voice command"
        ! echo " -l : logoff"
        ! echo " -h : help"
        ! }
        ! while [ "$#" -gt 0 ] ; do
        ! case "$1" in
        ! -d)
        ! if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
        ! echo "ERROR: missing argument for ${1}"
        ! usage
        ! exit 1
        ! fi
        ! DEVICE=$2
        ! shift
        ! ;;
        ! -e)
        ! if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
        ! echo "ERROR: missing argument for ${1}"
        ! usage
        ! exit 1
        ! fi
        ! COMMAND=$2
        ! shift
        ! ;;
        ! -b)
        ! if [ "${2#-}" = "${2}" -a -n "$2" ] ; then
        ! BLUETOOTH=$2
        ! shift
        ! else
        ! BLUETOOTH="null"
        ! fi
        ! ;;
        ! -m)
        ! if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
        ! echo "ERROR: missing argument for ${1}"
        ! usage
        ! exit 1
        ! fi
        ! LEMUR=$2
        ! shift
        ! while [ "${2#-}" = "${2}" -a -n "$2" ] ; do
        ! CHILD="${CHILD} ${2}"
        ! shift
        ! done
        ! ;;
        ! -r)
        ! if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
        ! echo "ERROR: missing argument for ${1}"
        ! usage
        ! exit 1
        ! fi
        ! STATIONID=$2
        ! shift
        ! # stationIDs are "s1234" or "s12345"
        ! if [ -n "${STATIONID##s[0-9][0-9][0-9][0-9]}" -a -n "${STATIONID##s[0-9][0-9][0-9][0-9][0-9]}" -a -n "${STATIONID##s[0-9][0-9][0-9][0-9][0-9][0-9]}" ] ; then
        ! # search for station name
        ! STATIONID=$(${CURL} ${OPTS} -s –data-urlencode "query=${STATIONID}" -G "https://api.tunein.com/profiles?fullTextSearch=true" | jq -r '.Items[] | select(.ContainerType == "Stations") | .Children[] | select( .Index==1 ) | .GuideId')
        ! if [ -z "$STATIONID" ] ; then
        ! echo "ERROR: no Station "$2" found on TuneIn"
        ! exit 1
        ! fi
        ! fi
        ! ;;
        ! -s)
        ! if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
        ! echo "ERROR: missing argument for ${1}"
        ! usage
        ! exit 1
        ! fi
        ! SONG=$2
        ! shift
        ! if [ "${2#-}" = "${2}" -a -n "$2" ] ; then
        ! ALBUM=$2
        ! ARTIST=$SONG
        ! shift
        ! fi
        ! ;;
        ! -t)
        ! if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
        ! echo "ERROR: missing argument for ${1}"
        ! usage
        ! exit 1
        ! fi
        ! ASIN=$2
        ! shift
        ! ;;
        ! -u)
        ! if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
        ! echo "ERROR: missing argument for ${1}"
        ! usage
        ! exit 1
        ! fi
        ! SEEDID=$2
        ! shift
        ! ;;
        ! -v)
        ! if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
        ! echo "ERROR: missing argument for ${1}"
        ! usage
        ! exit 1
        ! fi
        ! HIST=$2
        ! shift
        ! ;;
        ! -w)
        ! if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
        ! echo "ERROR: missing argument for ${1}"
        ! usage
        ! exit 1
        ! fi
        ! PLIST=$2
        ! shift
        ! ;;
        ! -l)
        ! LOGOFF="true"
        ! ;;
        ! -a)
        ! LIST="true"
        ! ;;
        ! -i)
        ! TYPE="IMPORTED"
        ! ;;
        ! -p)
        ! TYPE="PURCHASES"
        ! ;;
        ! -P)
        ! PRIME="prime-playlist-browse-nodes"
        ! ;;
        ! -S)
        ! PRIME="prime-sections"
        ! ;;
        ! -q)
        ! QUEUE="true"
        ! ;;
        ! -lastalexa)
        ! LASTALEXA="true"
        ! ;;
        ! -h|-?|–help)
        ! usage
        ! exit 0
        ! ;;
        ! )
        ! echo "ERROR: unknown option ${1}"
        ! usage
        ! exit 1
        ! ;;
        ! esac
        ! shift
        ! done
        ! case "$COMMAND" in
        ! pause)
        ! COMMAND='{"type":"PauseCommand"}'
        ! ;;
        ! play)
        ! COMMAND='{"type":"PlayCommand"}'
        ! ;;
        ! next)
        ! COMMAND='{"type":"NextCommand"}'
        ! ;;
        ! prev)
        ! COMMAND='{"type":"PreviousCommand"}'
        ! ;;
        ! fwd)
        ! COMMAND='{"type":"ForwardCommand"}'
        ! ;;
        ! rwd)
        ! COMMAND='{"type":"RewindCommand"}'
        ! ;;
        ! shuffle)
        ! COMMAND='{"type":"ShuffleCommand","shuffle":"true"}'
        ! ;;
        ! vol:
        )
        ! VOL=${COMMAND##:}
        ! # volume as integer!
        ! if [ $VOL -le 100 -a $VOL -ge 0 ] ; then
        ! COMMAND='{"type":"VolumeLevelCommand","volumeLevel":'${VOL}'}'
        ! else
        ! echo "ERROR: volume should be an integer between 0 and 100"
        ! usage
        ! exit 1
        ! fi
        ! ;;
        ! speak:
        )
        ! SEQUENCECMD='Alexa.Speak'
        ! 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'
        ! ;;
        ! 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'
        ! ;;
        ! "")
        ! ;;
        ! )
        ! echo "ERROR: unknown command "${COMMAND}"!"
        ! usage
        ! exit 1
        ! ;;
        ! esac
        ! #
        ! # Amazon Login
        ! #
        ! log_in()
        ! {
        ! ################################################################
        ! #
        ! # following headers are required:
        ! # Accept-Language (possibly for determining login region)
        ! # User-Agent (cURL wouldn't store cookies without)
        ! #
        ! ################################################################
        ! rm -f ${DEVLIST}
        ! rm -f ${COOKIE}
        ! rm -f ${TMP}/.alexa.
        .list
        ! #
        ! # get first cookie and write redirection target into referer
        ! #
        ! ${CURL} ${OPTS} -s -D "${TMP}/.alexa.header" -c ${COOKIE} -b ${COOKIE} -A "${BROWSER}" -H "Accept-Language: ${LANGUAGE}" -H "DNT: 1" -H "Connection: keep-alive" -H "Upgrade-Insecure-Requests: 1" -L
        ! https://alexa.${AMAZON} | grep "hidden" | sed 's/hidden/\n/g' | grep "value="" | sed -r 's/^.*name="([^"]+)".value="([^"]+)"./\1=\2&/g' > "${TMP}/.alexa.postdata"
        ! #
        ! # login empty to generate session
        ! #
        ! ${CURL} ${OPTS} -s -c ${COOKIE} -b ${COOKIE} -A "${BROWSER}" -H "Accept-Language: ${LANGUAGE}" -H "DNT: 1" -H "Connection: keep-alive" -H "Upgrade-Insecure-Requests: 1" -L
        ! -H "$(grep 'Location: ' ${TMP}/.alexa.header | sed 's/Location: /Referer: /')" -d "@${TMP}/.alexa.postdata" https://www.${AMAZON}/ap/signin | grep "hidden" | sed 's/hidden/\n/g' | grep "value="" | sed -r 's/^.*name="([^"]+)".value="([^"]+)"./\1=\2&/g' > "${TMP}/.alexa.postdata2"
        ! #
        ! # login with filled out form
        ! # !!! referer now contains session in URL
        ! #
        ! ${CURL} ${OPTS} -s -D "${TMP}/.alexa.header2" -c ${COOKIE} -b ${COOKIE} -A "${BROWSER}" -H "Accept-Language: ${LANGUAGE}" -H "DNT: 1" -H "Connection: keep-alive" -H "Upgrade-Insecure-Requests: 1" -L
        ! -H "Referer: https://www.${AMAZON}/ap/signin/$(awk "$0 ~/.${AMAZON}.*session-id[ \s\t]+/ {print $7}" ${COOKIE})" –data-urlencode "email=${EMAIL}" --data-urlencode "password=${PASSWORD}" -d "@${TMP}/.alexa.postdata2" https://www.${AMAZON}/ap/signin > "${TMP}/.alexa.login"
        ! # check whether the login has been successful or exit otherwise
        ! if [ -z "$(grep 'Location: https://alexa.html' ${TMP}/.alexa.header2)" ] ; then
        ! echo "ERROR: Amazon Login was unsuccessful. Possibly you get a captcha login screen."
        ! echo " Try logging in to https://alexa.${AMAZON} with your browser. In your browser"
        ! echo " make sure to have all Amazon related cookies deleted and Javascript disabled!"
        ! echo
        ! echo " (For more information have a look at ${TMP}/.alexa.login)"
        ! rm -f ${COOKIE}
        ! rm -f "${TMP}/.alexa.header"
        ! rm -f "${TMP}/.alexa.header2"
        ! rm -f "${TMP}/.alexa.postdata"
        ! rm -f "${TMP}/.alexa.postdata2"
        ! exit 1
        ! fi
        ! #
        ! # get CSRF
        ! #
        ! ${CURL} ${OPTS} -s -c ${COOKIE} -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L
        ! -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"
        ! https://${ALEXA}/api/language > /dev/null
        ! rm -f "${TMP}/.alexa.login"
        ! rm -f "${TMP}/.alexa.header"
        ! rm -f "${TMP}/.alexa.header2"
        ! rm -f "${TMP}/.alexa.postdata"
        ! rm -f "${TMP}/.alexa.postdata2"
        ! }
        ! #
        ! # get JSON device list
        ! #
        ! get_devlist()
        ! {
        ! ${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})"
        ! "https://${ALEXA}/api/devices-v2/device?cached=false" > ${DEVLIST}
        ! }
        ! check_status()
        ! {
        ! #
        ! # bootstrap with GUI-Version writes GUI version to cookie
        ! # returns among other the current authentication state
        ! #
        ! AUTHSTATUS=$(${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L https://${ALEXA}/api/bootstrap?version=${GUIVERSION} | sed -r 's/^.
        "authenticated":([^,]+),.
        $/\1/g')
        ! if [ "$AUTHSTATUS" = "true" ] ; then
        ! return 1
        ! fi
        ! return 0
        ! }
        ! #
        ! # set device specific variables from JSON device list
        ! #
        ! set_var()
        ! {
        ! DEVICE=$(echo ${DEVICE} | sed -r 's/%20/ /g')
        ! if [ -z "${DEVICE}" ] ; then
        ! # if no device was supplied, use the first Echo(dot) in device list
        ! echo "setting default device to:"
        ! DEVICE=$(jq -r '[ .devices[] | select(.deviceFamily == "ECHO" or .deviceFamily == "KNIGHT" or .deviceFamily == "ROOK" ) | .accountName] | .[0]' ${DEVLIST})
        ! echo ${DEVICE}
        ! fi
        ! DEVICETYPE=$(jq –arg device "${DEVICE}" -r '.devices[] | select(.accountName == $device) | .deviceType' ${DEVLIST})
        ! DEVICESERIALNUMBER=$(jq --arg device "${DEVICE}" -r '.devices[] | select(.accountName == $device) | .serialNumber' ${DEVLIST})
        ! MEDIAOWNERCUSTOMERID=$(jq --arg device "${DEVICE}" -r '.devices[] | select(.accountName == $device) | .deviceOwnerCustomerId' ${DEVLIST})
        ! if [ -z "${DEVICESERIALNUMBER}" ] ; then
        ! echo "ERROR: unkown device dev:${DEVICE}"
        ! exit 1
        ! fi
        ! }
        ! #
        ! # list available devices from JSON device list
        ! #
        ! list_devices()
        ! {
        ! jq -r '.devices[].accountName' ${DEVLIST}
        ! }
        ! #
        ! # execute command
        ! # (SequenceCommands by Michael Geramb and Ralf Otto)
        ! #
        ! run_cmd()
        ! {
        ! if [ -n "${SEQUENCECMD}" ]
        ! then
        ! 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
        ! ${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
        ! }
        ! #
        ! # play TuneIn radio station
        ! #
        ! play_radio()
        ! {
        ! ${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
        ! "https://${ALEXA}/api/tunein/queue-and-play?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&guideId=${STATIONID}&contentType=station&callSign=&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}"
        ! }
        ! #
        ! # play library track
        ! #
        ! 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
        ! -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 "${JSON}"
        ! "https://${ALEXA}/api/cloudplayer/queue-and-play?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}&shuffle=false"
        ! }
        ! #
        ! # play library playlist
        ! #
        ! play_playlist()
        ! {
        ! ${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 "{"playlistId":"${PLIST}","playQueuePrime":true}"
        ! "https://${ALEXA}/api/cloudplayer/queue-and-play?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}&shuffle=false"
        ! }
        ! #
        ! # play PRIME playlist
        ! #
        ! play_prime_playlist()
        ! {
        ! ${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 "{"asin":"${ASIN}"}"
        ! "https://${ALEXA}/api/prime/prime-playlist-queue-and-play?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}"
        ! }
        ! #
        ! # play PRIME station
        ! #
        ! play_prime_station()
        ! {
        ! ${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 "{"seed":"{\"type\":\"KEY\",\"seedId\":\"${SEEDID}\"}","stationName":"none","seedType":"KEY"}"
        ! "https://${ALEXA}/api/gotham/queue-and-play?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}"
        ! }
        ! #
        ! # play PRIME historical queue
        ! #
        ! play_prime_hist_queue()
        ! {
        ! ${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 "{"deviceType":"${DEVICETYPE}","deviceSerialNumber":"${DEVICESERIALNUMBER}","mediaOwnerCustomerId":"${MEDIAOWNERCUSTOMERID}","queueId":"${HIST}","service":null,"trackSource":"TRACK"}"
        ! "https://${ALEXA}/api/media/play-historical-queue"
        ! }
        ! #
        ! # show library tracks
        ! #
        ! show_library()
        ! {
        ! OFFSET="";
        ! SIZE=50;
        ! TOTAL=0;
        ! FILE=${TMP}/.alexa.${TYPE}.list
        ! if [ ! -f ${FILE} ] ; then
        ! echo -n '{"playlist":{"entryList":[' > ${FILE}
        ! while [ 50 -le ${SIZE} ] ; do
        ! ${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/cloudplayer/playlists/${TYPE}-V0-OBJECTID?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&size=${SIZE}&offset=${OFFSET}&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}" > ${FILE}.tmp
        ! OFFSET=$(jq -r '.nextResultsToken' ${FILE}.tmp)
        ! SIZE=$(jq -r '.playlist | .trackCount' ${FILE}.tmp)
        ! jq -r -c '.playlist | .entryList' ${FILE}.tmp >> ${FILE}
        ! echo "," >> ${FILE}
        ! TOTAL=$((TOTAL+SIZE))
        ! done
        ! echo "[]],"trackCount":"${TOTAL}"}}" >> ${FILE}
        ! rm -f ${FILE}.tmp
        ! fi
        ! jq -r '.playlist.trackCount' ${FILE}
        ! jq '.playlist.entryList[] | .[]' ${FILE}
        ! }
        ! #
        ! # show Prime stations and playlists
        ! #
        ! show_prime()
        ! {
        ! FILE=${TMP}/.alexa.${PRIME}.list
        ! if [ ! -f ${FILE} ] ; 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/prime/{$PRIME}?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}" > ${FILE}
        ! if [ "$PRIME" = "prime-playlist-browse-nodes" ] ; then
        ! for I in $(jq -r '.primePlaylistBrowseNodeList[].subNodes[].nodeId' ${FILE} 2>/dev/null) ; do
        ! ${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/prime/prime-playlists-by-browse-node?browseNodeId=${I}&deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}" >> ${FILE}
        ! done
        ! fi
        ! fi
        ! jq '.' ${FILE}
        ! }
        ! #
        ! # current queue
        ! #
        ! show_queue()
        ! {
        ! PARENT/>! PARENTID=$(jq –arg device "${DEVICE}" -r '.devices[] | select(.accountName == $device) | .parentClusters[0]' ${DEVLIST})
        ! if [ "$PARENTID" != "null" ] ; then
        ! 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/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 '.'
        ! }
        ! #
        ! # deletes a multiroom device
        ! #
        ! delete_multiroom()
        ! {
        ! ${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 DELETE
        ! "https://${ALEXA}/api/lemur/tail/${DEVICESERIALNUMBER}"
        ! }
        ! #
        ! # creates a multiroom device
        ! #
        ! create_multiroom()
        ! {
        ! JSON="{"id":null,"name":"${LEMUR}","members":["
        ! for DEVICE in $CHILD ; do
        ! set_var
        ! JSON="${JSON}{"dsn":"${DEVICESERIALNUMBER}","deviceType":"${DEVICETYPE}"},"
        ! done
        ! JSON="${JSON%,}]}"
        ! ${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 "${JSON}"
        ! "https://${ALEXA}/api/lemur/tail"
        ! }
        ! #
        ! # list bluetooth devices
        ! #
        ! list_bluetooth()
        ! {
        ! ${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/bluetooth?cached=false" | jq –arg serial "${DEVICESERIALNUMBER}" -r '.bluetoothStates[] | select(.deviceSerialNumber == $serial) | "(.pairedDeviceList[]?.address) (.pairedDeviceList[]?.friendlyName)"'
        ! }
        ! #
        ! # connect bluetooth device
        ! #
        ! connect_bluetooth()
        ! {
        ! ${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 "{"bluetoothDeviceAddress":"${BLUETOOTH}"}"
        ! "https://${ALEXA}/api/bluetooth/pair-sink/${DEVICETYPE}/${DEVICESERIALNUMBER}"
        ! }
        ! #
        ! # disconnect bluetooth device
        ! #
        ! disconnect_bluetooth()
        ! {
        ! ${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
        ! "https://${ALEXA}/api/bluetooth/disconnect-sink/${DEVICETYPE}/${DEVICESERIALNUMBER}"
        ! }
        ! #
        ! # device that sent the last command
        ! # (by Markus Wennesheimer)
        ! #
        ! last_alexa()
        ! {
        ! ${CURL} ${OPTS} -s -b ${COOKIE} -A "Mozilla/5.0" -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/activities?startTime=&size=1&offset=1" | jq -r '.activities[0].sourceDeviceIds[0].serialNumber' | xargs -i jq -r –arg device {} '.devices[] | select( .serialNumber == $device) | .accountName' ${DEVLIST}
        ! # Serial number: | jq -r '.activities[0].sourceDeviceIds[0].serialNumber'
        ! # Device name: | jq -r '.activities[0].sourceDeviceIds[0].serialNumber' | xargs -i jq -r –arg device {} '.devices[] | select( .serialNumber == $device) | .accountName' ${DEVLIST}
        ! }
        ! #
        ! # logout
        ! #
        ! log_off()
        ! {
        ! ${CURL} ${OPTS} -s -c ${COOKIE} -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L
        ! https://${ALEXA}/logout > /dev/null
        ! rm -f ${DEVLIST}
        ! rm -f ${COOKIE}
        ! rm -f ${TMP}/.alexa.
        .list
        ! }
        ! if [ -z "$LASTALEXA" -a -z "$BLUETOOTH" -a -z "$LEMUR" -a -z "$PLIST" -a -z "$HIST" -a -z "$SEEDID" -a -z "$ASIN" -a -z "$PRIME" -a -z "$TYPE" -a -z "$QUEUE" -a -z "$LIST" -a -z "$COMMAND" -a -z "$STATIONID" -a -z "$SONG" -a -n "$LOGOFF" ] ; then
        ! echo "only logout option present, logging off …"
        ! log_off
        ! exit 0
        ! fi
        ! if [ ! -f ${COOKIE} ] ; then
        ! echo "cookie does not exist. logging in …"
        ! log_in
        ! fi
        ! check_status
        ! if [ $? -eq 0 ] ; then
        ! echo "cookie expired, logging in again …"
        ! log_in
        ! check_status
        ! if [ $? -eq 0 ] ; then
        ! echo "log in failed, aborting"
        ! exit 1
        ! fi
        ! fi
        ! if [ ! -f ${DEVLIST} ] ; then
        ! echo "device list does not exist. downloading …"
        ! get_devlist
        ! if [ ! -f ${DEVLIST} ] ; then
        ! echo "failed to download device list, aborting"
        ! exit 1
        ! fi
        ! fi
        ! if [ -n "$COMMAND" -o -n "$QUEUE" ] ; then
        ! if [ "${DEVICE}" = "ALL" ] ; 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
        ! set_var
        ! if [ -n "$COMMAND" ] ; then
        ! echo "sending cmd:${COMMAND} to dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER} customerid:${MEDIAOWNERCUSTOMERID}"
        ! run_cmd
        ! else
        ! echo "queue info for dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER}"
        ! show_queue
        ! fi
        ! done
        ! else
        ! set_var
        ! if [ -n "$COMMAND" ] ; then
        ! echo "sending cmd:${COMMAND} to dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER} customerid:${MEDIAOWNERCUSTOMERID}"
        ! run_cmd
        ! else
        ! echo "queue info for dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER}"
        ! show_queue
        ! fi
        ! fi
        ! elif [ -n "$LEMUR" ] ; then
        ! DEVICESERIALNUMBER=$(jq –arg device "${LEMUR}" -r '.devices[] | select(.accountName == $device and .deviceFamily == "WHA") | .serialNumber' ${DEVLIST})
        ! if [ -n "$DEVICESERIALNUMBER" ] ; then
        ! delete_multiroom
        ! else
        ! if [ -z "$CHILD" ] ; then
        ! echo "ERROR: ${LEMUR} is no multiroom device. Cannot delete ${LEMUR}".
        ! exit 1
        ! fi
        ! fi
        ! if [ -z "$CHILD" ] ; then
        ! echo "Deleted multi room dev:${LEMUR} serial:${DEVICESERIALNUMBER}"
        ! else
        ! echo "Creating multi room dev:${LEMUR} member_dev(s):${CHILD}"
        ! create_multiroom
        ! fi
        ! rm -f ${DEVLIST}
        ! get_devlist
        ! elif [ -n "$BLUETOOTH" ] ; then
        ! if [ "$BLUETOOTH" = "list" -o "$BLUETOOTH" = "List" -o "$BLUETOOTH" = "LIST" ] ; then
        ! if [ "${DEVICE}" = "ALL" ] ; 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
        ! set_var
        ! echo "bluetooth devices for dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER}:"
        ! list_bluetooth
        ! done
        ! else
        ! set_var
        ! echo "bluetooth devices for dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER}:"
        ! list_bluetooth
        ! fi
        ! elif [ "$BLUETOOTH" = "null" ] ; then
        ! set_var
        ! echo "disconnecting dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER} from bluetooth"
        ! disconnect_bluetooth
        ! else
        ! set_var
        ! echo "connecting dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER} to bluetooth device:${BLUETOOTH}"
        ! connect_bluetooth
        ! fi
        ! elif [ -n "$STATIONID" ] ; then
        ! set_var
        ! echo "playing stationID:${STATIONID} on dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER} mediaownerid:${MEDIAOWNERCUSTOMERID}"
        ! play_radio
        ! elif [ -n "$SONG" ] ; then
        ! set_var
        ! echo "playing library track:${SONG} on dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER} mediaownerid:${MEDIAOWNERCUSTOMERID}"
        ! play_song
        ! elif [ -n "$PLIST" ] ; then
        ! set_var
        ! echo "playing library playlist:${PLIST} on dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER} mediaownerid:${MEDIAOWNERCUSTOMERID}"
        ! play_playlist
        ! elif [ -n "$LIST" ] ; then
        ! echo "the following devices exist in your account:"
        ! list_devices
        ! elif [ -n "$TYPE" ] ; then
        ! set_var
        ! echo -n "the following songs exist in your ${TYPE} library: "
        ! show_library
        ! elif [ -n "$PRIME" ] ; then
        ! set_var
        ! echo "the following songs exist in your PRIME ${PRIME}:"
        ! show_prime
        ! elif [ -n "$ASIN" ] ; then
        ! set_var
        ! echo "playing PRIME playlist ${ASIN}"
        ! play_prime_playlist
        ! elif [ -n "$SEEDID" ] ; then
        ! set_var
        ! echo "playing PRIME station ${SEEDID}"
        ! play_prime_station
        ! elif [ -n "$HIST" ] ; then
        ! set_var
        ! echo "playing PRIME historical queue ${HIST}"
        ! play_prime_hist_queue
        ! elif [ -n "$LASTALEXA" ] ; then
        ! last_alexa
        ! else
        ! echo "no alexa command received"
        ! fi
        ! if [ -n "$LOGOFF" ] ; then
        ! echo "logout option present, logging off …"
        ! log_off
        ! fi</routine></text></multiroom_device></playlistid></queueid></seedid></asin></trackid|'artist'></pause|play|next|prev|fwd|rwd|shuffle|vol:<0-100></device>

        mehr kann ich leider nicht für dich tun

        ach noch: manchmal muss ich einen tag waten bis wieder etws geht - frag mich bitte nicht warum

        1 Reply Last reply Reply Quote 0
        • P
          Praxxos last edited by

          😄 Das mit dem Tag warten kenne ich nur all zu gut. –> alte Programmierer Weisheit :mrgreen:

          Das Script ist bei mir aktuell.

          Bei mir leider nicht da das script die cookies unter /tmp (ist im script default) abspeichert und lynx nach der Installation überhaupt nicht.

          Erst wenn in lynx das Speichern eines cookies aktiviert wurde werden diese gespeichert.

          Hab das Problem vermutlich gefunden, im cookie vom script gibt es einen Zeile mit dem Type (sag ich jetzt mal) csrf der wird im lynx cookie nicht angelegt, eventuell hat das was mit der Konfiguration von lynx zu tun das diese Zeile nicht angelegt wird. –> Ich werde mal Mister Googel Fragen.

          Laut Google ist csrf ein Sicherheitstoken.

          @liv-in-sky: Danke für deine Hilfe!!!!!

          lg Praxxos

          1 Reply Last reply Reply Quote 0
          • liv-in-sky
            liv-in-sky last edited by

            gerne

            zum abschluss - vielleicht hatte ich nur glück

            das cookie ist bei mir völlig unwichtig - es geht eigentlich nur um das captcha (sicherheitsabfrage von amazon). ist das gelöst (mit lynx) - also code eingegeben! - hat mich amazon wieder freigegeben. damit kann das script sich wieder einloggen (weil kein captcha mehr verlangt wird) und legt alles benötigte wieder unter /tmp ab. ich selbst habe es bis jetzt noch nicht geschafft, ein richtiges/funktionierendes .alexa.cookie file zu kreiren. das cookie z.b im chrome browser ausgeledsen sieht vollkommen anders aus als das von .alexa.cookie.

            geht den alexa_remote_control.sh -a und zeigt die die devices/echos '?

            vielleicht versteh ich auch einfach auf dem schlauch. viel glück beim lösen

            1 Reply Last reply Reply Quote 0
            • N
              Nikoxx last edited by

              Guten Abend zusammen,

              ich hätte mal eine Frage auch wenn es hier nicht wirklich reingehört.

              ich lasse mir von meinem Handy über Tasker den Anrufernamen schicken und Alexa den dann ansagen. Das klappt auch alles super. Heute hat jemand angerufen den ich nicht im Telefonbuch gehabt habe. Daraufhin hat Alexa nicht die einzelnen Ziffern gesagt sondern "es ruft 49 billionen so und so tausend etc. an". Kann ich die Zahl so zerlegen das Alexa die einzelnen Ziffern vorliest.

              -Danke

              Gruss Niko

              1 Reply Last reply Reply Quote 0
              • Mic
                Mic Developer last edited by

                Hi Niko, warum postest Du dann hier obwohl es nicht hier rein gehört, wie du selber feststellst? Bitte dazu am besten separaten Beitrag eröffnen. Danke 🙂

                1 Reply Last reply Reply Quote 0
                • liv-in-sky
                  liv-in-sky last edited by

                  mache leerzeichen zwischen die nummern - müßte funktionieren

                  1 Reply Last reply Reply Quote 0
                  • apollon77
                    apollon77 last edited by

                    … oder den neuen iobroker.alexa2 nehmen ... der kann das auch :-))

                    viewtopic.php?f=37&t=15547

                    1 Reply Last reply Reply Quote 0
                    • liv-in-sky
                      liv-in-sky last edited by

                      @ appollon,

                      na du fleissiges bienchen - vielleicht erinnerst du dich an mein dilemma - adapter crash !

                      eine frage: hast du den adapter jetzt soweit neu gemacht, dass ich es nochmal probieren kann - ist z.b. das umbennen der echos bereinigt ?

                      1 Reply Last reply Reply Quote 0
                      • apollon77
                        apollon77 last edited by

                        Umbennen war schon seit einer 0.1.5 nur noch einmal berichtet aber nie wieder nachvollziehbar.

                        Das andere konnte nie ausser Dir jemand nachvollziehen. Inzwischen denke ich auch das der Adapter nicht schuld sein konnte … Jetzt ist aber alles neu - und falls jetzt nochmal passiert und DU Debug Log hast dann kann man tiefer reinschauen.

                        Ich kann kein Multiroom testen weil ich nur ein gerät habe ...

                        Also aus meiner Sicht: Nachbestem Wissen und gewissen ist alles super (auch wen diese Diskussion im falschen thread stattfindet 🙂 )

                        1 Reply Last reply Reply Quote 0
                        • liv-in-sky
                          liv-in-sky last edited by

                          ich wollte den neuen thread nicht mit meinem alten zeug vollmüllen

                          ich denke, ich werd es mal nochmal probieren - bin eh voll gespannt auf deine arbeit ! danke dafür

                          1 Reply Last reply Reply Quote 0
                          • flkontakt
                            flkontakt last edited by

                            Habe soeben den neuen Alexa Adapter installiert, läuft sehr gut, dann würde ich hier die Lautstärke nehmen. Der erste Adapter lief nicht sehr zuverlässig. Danke für die Rückmeldung! @painkillerde:

                            @flkontakt:

                            Hallo zusammen,

                            Frage zur Funktion:

                            Kann ich mehrer Geräte gleichzeitig ansprechen, ohne eine Gruppe anlegen zu müssen? Kann ich die Lautstärke vorgeben?

                            Bin für jeden Tipp dankbar!

                            Gruß, Frank

                            hardcopy.JPG `

                            Lautstärke geht problemlos mit dem Alexa Adapter. `

                            Gesendet von meinem SM-G920F mit Tapatalk

                            1 Reply Last reply Reply Quote 0
                            • P
                              Praxxos last edited by

                              @liv-in-sky:

                              gerne

                              zum abschluss - vielleicht hatte ich nur glück

                              das cookie ist bei mir völlig unwichtig - es geht eigentlich nur um das captcha (sicherheitsabfrage von amazon). ist das gelöst (mit lynx) - also code eingegeben! - hat mich amazon wieder freigegeben. damit kann das script sich wieder einloggen (weil kein captcha mehr verlangt wird) und legt alles benötigte wieder unter /tmp ab. ich selbst habe es bis jetzt noch nicht geschafft, ein richtiges/funktionierendes .alexa.cookie file zu kreiren. das cookie z.b im chrome browser ausgeledsen sieht vollkommen anders aus als das von .alexa.cookie.

                              geht den alexa_remote_control.sh -a und zeigt die die devices/echos '?

                              vielleicht versteh ich auch einfach auf dem schlauch. viel glück beim lösen `

                              Hallo liv-in-sky!

                              Ohne 2 Faktor Authentifizierung funktioniert alles, mit leider nur ein paar Tag bis das Cookie abgelaufen ist.

                              Hab mich noch einen Nachmittag damit beschäftigt, hatte aber leider kein Erfolg.

                              Daher habe ich den Adapter "alexa2" von appollon installiert, funktioniert super.

                              @appollon: Danke für den tollen Adapter!!!!

                              liv-in-sky Danke, auf jeden Fall für deine Hilfe.

                              lg Praxxos.

                              1 Reply Last reply Reply Quote 0
                              • T
                                Timur last edited by

                                @liv-in-sky:

                                @Mic

                                hi mic,

                                ich bin nicht das hellste licht im programmieren - würdest du mir bitte kurz erklären (falls kurz möglich) warum du das global machst. ich mache das ähnlich wie du aber mit einen normalen blockly - hat das einen vorteil? alexa.rede ist ein bashscript, welches das alexa_remote_control_plain.sh nutzt.

                                alexa-blockly.jpg `

                                Bin auch ein ziemlich anfänger im Programmieren…vielleicht kansnt du mir weiterhelfen?

                                Und zwar weiß ich nicht wie ich die datei oder text in das neue verzeichnis hineinkopieren soll( alexa_remote_control.sh)

                                1 Reply Last reply Reply Quote 0
                                • liv-in-sky
                                  liv-in-sky last edited by

                                  hi timor,

                                  ist alles schon lange her - ich benutze nur noch den alexa2 adapter. so auf anhieb verstehe ich deine frage nicht. kannst du das nochmal näher beschreiben? dieser thread hier war vor dem adapter - apollon hat einen tollen adapter daraus gemacht - hast du den adapter schon mal probiert? damit ist es "super" einfach alexa zum reden zu bringen

                                  1 Reply Last reply Reply Quote 0
                                  • T
                                    Timur last edited by

                                    @liv-in-sky:

                                    hi timor,

                                    ist alles schon lange her - ich benutze nur noch den alexa2 adapter. so auf anhieb verstehe ich deine frage nicht. kannst du das nochmal näher beschreiben? dieser thread hier war vor dem adapter - apollon hat einen tollen adapter daraus gemacht - hast du den adapter schon mal probiert? damit ist es "super" einfach alexa zum reden zu bringen `

                                    Also bisher habe ich es geschafft das alexa mir auch die raumtemperatur ansagt, wenn ich danach über hconnect frage. Nun möchte ich bewerkstelligen das ich eine routine draus mache z.b Alexa „Guten Morgen“ bisher werden dabei licht usw. Dann gesteuert… nun wäre es klasse, wenn sie mir dann auch automatisch die raumtemperatur sagt.

                                    1 Reply Last reply Reply Quote 0
                                    • liv-in-sky
                                      liv-in-sky last edited by

                                      zum scripten bist du im falschen thread

                                      ich würde es so machen (vielleicht geht es auch anders).

                                      einen eigenen log. datenpunkt anlegen zb. "TempLesen" (mit switch als rolle) - danach ein script (evtl blockly) welches den datenpunkt abfragt. wenn Templesen ist true, startet das script - liest den wert aus und schreibt ihn in den alexa2 adapter (da wird dann ausgegeben).

                                      TempLesen wird im cloud Adapter hinzugefügt - in alexa geräte suchen lassen. in der alexa- routine wird dann der TempLesen auf wahr gesetzt (ähnlich wie licht einschalten) -> das script startet und der alexa2 adapter gibt den wert aus.

                                      wenn du im script auf geändert reagieren möchtest, musst du im script nach einigen sekunden den TempLesen wieder auf false setzen. wenn du auf aktualisieren das script startest, brauchst du das nicht

                                      1 Reply Last reply Reply Quote 0
                                      • F
                                        firephaser last edited by

                                        Irgendwie bekomme ich den Login nicht hin. Ich habe IObroker auf einem Debian am laufen und dort das Script unter /opt/iobroker/alexa angelegt. Logindaten (User und PW) sind eingetragen und mehrfach kontrolliert. Wenn ich das Script auf dem CLI ausführe erhalte ich den Loginfehler:

                                        cookie does not exist. logging in …

                                        ERROR: Amazon Login was unsuccessful. Possibly you get a captcha login screen.

                                        Try logging in to https://alexa.amazon.de with your browser. In your browser

                                        make sure to have all Amazon related cookies deleted and Javascript disabled!

                                        (For more information have a look at /opt/iobroker/alexa-speak/.alexa.login)

                                        Ich habe dann den Login mit lynx auf der CLI probiert, leider ebenfalls ohne Erfolg, da ich kein Bild für den Capcha sehe. Dann auf dem Debian die GUI gestartet und mich mit dem Firefox auf alexa.amazon.de erfolgreich angemeldet, nachdem ich den capcha eingetragen hatte. Wieder zurück auf der CLI und das Script probiert mit leider selben Ergebnis, Fehler mit Login ist immer noch vorhanden.

                                        Was habe ich übersehen?

                                        1 Reply Last reply Reply Quote 0
                                        • liv-in-sky
                                          liv-in-sky last edited by

                                          den alexa2 adapter

                                          wie erwähnt - der alexa2 adapter regelt das alles - genau deshalb wurde er programmiert - amazon und die cookies ärgert viele, besonders mit dem script hier. wenn du glück hast läuft das alles nur 1-2 wochen, danach hast du wieder probleme mit cookies. das script wurde für reine linux user entwickelt (ohne iobroker !!) - das hier war eine notlösung

                                          bitte installiere den alexa2 adapter - mit dem scriptt hier wirst du nicht "glücklich" - der alexa2 adapter hat ab und an auch probleme mit den cookies - aber das kannst du zum einem einfach überwachen und zum anderen wird dir im log angezeigt, was du zu tun hast.

                                          1 Reply Last reply Reply Quote 0
                                          • F
                                            firephaser last edited by

                                            Danke für den Tip mit dem Adapter ALEXA2.

                                            Ich muss bei mir im Script den Eintrag für den Browser auf BROWSER='Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36' ändern, dann ging es sofort.

                                            1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post

                                            Support us

                                            ioBroker
                                            Community Adapters
                                            Donate
                                            FAQ Cloud / IOT
                                            HowTo: Node.js-Update
                                            HowTo: Backup/Restore
                                            Downloads
                                            BLOG

                                            604
                                            Online

                                            31.6k
                                            Users

                                            79.4k
                                            Topics

                                            1.3m
                                            Posts

                                            24
                                            87
                                            20658
                                            Loading More Posts
                                            • Oldest to Newest
                                            • Newest to Oldest
                                            • Most Votes
                                            Reply
                                            • Reply as topic
                                            Log in to reply
                                            Community
                                            Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                                            The ioBroker Community 2014-2023
                                            logo