Tesla フリートAPI 実装の備忘

Tesla API(Fleet API)の実装について、備忘録としてまとめます。

1. 前提条件

1.1. 必要なもの

必要な基盤とミドルウェアは以下の通りです。

・サーバ基盤:
 私の環境ではProxmox上のdebian で構築

・独自ドメイン:
 認証のために必要

・Webサーバ:
 apache/nginx等のWebサーバが必要 公開鍵を公開する

・Python / Go 言語環境:
 最終的なAPI制御用

2. 作業概要

STEP 1: 鍵作成(秘密鍵・公開鍵)
操作者の認証のためにキーペアを作成し、自ドメイン上で公開鍵を公開する。

STEP 2: Tesla Developer にてアプリ登録を行う
API操作に必要な Client ID と Client Secret を取得する。

STEP 3: 車両キーとして、Teslaに公開鍵を登録する
Teslaのキー登録と同様に、自ドメインと紐付く公開鍵を車両に登録する。

STEP 4: 公式ツール(tesla-control)の導入とAPI実行
今回はアンペア操作などの充電操作を試します(充電操作のみの権限をつけています)


STEP 1. 鍵作成(秘密鍵・公開鍵)とWebサーバ構築

1.1. APACHEによるWEBサイトの構築

昨今はIPv4枯渇の影響でポート開放ができない回線が多いため、Cloudflareトンネルによるサイト公開とします。
Cloudflare による通信暗号化、HTTPS化も可能です。しかも無料です。

1.1.1. apache2インストール

必要に応じてsudo してください。
apt install apache2 -y

#OSが起動したときに、apacheが自動起動させるためのおまじない
systemctl start apache2
systemctl enable apache2
systemctl status apache2
 →enabled であれば、OS再起動時もapacheが自動起動します。

1.1.2. サイトページの設置

誰もアクセスしてこないと思いますが、デフォルトページの公開は不適切なので念のためサイトファイルを設置します。

cd /var/www/html

# デフォルトページを削除
rm -rf index.html

# 明示的にファイル作成
touch index.html

# サイトにアクセスすると、自前のドメイン名が表示されるようにする
sh -c 'echo "自分のドメイン名" > index.html'

# 一般公開用なので644 (rw-r--r--) に設定
chmod 644 index.html

※このファイルの所有者は「読み書き」ができ、他の人は「読み取り」しかできない状態にします。

1.1.3. ローカルネットワークでサイトが表示できるかを確認する

宅内NW上のサーバのIPアドレスを調べ、ブラウザでアクセスできることを確認します。(ip aコマンドなど)

1.2. 鍵ペアの作成(秘密鍵・公開鍵)

参考:https://developer.tesla.com/docs/fleet-api/virtual-keys/developer-guide#hosting-the-public-key

mkdir ~/pem
cd ~/pem

# 1. 秘密鍵(絶対に誰にも見せちゃダメ)を作成
openssl ecparam -name prime256v1 -genkey -noout -out private_key.pem

# 2. 秘密鍵から公開鍵(こちら公開)を作成
openssl ec -in private_key.pem -pubout -out public_key.pem

公開鍵を公開するためのディレクトリを作成し、公開鍵を配置します。

# 公開のためのディレクトリを作成する
mkdir -p /var/www/html/.well-known/appspecific

# 公開鍵をコピーし、「com.tesla.3p.public-key.pem」 というファイル名に変える
cp ~/pem/public_key.pem /var/www/html/.well-known/appspecific/com.tesla.3p.public-key.pem

1.3. CloudflareによるWebページの公開

Cloudflareは自宅のインターネット側IPアドレスを公開することなく、サイト公開ができます。 https化も無料です。サーバにエージェントをインストールするだけです。

非常にわかりやすい記事を書いている方がおられたので、リンクします。

https://zenn.dev/takajun/articles/fbd783e459c722

自分のドメインに置き換えて、以下にアクセスします。 
公開鍵が表示できることを確認して、ここまで完了です。 

https://自分のドメイン/.well-known/appspecific/com.tesla.3p.public-key.pem

STEP 2. Tesla Developer にてアプリ登録を行う

2.1. Tesla Developerにアクセスし、Teslaアカウントでサインインする。

https://developer.tesla.com

2.2. 新しいアプリケーションを作成

「新しいアプリケーションを作成する」から、各種必要事項を入力する。 

以下参考

Auth付与タイプclient-credentialsauthorization-code

許可された送信元https://自分のドメイン

許可されたリダイレクトURIhttps://自分のドメイン/callback

2.3. 顧客ID(Client ID)および顧客機密(シークレット)を控える。

後ほど使います。 ※流出しないように注意

2.4. Tesla アプリをインストールしたスマホ、またはブラウザから、以下のURLにアクセスする。

https://auth.tesla.com/oauth2/v3/authorize?&client_id=$【ClientID】
&locale=en-US&prompt=login&redirect_uri=$【自分のドメイン】
&response_type=code&scope=scope=openid%20vehicle_device_data%20o"i
ne_access%20vehicle_cmds

※【ClientID】【ドメイン】は置き換えてください。

このとき、リダイレクトされたURLから 「code=xxx」を抜き出して、保管してください。
次のステップで使用します。 この認可コードは10分の期限があります。

2.5. アクセストークンの取得 (認可コード取得から10分以内)

テスラを操作するサーバから、以下のコマンドを実行します。
表示された Access Token、Refresh Token を控えてください。

curl -X POST https://auth.tesla.com/oauth2/v3/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "authorization_code",
"client_id": "クライアントID",
"client_secret": "シークレット",
"code": "手順2.4で取得したコード",
"audience": "https://fleet-api.prd.na.vn.cloud.tesla.com",
"redirect_uri": "https://dev.cre-noa.me/callback"
}'

※アクセストークンには期限があります。
リフレッシュトークンを使うことで、新しいアクセストークンを取得することができます。リフレッシュトークンについては、プログラムの実装次第で使います。

STEP 3: 車両キーとして、Teslaに公開鍵を登録する

API経由で車両を操作(コマンド送信)するためには、Teslaのクラウドと「車両本体」の両方に、作成した公開鍵を登録・ペアリングする必要があります。

操作の流れは以下の通りです。

3.1. Tesla公式アプリがインストールされており、ログイン済みのスマートフォンを用意

3.2. (念のため)物理的キーカードを持って、車両に乗り込む

3.3. 以下のURLにアクセスします。
 https://tesla.com/_ak/自分のドメイン

3.4. Finish Setup をタップすると、自動的にTesla公式アプリが起動します。
「サードパーティアプリにアクセスを許可しますか?」という確認画面を確認し、承認します。

※車両のコンソール画面にキーカードをかざすよう求められた場合は、指示に従って物理キーかざす

STEP 4: 公式ツール(tesla-control)の導入とAPI実行

Tesla公式が提供しているGo言語のCLIツール「tesla-control」を利用します。

4.1. Go言語のインストール

tesla-control をビルド・インストールするために、まずはサーバにGo言語環境をインストールします。

sudo apt update
sudo apt install golang -y

# インストール確認
go version

4.2. tesla-control のインストール

Go環境が整ったら、Tesla公式のGitHubリポジトリから tesla-control をインストールします。

go install https://github.com/teslamotors/vehicle-command/cmd/tesla-control@latest

4.3. 実行環境(作業ディレクトリとファイル)の準備

スクリプトやトークンを保存するための作業用ディレクトリを作成し、STEP 2.5で取得したトークンをテキストファイルに保存します。

また、STEP 1で作成した秘密鍵もこのディレクトリに集約しておきます。

# 作業用ディレクトリの作成 ※任意で読み替えてください。
mkdir -p ~/TESLA-POST 
cd ~/TESLA-POST

# STEP 1で作成した秘密鍵を作業ディレクトリにコピー
cp ~/pem/private_key.pem ./

# トークンをファイルに保存する
【】の中身を実際のトークンに置き換えて実行してください

echo "【STEP2.5で取得したアクセストークン】" > token.txt
echo "【STEP2.5で取得したリフレッシュトークン】" > refresh_token.txt

4.4. コマンドを実行する


Pythonのプログラムを作成・実行して正しく動作するかテストします。
(サンプルをおいておきます)

以下のコマンドのパスやVIN(車台番号)、アンペア数をご自身の環境に合わせて変更し、実行してください。

touch test_amps.py
vim test_anps.py
import subprocess
import os

# === 設定項目 ===
BASE_DIR = "以下のPATHが含まれるルートパス"

TESLA_CONTROL_PATH = os.path.join(BASE_DIR, "手順4-3でインストールしたvehicle-commandのファイルパス")
TOKEN_FILE = os.path.join(BASE_DIR, "トークンを保存したTXTのパス token.txt")
KEY_FILE = os.path.join(BASE_DIR, "秘密鍵を保存したTXTのパス private.pem") 

VIN = "操作対象のVIMを大文字で入力"
API_URL = "https://fleet-api.prd.na.vn.cloud.tesla.com"
# =================

def set_charging_amps(amps):
    if not os.path.exists(TOKEN_FILE):
        print(f"トークンファイルが見つかりません: {TOKEN_FILE}")
        return
    if not os.path.exists(KEY_FILE):
        print(f"秘密鍵({KEY_FILE})が見つかりません")
        return

    # Fleet APIを使うための環境変数をセット
    env = os.environ.copy()
    env["TESLA_API_URL"] = API_URL

    # tesla-control のコマンドリストを組み立てる
    command = [
        TESLA_CONTROL_PATH,
        "-command-timeout", "30s",
        "-key-file", KEY_FILE,
        "-token-file", TOKEN_FILE, # token.txtを直接読
        "-vin", VIN,
        "-ble=false", # Bluetoothではなくインターネット経由(Fleet API)を使う
        "charging-set-amps", str(amps)
    ]

    print(f"Tesla (VIN: {VIN}) に {amps}A への変更コマンドを送信中...")

    try:
        # コマンドの実行!
        result = subprocess.run(
            command, 
            env=env,
            capture_output=True, 
            text=True, 
            check=True
        )
        print(" 成功")
        print("レスポンス:", result.stdout.strip())

    except subprocess.CalledProcessError as e:
        print("エラーあり")
        print("終了コード:", e.returncode)
        print("エラー内容:", e.stderr.strip())

if __name__ == "__main__":
    # テスト実行: 例として16Aに変更
    set_charging_amps(16)

実行

python test_amps.py

まとめ

テスラの魅力はこういったプログラムによって、車両を制御できるのが楽しいですね。
インフラエンジニアにはちょっと難しかったです

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です