-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Hyundai Kia: Refresh Token
This scripts helps owners of cars made by Hyundai or Kia to retrieve the
refresh_token that is now necessary to access the Bluelink API in the
integrations for HomeAssistant and evcc.
It is a combination of the separate efforts of @fuatakgun (original Kia implementation) and @Maaxion (Hyundai aption)
You need to have the following installed on your computer
Important
On Windows installations make sure to set the check at "Add Python 3.x to PATH" in the installer
- Python3 >= 3.12
-
wget(Linux/MacOS) oriwr(Windows) - Chrome or a Chromium based Brower
-
Copy the script from below to your local hard drive:
-
Linux/MacOS
wget -O bluelinktoken.py https://raw.githubusercontent.com/RustyDust/bluelink_refresh_token/refs/heads/main/bluelinktoken.py
-
Windows
Run inpowershell:iwr -UseBasicParsing -OutFile bluelinktoken.py https://raw.githubusercontent.com/RustyDust/bluelink_refresh_token/refs/heads/main/bluelinktoken.py
-
Linux/MacOS
-
Prepare the python runtime environment (you do have Python3 installed, right?)
-
Linux/MacOS
python3 -m venv .venv source .venv/bin/activate pip3 install selenium requests -
Windows
Do not double click the python file to run it. If you do, the terminal will close after the program ends, giving you no chance to copy the
refresh token.Open
cmdin the same dir you downloaded the Python file into (or continue in the powershell from the previous step):python -m venv .venv .\.venv\Scripts\Activate.ps1 python -m pip install --upgrade pip pip install selenium requests webdriver-manager
-
Note
You should still be in the Python environment from step 2.1 or 2.2 from above!
-
Linux/MacOS:
python ./bluelinktoken.py --brand kia
-
Windows:
python .\bluelinktoken.py --brand kia
-
Linux/MacOS:
python ./bluelinktoken.py --brand hyundai
-
Windows:
python .\bluelinktoken.py --brand hyundai
The script will automatically open your browser (you did install Chrome, yes?) with the correct URL for your vehicle's brand. Log in using the credentials (username / password) you use in the app on your mobile phone.
If everything worked as expected you'll get an output in your terminal similar to this:
Opening login page: https://idpconnect-eu.(kia/hyundai).com/auth/api/v2/user/oauth2/authorize?(...shortened...)
==================================================
Please log in manually in the browser window.
The script will wait for you to complete the login...
==================================================
✅ Login successful! Element found.
✅ Your tokens are:
- Refresh Token: M2M2OG................................YOTG5
- Access Token: eyJhbGc.........................0_AijpHXp0yg
Cleaning up and closing the browser.Use the Refresh Token from above as the password together with your normal
username when setting up either the HomeAssistant or evcc integration for your
vehicle.
Note
The refresh token you generated is valid for 180 days. After that period
you'll have to generate a new one and reconfigure your integrations
On macOS by default the x86 emulated Chrome is opened by selenium and that's so slow that it doesn't really work. Here is a all in one workaround script that just needs to be executed. It could be that you need to go the Systemsettings > Security to allow for the chromedriver to be executed.
#!/bin/zsh
set -e
# Define variables
FILENAME="bluelinktoken.py"
URL="https://raw.githubusercontent.com/RustyDust/bluelink_refresh_token/refs/heads/main/bluelinktoken.py"
# Check if the file already exists
if [ -f "$FILENAME" ]; then
echo "File '$FILENAME' already exists."
echo "Skipping download and patch to avoid overwriting your current file."
else
echo "File not found. Proceeding with download..."
# Download with curl
curl -L -o "$FILENAME" "$URL"
# Verify download succeeded before patching
if [ -f "$FILENAME" ]; then
echo "Download complete. Patching file..."
# Use perl to insert the 'service' line and the updated 'driver' line
# keeping the original indentation ($1)
perl -i -pe 's/^(\s*)driver = webdriver\.Chrome\(options=options\)/$1service = webdriver.ChromeService(port=54130)\n$1driver = webdriver.Chrome(service=service, options=options)/' "$FILENAME"
echo "Success! The file has been downloaded and updated."
else
echo "Error: Download failed."
fi
fi
# --- STEP 1: Detect OS and Architecture for Chromedriver ---
echo "--- Checking System Configuration ---"
OS="$(uname -s)"
ARCH="$(uname -m)"
PLATFORM=""
if [[ "$OS" == "Darwin" ]]; then
if [[ "$ARCH" == "arm64" ]]; then
PLATFORM="mac-arm64" # Apple Silicon
else
PLATFORM="mac-x64" # Intel Mac
fi
elif [[ "$OS" == "Linux" ]]; then
PLATFORM="linux64"
else
echo "Error: Unsupported OS ($OS)"
exit 1
fi
echo "Detected Platform: $PLATFORM"
# --- STEP 2: Download & Unzip Latest Stable Chromedriver ---
echo "--- Downloading latest Chromedriver Stable ---"
# We use Python to parse the official JSON to get the exact download URL for your platform
JSON_URL="https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json"
DOWNLOAD_URL=$(curl -s "$JSON_URL" | python3 -c "
import sys, json
data = json.load(sys.stdin)
# Find the URL for the 'Stable' channel matching our platform
downloads = data['channels']['Stable']['downloads']['chromedriver']
url = next(item['url'] for item in downloads if item['platform'] == '$PLATFORM')
print(url)
")
echo "Downloading from: $DOWNLOAD_URL"
curl -L -o chromedriver.zip "$DOWNLOAD_URL"
echo "Unzipping..."
# Unzip quietly (-q) and overwrite (-o)
unzip -q -o chromedriver.zip
mv chromedriver-mac-arm64/chromedriver chromedriver
chmod +x chromedriver
rm -rf chromedriver-mac-arm64
rm -rf chromedriver.zip
echo "Chromedriver updated successfully."
# --- STEP 3: Setup Python Environment ---
echo "--- Setting up Python VENV ---"
if [[ ! -d ".venv" ]]; then
echo "Creating virtual environment..."
python3 -m venv .venv
fi
source .venv/bin/activate
pip install -q selenium requests
# --- STEP 4: Start Background Process & Trap ---
echo "--- Starting Chromedriver Background Service ---"
# Note: We use ./chromedriver to ensure we use the one we just downloaded
./chromedriver --port=54130 &
CHROMEDRIVER_PID=$!
# Define cleanup to kill chromedriver on exit
cleanup() {
echo "\n--- Stopping chromedriver (PID: $CHROMEDRIVER_PID) ---"
kill "$CHROMEDRIVER_PID" 2>/dev/null
}
trap cleanup EXIT INT TERM
# Wait a moment for chromedriver to spin up
sleep 2
# --- STEP 5: Run Main Script ---
echo "--- Running Bluelink Token Script ---"
python ./bluelinktoken.py --brand hyundai