# Tesla Fleet API — napojení EMS (čtení SoC vozidla) Cíl: po příjezdu EV přečíst skutečné SoC → `ev_session.energy_needed_wh` přesně místo defaultu. Doména `ems.vojacek.eu` slouží JEN jako veřejná vizitka pro Tesla (cert + public key + jednorázový OAuth callback) — EMS samotné zůstává na VPN. ## 1. Doména (jednorázově, na serveru) ```bash bash /opt/ems-deploy/app/deploy/tesla/setup_tesla_domain.sh # → přidat vypsaný blok do /etc/caddy/Caddyfile a `systemctl reload caddy` ``` Veřejné je pouze: - `https://ems.vojacek.eu/.well-known/appspecific/com.tesla.3p.public-key.pem` - `https://ems.vojacek.eu/tesla/callback` (statická stránka zobrazí `?code=`) - vše ostatní → 404; certifikát řeší Caddy (Let's Encrypt) automaticky. ## 2. Tesla developer portál (developer.tesla.com) Vytvořit aplikaci: - **Allowed Origin:** `https://ems.vojacek.eu` - **Allowed Redirect URI:** `https://ems.vojacek.eu/tesla/callback` - **Scopes:** `openid offline_access vehicle_device_data` (čtení SoC stačí; `vehicle_charging_cmds` až kdybychom chtěli vozidlu poroučet my — teď řídí wallbox, ne auto) → získáš `CLIENT_ID` a `CLIENT_SECRET`. ## 3. Partner account registrace (jednorázově) ```bash # partner token (client_credentials): curl -s https://fleet-auth.prd.vn.cloud.tesla.com/oauth2/v3/token \ -d grant_type=client_credentials -d client_id=$CLIENT_ID \ -d client_secret=$CLIENT_SECRET \ -d scope='openid vehicle_device_data' \ -d audience=https://fleet-api.prd.eu.vn.cloud.tesla.com | jq -r .access_token # registrace domény (ověří si public key na .well-known): curl -s -X POST https://fleet-api.prd.eu.vn.cloud.tesla.com/api/1/partner_accounts \ -H "Authorization: Bearer $PARTNER_TOKEN" -H 'Content-Type: application/json' \ -d '{"domain":"ems.vojacek.eu"}' ``` ## 4. Uživatelský OAuth (jednorázově, z prohlížeče) ``` https://fleet-auth.prd.vn.cloud.tesla.com/oauth2/v3/authorize? response_type=code&client_id=$CLIENT_ID& redirect_uri=https://ems.vojacek.eu/tesla/callback& scope=openid%20offline_access%20vehicle_device_data&state=ems ``` Přihlásíš se Tesla účtem → redirect na callback stránku → zkopíruješ `code` → výměna za tokeny: ```bash curl -s https://fleet-auth.prd.vn.cloud.tesla.com/oauth2/v3/token \ -d grant_type=authorization_code -d client_id=$CLIENT_ID \ -d client_secret=$CLIENT_SECRET -d code=$CODE \ -d redirect_uri=https://ems.vojacek.eu/tesla/callback # → access_token (krátký) + refresh_token (ULOŽIT — viz krok 5) ``` ## 5. EMS integrace (plán implementace) - env: `TESLA_CLIENT_ID`, `TESLA_CLIENT_SECRET`, `TESLA_REFRESH_TOKEN` (`/opt/ems-deploy/.env`); refresh token rotuje → po každém refreshi uložit nový (tabulka `ems.tesla_token` nebo aktualizace .env jobem — rozhodnout). - `services/tesla_client.py`: refresh → access token (cache ~8 h), `GET /api/1/vehicles`, `GET /api/1/vehicles/{id}/vehicle_data` → `charge_state.battery_level`, `charge_state.charge_limit_soc`. - Hook v `_on_ev_arrival` (telemetry_collector): po detekci příjezdu zavolat API, `energy_needed_wh = max(0, (limit − level)/100 × battery_capacity_kwh × 1000 / účinnost nabíjení)` → `fn_ev_session_apply_patch`; replan už běží. - Mapování vozidlo↔wallbox: `asset_vehicle.api_type='tesla'` + VIN sloupec (doplnit migrací), heuristika „Tesla je na chargeru X" dle `default_charger_id`. - Pozn.: vehicle_data budí auto (vampire drain) — volat jen při příjezdu a max 1× za session. ## Stav - [x] skript + callback + dokumentace v repu - [ ] uživatel: spustit setup na serveru + Caddy blok + reload - [ ] uživatel: developer portál (CLIENT_ID/SECRET) + partner registrace + OAuth - [ ] EMS: tesla_client.py + hook (čeká na credentials)