#!/usr/bin/env bash # castanet.sh: Script to connect a chromecast to a WiFi network. # # Allows you to put your Chromecast on WiFi and do Chromecast initial setup # without using the Google Home app at all, just using a normal Linux computer. # # You do need your Chromecast to be on Ethernet, or (untested) to join its setup WiFi # network with your PC, and you also need to find out its IP yourself with e.g. # Wireshark. set -e if [[ -z "${CHROMECAST_IP}" || -z "${WIFI_SSID}" || -z "${WIFI_PASSWORD}" ]] ; then echo 1>&2 "Usage: CHROMECAST_IP=\"XXX\" WIFI_SSID=\"XXX\" WIFI_PASSWORD=\"XXX\" ${0}" exit 1 fi if ! which curl >/dev/null 2>/dev/null ; then echo 1>&2 "Install curl to use this script!" exit 1 fi if ! which jq >/dev/null 2>/dev/null ; then echo 1>&2 "Install jq to use this script!" exit 1 fi if ! which nodejs >/dev/null 2>/dev/null ; then echo 1>&2 "Install nodejs to use this script!" exit 1 fi # Set VERBOSITY=-vvv to see Curl traffic happening if [[ -z "${VERBOSITY}" ]] ; then VERBOSITY=-s fi echo "Connecting ${CHROMECAST_IP} to ${WIFI_SSID} with password ${WIFI_PASSWORD}" # Get the device's public key INFO_JSON="$(curl ${VERBOSITY} --insecure --tlsv1.2 --tls-max 1.2 https://${CHROMECAST_IP}:8443/setup/eureka_info)" CHROMECAST_PUBKEY="$(echo "${INFO_JSON}" | jq -r '.public_key')" # Scan for and find the network we want to get the encryption parameters curl ${VERBOSITY} --insecure --tlsv1.2 --tls-max 1.2 -X POST https://${CHROMECAST_IP}:8443/setup/scan_wifi sleep 20 WIFI_JSON="$(curl ${VERBOSITY} --insecure --tlsv1.2 --tls-max 1.2 https://${CHROMECAST_IP}:8443/setup/scan_results)" WIFI_NETWORK_JSON="$(echo "${WIFI_JSON}" | jq ".[] | select(.ssid == \"${WIFI_SSID}\")")" WIFI_AUTH_NUMBER="$(echo "${WIFI_NETWORK_JSON}" | jq -r '.wpa_auth')" WIFI_CIPHER_NUMBER="$(echo "${WIFI_NETWORK_JSON}" | jq -r '.wpa_cipher')" echo "${WIFI_NETWORK_JSON}" # Encrypt the password to the device # Encryption kernel by @thorleifjaocbsen # See ENCRYPTED_KEY="$(nodejs < SAVE_COMMAND="{\"keep_hotspot_until_connected\": true}" # Send the commands curl ${VERBOSITY} --insecure --tlsv1.2 --tls-max 1.2 -H "content-type: application/json" -d "${CONNECT_COMMAND}" https://${CHROMECAST_IP}:8443/setup/connect_wifi # Hope this one gets there before it can actually disconnect if we're using the setup hotspot? # Otherwise we have to use Ethernet or jump over to the target network and find the device again. # See for a script that knows how to swap wifi networks but needs to be ported to use the current API. curl ${VERBOSITY} --insecure --tlsv1.2 --tls-max 1.2 -H "content-type: application/json" -d "${SAVE_COMMAND}" https://${CHROMECAST_IP}:8443/setup/save_wifi # To see it working, if you aren't kicked off the hotspot (or if you set the new CHROMECAST_IP in your shell): # # curl --insecure --tlsv1.2 --tls-max 1.2 https://${CHROMECAST_IP}:8443/setup/eureka_info | jq . # # To list known networks: # # curl --insecure --tlsv1.2 --tls-max 1.2 https://${CHROMECAST_IP}:8443/setup/configured_networks | jq . # # To forget a newtwork: # # curl --insecure --tlsv1.2 --tls-max 1.2 -H "content-type: application/json" -d '{"wpa_id": 0}' https://${CHROMECAST_IP}:8443/setup/forget_wifi # # If you leave Ethernet plugged in, the Chromecast will ARP for its WiFi IP on # Etherenet and drop the WiFi connection! Unplug the Chromecast, and plug it in # again with no Ethernet, to get it to keep the WiFi connection up! # # Set Name and opt out of things: # # curl --insecure --tlsv1.2 --tls-max 1.2 -H "content-type: application/json" -d '{"name": "NovakCast5000", "opt_in": {"crash": false, "stats": false, "opencast": false}}' https://${CHROMECAST_IP}:8443/setup/set_eureka_info