Skip to content

tesla-automation

Pre-condition the 2023 Model Y Performance before tagged calendar appointments, from the Plex server, via Tesla's Fleet API + the official signed-command proxy. No phone shortcuts. Repo: ~/tesla-automation → github.com/angelEmbeddedEra/tesla-automation (private) — one repo for every Tesla automation; pre-cooling is the first. Key host: ~/tesla-key → github.com/angelEmbeddedEra/tesla-key (public) → Cloudflare Pages.

Status

  • 2026-09-10 12:00: scripts written and dry-run tested (start trigger fires 08:45–08:55 for a 09:00 event, end trigger 09:45, nothing inside the event, no markers on dry-run); pushed to github.com/angelEmbeddedEra/tesla-automation. install.sh has created the empty ~/.config/tesla/env (0600). Waiting on Angel: Cloudflare Pages connect, Tesla app registration, iCal URL → then tesla-login.py, key pairing, --test-command, re-run install.sh for the cron line.

Decisions

  • Trigger rule: only timed events whose title contains 🚗. Explicit beats heuristics; training blocks and calls never pre-cool the car. 2026-09-10.
  • Public key hosted on Cloudflare Pages, not on this server: Tesla needs the key at an HTTPS domain root; the GitHub Pages user site is the private portfolio; exposing port 443 on the Plex box was rejected. 2026-09-10.
  • Calendar read via the Google Calendar private iCal URL, not the Calendar API — no OAuth app, no token refresh, read-only. 2026-09-10.
  • Commands go through tesla/vehicle-command (tesla-http-proxy) on loopback with a self-signed cert; a 2023 Model Y requires the signed protocol. 2026-09-10.

Gotchas

  • Fleet API pricing (2026): $10/month credit per developer account; ~$0.001 per command, ~$0.02 per wake, ~$0.000007 per data signal. Four pre-cools a day ≈ $2.50/month — inside the credit. A wake costs 20× a command: never poll a sleeping car "to see", only wake when a trigger is due.
  • The Tesla proxy image runs as uid 65532 and cannot read 0600 files owned by angel — run it as user: "1000:1000" with HOME=/cache; the cache dir must be a bind mount you own, not a named volume.
  • GitHub Pages user sites cannot serve /.well-known/ at the root (per Tesla docs research 09-10) — one more reason for Cloudflare Pages.
  • Secrets live in ~/.config/tesla/ (0600): private-key.pem, TLS pair, env. Never in the repo. The public key is the only file that is public — by design.
  • The Tesla virtual key must be paired on the car once: open https://tesla.com/_ak/<domain> in the Tesla app while near the car.

Open

See ~/Notes/tasks.md — this section is now generated from the task register.

Log

  • 2026-09-10: Dropped the proxy healthcheck from docker-compose.yml: tesla/vehicle-command is distroless (no sh/wget/curl), so no probe can pass. Container now shows plain "Up". Health = precool.py --test-command + ntfy on failure.
  • 2026-09-10: ARMED. install.sh installed the */5 cron (precool.py, log ~/.local/state/tesla-automation/cron.log). Gotcha: the proxy container had been started under the old tesla-precool compose project, so compose refused to recreate it under tesla-automation; fixed with docker rm -f tesla-http-proxy + docker network rm tesla-precool_default, then rerun. Bind mounts meant nothing was lost.
  • 2026-09-10: Barbershop address resolved: D&D Luxury Barbershop, 1648 N Market Dr Ste B, Raleigh NC 27609 (Square name "EL MARAC0 BARBERSHOP"); now set as location by the CAR-TRIP TAGGING rule.
  • 2026-09-10: CAR-TRIP TAGGING rule added to the training-sync passes: non-managed events whose title matches BARBERSHOP/MARACO (Square SMS reminders iOS auto-adds, Thu 11:30–12:30) get a 🚗 title prefix — the one permitted write to a non-managed event. Address still unknown.
  • 2026-09-10: Personal calendar (angelgdo7) connected via secret iCal URL (CALENDAR_ICS_URL, env only). Trigger = 🚗 in title. Swims are the first automated tag: training-sync now places weekday swims 11:30–12:30 at Millbrook Exchange Pool, 1911 Spring Forest Rd, Raleigh NC 27615 (Garmin median start 11:46) with location + 🚗 prefix — rule lives in ~/.claude/routines/_shared-facts.md SWIM PLACEMENT.
  • 2026-09-10 13:55: virtual key paired; --test-command succeeded — car woke and climate started via the signed proxy. Full chain proven. Fixed: --test-command no longer requires calendar keys. Proxy healthcheck reads 'unhealthy' but commands pass (cosmetic). Remaining: CALENDAR_ICS_URL, then install.sh for cron.
  • 2026-09-10 13:42: app registered (client_id 25ca4d7c…, tier pay_as_you_go, domain public-key hash matches). OAuth complete — refresh token + VIN 7SAYGDEF3PF709653 ("Tesla Y", online) saved to env. tesla-login.py made step-runnable (--step register|url|exchange|vehicles). Next: virtual-key pairing on the car.
  • 2026-09-10 13:05: tesla.embeddedera.com attached to the Pages project (two 522s while the edge cert issued, then 200); key byte-identical over the custom domain. TESLA_DOMAIN set in env. Register the Tesla app against this domain.
  • 2026-09-10 13:02: Cloudflare Pages project live at https://tesla-key-chd.pages.dev — /.well-known/appspecific/com.tesla.3p.public-key.pem serves the key byte-identical to ~/.config/tesla/com.tesla.3p.public-key.pem, content-type application/x-pem-file; /callback page 200.
  • 2026-09-10 11:10: scout pass — considered Home Assistant Tesla Fleet integration (would mean running HA just for this), iainbullock/tesla-http-proxy-docker (wrapper around the same official proxy we run directly), PrecondAI (abandoned 2024), TeslaMate (logging only), tesla-fleet-api lib (Apache-2.0; the paid Teslemetry service is not needed). Chose: official proxy + ~300-line Python cron script + private iCal URL. Proxy up on 127.0.0.1:4443; venv with requests/icalendar/recurring-ical-events.
  • 2026-09-10: started. EC P-256 keypair + self-signed TLS in ~/.config/tesla; tesla-key repo public with .well-known/appspecific/com.tesla.3p.public-key.pem; tesla/vehicle-command:latest pulled.